TypeORM在RDS Aurora MySQL故障转移后卡在只读节点求助
RDS Aurora MySQL故障转移后TypeORM写入报错问题
问题现象
使用RDS Aurora MySQL集群,应用通过集群写入端点连接,执行故障转移后首次插入记录时收到报错:
The MySQL server is running with the --read-only option so it cannot execute this statement
第二次执行故障转移后,插入操作恢复正常。怀疑TypeORM内部缓存了旧的主机IP,未识别到RDS CNAME切换后的新主节点。
问题原因
这类问题确实存在,核心原因是:
- TypeORM依赖的mysql2驱动默认会缓存DNS解析结果,故障转移后CNAME指向新IP,但驱动未及时刷新缓存;
- 连接池中的旧连接依然指向原只读节点,且未配置连接有效性检测,导致获取到的连接无法执行写入操作。第一次故障转移后连接池未完成连接刷新,第二次故障转移时旧连接被回收或触发重连,因此恢复正常。
解决方案
1. 配置驱动DNS缓存过期时间
在TypeORM数据源配置中,给mysql2驱动添加dnsTtl参数,定期刷新DNS解析结果:
const dataSource = new DataSource({ type: 'mysql', host: '你的集群写入端点', port: 3306, username: 'xxx', password: 'xxx', database: 'xxx', driver: require('mysql2'), extra: { dnsTtl: 60, // 每60秒重新解析一次DNS connectTimeout: 10000, }, });
2. 开启连接池有效性检测
配置连接池参数,每次获取连接时验证有效性,失效则自动重建:
extra: { testOnBorrow: true, validationQuery: 'SELECT 1', // MySQL通用检测语句 validationInterval: 30000, // 每30秒批量验证一次连接 connectTimeout: 10000, acquireTimeout: 10000, }
3. 手动触发连接池重建
如果有自动化运维流程,可以监听RDS故障转移完成的事件,手动销毁并重建TypeORM数据源:
// 故障转移事件触发后执行 await dataSource.destroy(); await dataSource.initialize();
内容的提问来源于stack exchange,提问作者Michael Ortiz
相关产品推荐
相关产品推荐

