MySQL 8.0Notes

第 22 章:后台线程

zjc 于 2026-01-22 发布

这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 InnoDB 的稳定运行依赖后台线程:刷脏、purge、IO、日志、统计和监控。它们决定写入平滑性、恢复速度和延迟抖动。

22.1 线程全景

线程 职责
master thread 协调后台任务
page cleaner 刷脏页
purge coordinator/worker 清理 undo
log writer/flusher/checkpointer redo 链路
read ahead / aio 异步 IO
dict stats 统计采集
monitor thread 周期检查

查看:

SELECT NAME, TYPE, PROCESSLIST_INFO
FROM performance_schema.threads
WHERE NAME LIKE '%innodb%';

22.2 Page Cleaner

dirty page pressure
  -> calculate target
     -> choose pages from LRU/flush list
        -> doublewrite
           -> write data files

目标:

  1. 控制脏页比例;
  2. 推进 checkpoint;
  3. 保留干净页;
  4. 避免用户线程大量 flush;
  5. 平滑 IO。

参数:

SHOW VARIABLES LIKE 'innodb_page_cleaners';
SHOW VARIABLES LIKE 'innodb_io_capacity%';
SHOW VARIABLES LIKE 'innodb_max_dirty_pages_pct%';

22.3 IO 线程

SHOW VARIABLES LIKE 'innodb_read_io_threads';
SHOW VARIABLES LIKE 'innodb_write_io_threads';

关注随机读、顺序预读、脏页写入、异步排队和设备队列深度。云盘与本地 NVMe 差异明显,应以压测为准。

22.4 日志线程

8.0.30 及以后版本使用 innodb_redo_log_capacity 管理 redo 容量;早期 8.0 使用 innodb_log_file_sizeinnodb_log_files_in_group

日志链路:

log buffer
  -> writer
  -> flusher
  -> write notifier
  -> checkpointer

22.5 观测

SELECT event_name, count_star, sum_timer_wait
FROM performance_schema.events_waits_summary_global_by_event_name
WHERE event_name LIKE 'wait/io/innodb%'
ORDER BY sum_timer_wait DESC;

22.6 常见故障

现象 排查
写入尖刺 checkpoint、purge、脏页
IO 队列高 io threads、设备能力
CPU 单核高 单模块锁或单线程瓶颈
history list 高 长事务
shutdown 慢 刷脏和 purge
恢复慢 redo、脏页、大事务

本章小结

后台线程承担 InnoDB 的刷脏、清理、日志和 IO 工作。调优要围绕压力来源,而不是只改线程数;观测应同时看状态、等待和操作系统 IO。

思考题

  1. page cleaner 如何降低用户线程 flush?
  2. redo 容量参数在 8.0 版本间有什么差异?
  3. IO 线程数是否越大越好?
  4. 写入尖刺常见来源有哪些?
  5. 如何区分 InnoDB 内部等待和操作系统 IO 压力?