页、缓存与日志责任边界
可运行 SQL
sql
SELECT @@innodb_buffer_pool_size,
@@innodb_redo_log_capacity,
@@innodb_flush_log_at_trx_commit,
@@sync_binlog,
@@binlog_format;
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Innodb_buffer_pool_reads',
'Innodb_buffer_pool_read_requests',
'Innodb_log_waits',
'Innodb_os_log_written'
);
SHOW ENGINE INNODB STATUS;机制解释
Buffer Pool 缓存数据和索引页;修改先作用于内存页并产生 redo。事务提交要求的持久性取决于 redo 与 binlog 的刷盘策略,脏页可在之后由 checkpoint 过程推进落盘。
undo 支持回滚和 MVCC 旧版本;purge 在不再有 Read View 需要旧版本后清理历史。doublewrite 保护页写入过程中发生部分写的场景。binlog 属于 Server 层,服务复制和时间点恢复;redo 属于 InnoDB 崩溃恢复,两者不可互换。
真实边界
- 命中率高不代表延迟健康,热点、扫描和写入压力仍需分解。
- innodb_flush_log_at_trx_commit 与 sync_binlog 的性能收益伴随明确故障窗口。
- 长事务会阻碍 purge;redo 容量不足会造成 checkpoint 压力。
- 不要删除或手工修改 InnoDB 内部文件处理磁盘告警。
练习
- 将一次 UPDATE 的数据页、undo、redo、binlog 路径画开。
- 说明“COMMIT 返回”和“数据页已写回表空间”为什么不等价。
- 设计采样,判断 Innodb_log_waits 是否持续增长。
验收清单
- 机制图分别标出 Buffer Pool、redo、undo、binlog 和表空间。
- 能解释 COMMIT 与脏页落盘不是同一事件。
- 状态变量使用时间窗口差值,并关联业务吞吐。
深度加餐:持久化是一条接力链
提交返回、redo 刷盘、数据页落盘、binlog 可复制是不同事件;把它们混成“已经保存”会误判故障。
先做一个可观察实验
sql
SELECT @@innodb_flush_log_at_trx_commit,
@@sync_binlog,
@@innodb_doublewrite,
@@innodb_redo_log_capacity;
SHOW GLOBAL STATUS
WHERE Variable_name IN (
'Innodb_log_waits',
'Innodb_buffer_pool_reads',
'Innodb_os_log_written'
);预期:先记录刷盘策略,再用状态变量的时间差观察 redo 等待与 buffer pool 命中;不要只看单点数值。
原理下潜与工程边界
Buffer Pool 缓存页,redo 记录物理变更,undo 保留旧版本,binlog 记录逻辑事件;checkpoint 把脏页推进表空间,doublewrite 保护部分页写。
提高性能的刷盘策略会扩大宕机窗口;redo 太小会制造 checkpoint 压力;删除内部文件不能解决磁盘告警。
反例排错路线
把提交延迟、Innodb_log_waits、磁盘 fsync 延迟和复制延迟放在同一时间轴;故障演练后核对恢复点与业务可接受 RPO。
练习加码(仍不提供答案)
加码:画出一次 UPDATE 从 buffer pool 到 redo/binlog/表空间的时序,并给每个阶段写可观测指标。
验收时请补充:一份可复现的环境/数据前提、正常结果、失败结果以及可回滚或清理动作。
继续查阅:MySQL 8.4 参考手册(外部资料已收录于证据账本) · InnoDB 文档(外部资料已收录于证据账本)