恢复数据库备份后Liquibase重复执行旧变更集问题求助
问题分析与解决思路
核心原因
Liquibase通过变更集id + author + filename的组合来唯一标识已执行的变更。备份的databasechangelog表中记录的filename为../db.bestekchecker.xml,但你执行Liquibase时指定的--changelog-file是db.bestekchecker.xml,路径不匹配导致Liquibase认为这是未执行过的新变更集,从而重复执行。
另外,<validCheckSum>ANY</validCheckSum>仅允许MD5校验值变化,无法解决变更集标识不匹配的问题。
解决步骤
1. 统一变更集filename匹配
方式一:调整执行命令的changelog路径
修改bash脚本中的Liquibase命令,将--changelog-file=db.bestekchecker.xml改为--changelog-file=../db.bestekchecker.xml,与databasechangelog中的记录保持一致:
/liquibase/liquibase --url $URL --classpath="/liquibase/postgres-jdbc/postgresql-42.2.5.jar" --driver=org.postgresql.Driver --changelog-file=../db.bestekchecker.xml --username=xxxx --password=xxxxx --defaultSchemaName=$schemaname --log-level=warning update -Dschemanaam=$schemaname
方式二:更新databasechangelog表的filename字段
针对每个恢复后的数据库/schema,执行SQL修改databasechangelog中的filename记录:
UPDATE databasechangelog SET filename = 'db.bestekchecker.xml' WHERE filename = '../db.bestekchecker.xml';
2. 验证变更集标识一致性
核对changelog.xml中变更集的id、author与databasechangelog中的对应字段,确保完全一致(包括大小写、拼写)。
3. 临时应急方案(适用于无法修改命令或数据库的场景)
在变更集中添加前置条件,判断目标列是否存在,不存在才执行SQL。即使Liquibase误判,也会自动标记变更集为已执行:
<changeSet id="125" author="xxx"> <validCheckSum>ANY</validCheckSum> <preConditions onFail="MARK_RAN"> <not> <columnExists tableName="beeldkwaliteit_type_werkzaamheden" columnName="favorite" schemaName="${schemanaam}"/> </not> </preConditions> <sqlFile encoding="utf8" endDelimiter=";" path="125/addfavorite.sql" relativeToChangelogFile="true" splitStatements="true" stripComments="false"/> </changeSet>
内容的提问来源于stack exchange,提问作者Tjidde Nieuwenhuizen
相关产品推荐
相关产品推荐

