LiquidBase操作GCP Spanner遇网络中断后报错的解决咨询
解决LiquidBase在GCP Spanner中因网络中断导致的重复DDL执行报错
问题根源
GCP Spanner的DDL操作是非事务性的,不支持回滚。所以即使LiquidBase的事务因网络中断中止,已经执行的DROP COLUMN操作实际上已经在Spanner中生效,但LiquidBase的DATABASECHANGELOG表未标记该变更完成,导致重新运行时重复执行相同的DROP语句,触发“找不到字段”的报错。
解决步骤
1. 确认字段的实际状态
先查询Spanner的元数据,确认sys_role表的status_apply字段是否已被删除:
SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'sys_role' AND column_name = 'status_apply'
如果查询结果为空,说明字段确实已被删除,接下来需要修正LiquidBase的变更日志。
2. 修正LiquidBase的DATABASECHANGELOG记录
LiquidBase通过DATABASECHANGELOG表跟踪已执行的变更,我们需要把对应DROP操作的记录标记为已成功执行:
- 首先找到对应变更的
ID和AUTHOR:从你的YML变更文件中找到包含ALTER TABLE sys_role DROP COLUMN status_apply的changeSet节点,获取它的id和author属性值。 - 查询当前
DATABASECHANGELOG中是否存在这条记录:SELECT * FROM DATABASECHANGELOG WHERE ID = '你的变更ID' AND AUTHOR = '你的作者名' - 若记录存在但
EXECUTION_STATUS为FAILED,更新状态:UPDATE DATABASECHANGELOG SET EXECUTION_STATUS = 'SUCCESS', DATEEXECUTED = CURRENT_TIMESTAMP WHERE ID = '你的变更ID' AND AUTHOR = '你的作者名' - 若记录不存在,手动插入一条成功的记录(替换占位符内容):
INSERT INTO DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, EXECUTION_STATUS, DESCRIPTION, LIQUIBASE) VALUES ( '你的变更ID', '你的作者名', '你的变更文件名(比如:changelog.yml)', CURRENT_TIMESTAMP, (SELECT MAX(ORDEREXECUTED) + 1 FROM DATABASECHANGELOG), 'SUCCESS', 'Alter Table(s) sys_role', '你使用的LiquidBase版本(比如:4.20.0)' )
3. 重新运行项目
完成上述操作后,重新启动项目,LiquidBase会识别该变更已成功执行,跳过重复的DROP COLUMN操作,继续执行后续的变更任务。
预防措施
- 拆分大变更:由于Spanner的DDL不支持事务,将复杂的DDL操作拆分为独立的
changeSet,避免单个变更失败影响多个操作的状态跟踪。 - 先验后修复:遇到网络中断或执行失败时,先通过Spanner元数据确认实际变更状态,再处理LiquidBase的日志,不要直接解锁后强行重新运行。
内容的提问来源于stack exchange,提问作者Jack Cheng
相关产品推荐
相关产品推荐

