Aurora MySQL读副本性能随运行时间逐步降级问题咨询
根因定位
完全匹配你所有观测特征的问题是读副本Undo日志清理滞后(History List过长):
- 重启后性能恢复:重启重置Purge线程状态,清空旧的Undo历史,History List降至低位
- 仅全表扫描类查询劣化:全表扫描需为每行遍历Undo日志匹配可见版本,索引点查仅处理少量行,Undo遍历的影响可忽略
- 索引查询无异常、CPU/复制延迟正常:Undo清理是后台IO,不会打满CPU,也不影响Redo应用的复制延迟
- 关闭block_nested_loop无效:问题出在表扫描阶段的Undo遍历,和连接算法无关
验证步骤
直接运行以下命令对比正常(刚重启)和劣化状态的指标:
- 查看InnoDB事务状态:
找到SHOW ENGINE INNODB STATUS;TRANSACTIONS模块的History list length值:- 正常状态:通常为数千至数万级
- 劣化状态:会涨到百万级甚至更高
- 查看Purge滞后差值:
两个值的差值越大,Undo清理滞后越严重。SELECT (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='innodb_oldest_trx_id') AS oldest_active_trx, (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='innodb_purge_trx_id') AS max_purged_trx;
解决方案
短期止血
- 调整离线分析查询的隔离级别为
READ COMMITTED:该级别下每条语句启动时生成独立Read View,不会持有长生命周期的一致性读快照,Purge线程可及时清理过期Undo。
单条查询测试可先执行:
再运行原慢查询验证性能恢复情况。SET TRANSACTION ISOLATION LEVEL READ COMMITTED; - 禁止在同一读副本上并发运行多个长耗时分析查询,避免多个长Read View叠加阻碍Purge进度。
长期优化
- 调整Purge线程参数:在RDS参数组中修改:
innodb_purge_threads:从默认4提升至8,增加Undo清理并行度innodb_purge_batch_size:从默认300提升至1000,单次清理更多Undo页
- 优化慢查询本身:你提到的低性能查询因
LOWER()函数无法使用现有索引,可直接创建函数索引避免全表扫描:
创建后该查询会直接走索引,无需全表扫描,从根源规避Undo遍历的影响。ALTER TABLE TCUSTOMERPROFILEVALUE ADD INDEX idx_attkey_lower_stv (LOCALIZED_ATTRIBUTE_KEY, (LOWER(SHORT_TEXT_VALUE))); - 负载隔离:将离线分析负载迁移至独立的Aurora读副本,避免分析查询的长Read View影响在线OLTP读负载的Purge进度。
- 可选开启Aurora MySQL Parallel Query(参数
aurora_parallel_query=1),加速大表扫描的同时降低Undo遍历的整体耗时。
内容的提问来源于stack exchange,提问作者redfish819
相关产品推荐
相关产品推荐

