SpringBoot服务数据库故障切换后无法自动恢复问题咨询
问题根因定位
报错recoverer is already running, abandoning this recovery request是Bitronix事务管理器的已知经典问题,通常由以下几种场景触发:
- 数据库重启过程中,Bitronix的定时恢复任务和连接池主动触发的异常恢复逻辑并发执行,两个恢复线程抢占恢复锁,其中一个被直接丢弃,导致未完成的事务分支一直处于挂起状态,连接池被占满无法响应新请求,最终健康检查失败
- 当前配置的
spring.jta.log-dir=target/transaction-logs是临时目录,当服务进程意外退出、容器/虚拟机重启后,事务日志丢失,恢复线程读取不到残留的事务信息时会进入死循环重试,重复触发恢复请求导致冲突 - Bitronix本身的版本缺陷:低于2.1.4的版本存在恢复锁释放逻辑的bug,当数据库恢复时间超过Bitronix默认的恢复超时时间时,锁不会被正确释放,后续所有恢复请求都会被直接拒绝
修复方案
临时应急方案
出现故障时不需要全量重启所有数据中心的服务,只需要清理对应服务节点target/transaction-logs目录下的事务日志文件,再单独重启故障节点即可恢复。
永久修复配置
直接修改现有配置,替换以下参数即可解决问题:
# 1. 把事务日志目录改为非临时目录,避免进程重启丢失日志 spring.jta.log-dir=/var/log/bitronix/transaction-logs # 2. 关闭LrcXADataSource的自动恢复触发,统一由Bitronix TM的定时任务触发恢复,避免并发 spring.jta.bitronix.datasource.enable-xa-recovery=false # 3. 调大恢复间隔时间,默认是60秒,改为120秒减少并发概率 spring.jta.bitronix.tm.recovery-interval=120 # 4. 开启恢复超时自动释放锁 spring.jta.bitronix.tm.recovery-timeout=30 # 原有其他配置保持不变即可 spring.jta.bitronix.datasource.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource spring.jta.bitronix.datasource.driverProperties.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver spring.jta.bitronix.datasource.driverProperties.url= spring.jta.bitronix.datasource.driverProperties.user= spring.jta.bitronix.datasource.driverProperties.password= spring.jta.bitronix.datasource.test-query=select 1 spring.jta.bitronix.datasource.max-pool-size=100 spring.jta.bitronix.datasource.prepared-statement-cache-size=100
版本升级建议
如果当前使用的Bitronix版本低于2.1.4,直接升级到2.1.4及以上版本即可,官方已修复恢复锁泄漏的问题。
验证方法
修改配置上线后,可以手动触发测试数据库重启,观察日志是否还有该报错,同时健康检查接口的响应成功率不会出现下降,不需要人工干预即可自动恢复。
内容的提问来源于stack exchange,提问作者codeLover
相关产品推荐
相关产品推荐

