1. 后台线程周期性刷盘
-
触发机制:
InnoDB 的 Page Cleaner 线程 会周期性地将脏页刷入磁盘,防止内存中脏页堆积。
-
触发条件:
-
脏页比例阈值:当 Buffer Pool 中脏页占比超过 innodb_max_dirty_pages_pct(默认 90%)时,触发异步刷盘。
-
空闲时主动刷盘:系统空闲时,后台线程主动刷盘以减少突发 I/O 压力。
-
-
相关参数:
-
innodb_io_capacity:定义每秒可执行的 I/O 操作次数(影响刷盘速度)。
-
innodb_max_dirty_pages_pct_lwm:低水位线阈值(默认 10%),脏页比例低于此值时减少刷盘频率。
-
2. Redo Log 空间循环利用
-
触发机制:
InnoDB 的 Redo Log 文件是循环写入的,当 Redo Log 空间即将耗尽时,必须推进 Checkpoint LSN,强制刷盘对应的脏页以释放可重用空间。
-
触发条件:
-
Redo Log 剩余空间不足,无法写入新日志。
-
-
相关参数:
-
innodb_log_files_in_group 和 innodb_log_file_size:控制 Redo Log 文件数量和大小。
-
3. Buffer Pool 空间不足
-
触发机制:
当 Buffer Pool 需要加载新页但空闲页不足时,会触发 LRU(最近最少使用)淘汰机制。如果淘汰的页是脏页,需先刷盘。
-
场景示例:
-
执行大查询时,需加载大量新页到 Buffer Pool,触发脏页刷盘。
-
4. 事务提交时的隐式刷盘
-
触发机制:
事务提交时,若开启 innodb_flush_log_at_trx_commit=1,Redo Log 会强制刷盘,但脏页可能仍留在 Buffer Pool 中异步刷盘。
-
例外情况:
-
若使用非持久性设置(如 innodb_flush_log_at_trx_commit=0/2),Redo Log 可能延迟刷盘,脏页刷盘仍由后台线程控制。
-
5. 数据库关闭或重启
-
触发机制:
MySQL 正常关闭时,会强制将所有脏页刷盘,确保数据持久化。
-
异常关闭恢复:
若崩溃或异常关闭,重启时通过 Redo Log 重放未刷盘的脏页修改。
6. 手动触发刷盘
-
命令操作:
-
FLUSH TABLES ... FOR EXPORT:强制刷盘指定表的脏页。
-
SET GLOBAL innodb_max_dirty_pages_pct=0:临时将脏页比例阈值设为 0,触发立即刷盘。
-
脏页刷盘流程
以事务 UPDATE t SET c1=10 WHERE id=1 为例:
-
修改数据页:
-
Buffer Pool 中的页被修改为 c1=10,标记为脏页。
-
-
Redo Log 记录:
-
生成 Redo Log 条目(物理修改),提交时根据配置刷盘。
-
-
异步刷盘触发:
-
后台线程将脏页副本写入双写缓冲区(Double Write Buffer),再写入数据文件。
-
-
更新 Checkpoint LSN:
-
脏页刷盘完成后,推进 Checkpoint LSN,释放 Redo Log 空间。
-
总结
触发场景 | 核心逻辑 | 性能影响 |
后台线程周期性刷盘 | 控制脏页比例,避免内存堆积 | 平滑 I/O,减少高峰压力 |
Redo Log 空间不足 | 强制刷盘以推进 Checkpoint,释放日志空间 | 可能引起短暂 I/O 高峰 |
Buffer Pool 空间不足 | 淘汰脏页前先刷盘,确保数据持久化 | 影响查询响应时间 |
事务提交与关闭 | 保证持久性,强制或异步刷盘 | 提交延迟或关闭时间延长 |
优化建议:
-
根据负载调整 innodb_io_capacity 和 innodb_max_dirty_pages_pct,平衡刷盘速度和内存使用。
-
监控 Innodb_buffer_pool_pages_dirty 状态,避免脏页堆积影响性能。
-
全 SSD 环境可关闭双写缓冲区(innodb_doublewrite=OFF),提升刷盘效率。