Docker部署Spring Boot应用遇Liquibase校验失败问题求助
解决Liquibase校验失败(Checksum不匹配)问题
问题原因
Liquibase会将每个已执行的changeSet的校验值(MD5SUM)存储在数据库的databasechangelog表中。当出现以下情况时,就会触发校验失败:
- 修改了已执行过的changeSet内容(包括空格、换行、注释等细微变化);
- changeSet的
id、author属性或文件路径发生变更; - 你提供的第二个changeSet的id是
2-ays-dml,但报错信息里对应的id是2-ays-ddl,如果是changeSet文件里的id写错了,也会导致Liquibase无法匹配对应记录,触发校验错误。
删除Docker镜像无法解决问题,因为校验值存储在数据库中,而非镜像或容器内。
解决方案
以下是几种可行的解决办法,按推荐程度排序:
1. 添加validCheckSum标签(推荐)
在对应的changeSet中添加validCheckSum标签,指定新的校验值或允许任意校验值,让Liquibase认可当前的changeSet内容。示例:
<changeSet id="1-ays-ddl" author="author"> <validCheckSum>8:6b1f7f790c04285a35dc3acd3e89a0f4</validCheckSum> <!-- 原changeSet的SQL或操作内容 --> </changeSet> <!-- 注意修正id为报错中的2-ays-ddl,或确认数据库记录中的id --> <changeSet id="2-ays-ddl" author="author"> <validCheckSum>8:f34f4332cdb9f4dd708875364cd476a0</validCheckSum> <!-- 原changeSet的SQL或操作内容 --> </changeSet>
如果后续还需要修改该changeSet,可使用<validCheckSum>ANY</validCheckSum>,但生产环境需谨慎使用,避免误操作。
2. 更新数据库中的校验值
直接修改数据库databasechangelog表中对应记录的MD5SUM字段,替换为报错中的新校验值。示例SQL:
-- 更新第一个changeSet的校验值 UPDATE databasechangelog SET MD5SUM = '8:6b1f7f790c04285a35dc3acd3e89a0f4' WHERE ID = '1-ays-ddl' AND AUTHOR = 'author' AND FILENAME = 'db/changelog/changes/1-ays-ddl.xml'; -- 更新第二个changeSet的校验值,注意ID要和数据库记录一致 UPDATE databasechangelog SET MD5SUM = '8:f34f4332cdb9f4dd708875364cd476a0' WHERE ID = '2-ays-ddl' AND AUTHOR = 'author' AND FILENAME = 'db/changelog/changes/2-ays-dml.xml';
注意:操作数据库前务必备份,防止数据丢失。
3. 删除数据库中的changeSet记录(仅开发环境)
如果是开发环境,且changeSet可以重复执行(比如操作是幂等的),可以删除databasechangelog表中对应的记录,然后重新启动应用。但此方法可能导致数据重复或结构异常,生产环境禁止使用。
4. 回滚后重新执行迁移(谨慎使用)
如果changeSet支持回滚,可先执行回滚操作恢复数据库到修改前的状态,修正changeSet后再重新执行迁移。回滚可能影响现有数据,需提前评估风险。
预防措施
- 不要修改已执行过的changeSet内容,如需变更,新增一个changeSet;
- 开发时确保changeSet操作具备幂等性,方便重复执行;
- 对changeSet文件进行版本控制,避免随意修改;
- 确保changeSet的
id、author属性与数据库记录一致,避免笔误。
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

