Skip to content

页、缓存与日志责任边界 ​

← 本站索引 | 练习答案

可运行 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 内部文件处理磁盘告警。

练习 ​

  1. 将一次 UPDATE 的数据页、undo、redo、binlog 路径画开。
  2. 说明“COMMIT 返回”和“数据页已写回表空间”为什么不等价。
  3. 设计采样,判断 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 文档(外部资料已收录于证据账本)

用心记录每一步成长