Liquibase在Azure CosmosDB(模拟Cassandra API)获取变更日志锁遇竞争问题求助
Liquibase在Azure CosmosDB(Cassandra API)上的变更日志锁异常问题
问题详情
向模拟Cassandra API的Azure CosmosDB实例应用Liquibase变更日志时,出现锁异常:
- 操作前确认
DATABASECHANGELOGLOCK表无锁,但执行更新时,Liquibase尝试获取锁后直接进入等待循环 - 第一条
Waiting for changelog lock....日志的时间戳,和该进程在DATABASECHANGELOGLOCK表中添加的锁时间戳完全一致 - 锁信息示例:
id | locked | lockgranted | lockedby ----+--------+---------------------------------+--------------------------- 1 | True | 2023-07-21 16:04:12.196000+0000 | 58ee50fd8429 (x.x.x.x)
- 关键日志片段(log-level=INFO):
clm-dev-liquibase-cassandra | Starting Liquibase at 16:04:09 (version 4.21.1 #9070 built at 2023-04-13 20:56+0000) clm-dev-liquibase-cassandra | [2023-07-21 16:04:09] INFO [liquibase.ui] Starting Liquibase at 16:04:09 (version 4.21.1 #9070 built at 2023-04-13 20:56+0000) clm-dev-liquibase-cassandra | Liquibase Version: 4.21.1 clm-dev-liquibase-cassandra | [2023-07-21 16:04:09] INFO [liquibase.ui] Liquibase Version: 4.21.1 clm-dev-liquibase-cassandra | Liquibase Open Source 4.21.1 by Liquibase clm-dev-liquibase-cassandra | [2023-07-21 16:04:09] INFO [liquibase.ui] Liquibase Open Source 4.21.1 by Liquibase clm-dev-liquibase-cassandra | [2023-07-21 16:04:09] INFO [liquibase.integration] Starting command execution. clm-dev-liquibase-cassandra | SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". clm-dev-liquibase-cassandra | SLF4J: Defaulting to no-operation (NOP) logger implementation clm-dev-liquibase-cassandra | SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. clm-dev-liquibase-cassandra | [2023-07-21 16:04:12] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:04:22] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:04:32] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:04:42] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:04:53] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:05:03] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:05:13] INFO [liquibase.ext] Waiting for changelog lock.... clm-dev-liquibase-cassandra | [2023-07-21 16:05:23] INFO [liquibase.ext] Waiting for changelog lock....
- 问题为偶发性,执行
liquibase release-locks可正常清除锁,但后续更新仍可能复发 - 相同配置在原生Cassandra数据库上运行正常,仅在Azure CosmosDB(Cassandra API)+ Simba JDBC驱动环境下出现
可能原因
- CosmosDB一致性模型差异:CosmosDB默认的最终一致性机制,可能导致Liquibase加锁后,读取锁状态时数据未同步到当前节点,误以为锁未获取成功
- Simba JDBC驱动兼容性:驱动对Cassandra锁操作的实现细节,在CosmosDB环境下存在偏差,导致Liquibase无法正确识别自己持有的锁
- Liquibase锁逻辑未适配CosmosDB延迟:Liquibase默认的锁检查超时、重试间隔,未考虑CosmosDB的读写延迟特性
解决方法
1. 调整Liquibase锁超时与重试参数
修改Liquibase配置,延长锁等待时间、调整重试间隔,给CosmosDB足够的同步时间:
在liquibase.properties中添加:
lock.wait.timeout=300 lock.retry.count=10 lock.retry.interval=5
或直接在命令行指定参数:
liquibase update --lock-wait-timeout=300 --lock-retry-count=10 --lock-retry-interval=5
2. 强制设置强一致性级别
通过JDBC URL参数,将CosmosDB的一致性级别设置为强一致性,确保锁操作的读写同步:
jdbc:cassandra://<cosmosdb-host>:10350/?consistencyLevel=STRONG&ssl=true&username=<username>&password=<password>
注:强一致性会带来一定性能损耗,需结合业务场景评估是否接受
3. 替换为Azure官方Cassandra驱动
尝试使用Azure官方提供的CosmosDB Cassandra驱动(替代Simba驱动),验证兼容性问题:
Maven依赖示例:
<dependency> <groupId>com.azure.cosmos</groupId> <artifactId>azure-cosmos-cassandra-driver</artifactId> <version>4.15.0</version> </dependency>
4. 自定义锁检查逻辑(进阶)
若上述方法无效,可扩展Liquibase的LockService接口,针对CosmosDB调整锁检查逻辑——比如在加锁后增加短暂延迟,再执行锁状态检查。
验证步骤
- 应用配置后,多次执行
liquibase update,观察是否仍出现锁等待循环 - 查看
DATABASECHANGELOGLOCK表的锁状态,确认锁持有者与当前进程一致时,Liquibase是否正常执行变更
内容的提问来源于stack exchange,提问作者MLamb
相关产品推荐
相关产品推荐

