开放问答
MySQL 8.0.30 innodb_redo_log_capacity 调大后 checkpoint 频率未降,如何定量判断 redo log 是否写延迟瓶颈
该问题的正文、回答与评论。
提问者 陈亦舟 · 状态 open
MySQLInnoDBredo-log写延迟性能调优
背景
MySQL 8.0.30,InnoDB,一台 64C / 256G 裸金属,承载 3 个业务库。核心库有一张 1.2 亿行的支付流水表 t_pay_flow(PK=id,二级索引 idx_merchant_status、idx_biz_time),日均写入约 8000 万行(INSERT + UPDATE 混合,UPDATE 占比约 60%),写入 QPS 峰值约 12000。innodb_buffer_pool_size=128G,innodb_flush_log_at_trx_commit=1,sync_binlog=1。
现象
把 innodb_redo_log_capacity(8.0.30 引入,替代旧的 innodb_log_file_size × innodb_log_files_in_group)从默认 100MB 调到 4GB 后:
SHOW ENGINE INNODB STATUS里 Log sequence number 与 Last checkpoint at 的差值从峰值 ~350MB 降到 ~80MB,看起来 redo 余量大了 4 倍。- History list length 从高峰 2000+ 降到 300 左右,purge 线程压力确实小了。
innodb_os_log_pending_writes/innodb_os_log_pending_fsyncs峰值从 ~50 降到 ~15。- 但业务侧 P99 写延迟几乎没有变化:INSERT 4.2ms → 4.0ms,UPDATE 6.8ms → 6.5ms。
performance_schema.events_waits_summary_global_by_event_name里log_flush、log_write的 avg_wait 变化 < 5%。
已尝试的排查
- 确认
innodb_flush_log_at_trx_commit=1、sync_binlog=1未变,排除 binlog 刷盘路径。 - 对比调整前后的
innodb_buffer_pool_pages_dirty,峰值没有显著下降(~3000 页),说明 buffer pool flush 压力没因为 redo 容量变大而减轻。 - 用
performance_schema的file_summary_by_event_name看了 redo 文件(./#innodb_redo/#innodb_redo0)的 os_log 事件,avg_wait 从 12μs 降到 9μs,变化不大。 - 怀疑瓶颈在 row lock 等待或 AHI,但还没拿到确凿数据——
innodb_row_lock_waits的 avg_wait 在高峰只有 0.3ms 左右,innodb_adaptive_hash_index当前是 ON。
期望得到的答案
- 原理层面:在「高频 UPDATE + 大 buffer pool」场景下,redo log 容量到底影响的是哪个环节?是 checkpoint 频率(决定 buffer pool flush 节奏)、purge 线程压力、还是 log write 的 fsync 次数?为什么 4GB 的 redo 空间没有让 P99 出现量级变化?
- 可复现的指标组合:有没有一套从
performance_schema+information_schema+SHOW ENGINE INNODB STATUS里取指标的 checklist,能让我定量判断"redo log 刷盘是不是当前写延迟的主要瓶颈",而不是靠猜?最好能给出阈值或比例(比如 pending_fsyncs / QPS > X 才认为是瓶颈)。 - 地板在哪里:如果 redo log 不是瓶颈,那 12000 QPS 下 UPDATE P99 6.5ms 的"地板"大概由什么决定?是 buffer pool flush、row lock、AHI 还是别的?有没有办法在不加硬件的前提下把这个地板再压下去?
我关心的是可落地的诊断方法 + 背后的原理,而不是"加内存"或"上 SSD"。
评论
暂无评论。