MySQL的buffer-pool的缓存中,修改语句在执行时,是先更新buffer-pool,还是先更新数据库
目录
MySQL的buffer pool的缓存中,修改语句在执行时,是先更新buffer pool,还是先更新数据库
在 MySQL 的 InnoDB 存储引擎中,修改语句(如
UPDATE
、
INSERT
、
DELETE
)的执行流程遵循
“先修改内存(Buffer Pool),再异步刷盘”
的机制。具体流程如下:
1. 修改操作的核心流程
Step 1:修改 Buffer Pool
- 当执行修改语句时,InnoDB 首先在内存的 Buffer Pool 中找到对应的数据页(Page)。
- 如果数据页不在 Buffer Pool 中,会先从磁盘加载到内存,再进行修改。
- 修改后的数据页会被标记为 “脏页”(Dirty Page) ,表示内存与磁盘数据不一致。
Step 2:写入 Redo Log(保证持久性)
- 在修改 Buffer Pool 的同时,InnoDB 会生成 Redo Log (重做日志),记录数据的变更操作。
- Redo Log 会先写入
Log Buffer
(内存中的日志缓冲区),然后根据配置策略(
innodb_flush_log_at_trx_commit
)刷到磁盘的 Redo Log 文件中。 - 关键作用 :即使系统崩溃,也可以通过 Redo Log 恢复未刷盘的脏页数据。
Step 3:异步刷盘(延迟写磁盘)
脏页不会立即写入磁盘,而是由后台线程(
InnoDB Master Thread
)通过 Checkpoint 机制 异步刷新到磁盘的数据文件中。刷盘时机由以下因素触发:
- Buffer Pool 空间不足时(LRU 淘汰机制)。
- Redo Log 写满需要循环复用。
- 系统空闲时主动刷脏页。
2. 为什么先修改 Buffer Pool,而不是直接写磁盘?
- 性能优化 :直接写磁盘(随机 I/O)速度极慢,而修改内存(Buffer Pool)是纳秒级操作,通过异步刷盘将随机写转换为顺序写(Redo Log),极大提升吞吐量。
- 事务持久性保障 :Redo Log 是顺序追加写入,即使脏页未刷盘,只要 Redo Log 落盘,事务的持久性(Durability)就能通过 Redo Log 恢复来保证。
- 并发控制 :所有修改操作在内存中完成,避免频繁的磁盘 I/O 阻塞其他操作。
3. 关键机制与组件
(1) Redo Log(重做日志)
作用 :记录事务对数据页的物理修改,用于崩溃恢复。
写入策略 :
innodb_flush_log_at_trx_commit=1
:每次事务提交时刷盘(默认,严格保证持久性)。innodb_flush_log_at_trx_commit=0/2
:延迟刷盘(高性能但可能丢数据)。
(2) Checkpoint 机制
- 触发条件 :定期将脏页刷新到磁盘,并更新 Redo Log 的检查点位置。
- 目的 :缩短崩溃恢复时需要重放的 Redo Log 范围。
(3) Double Write Buffer(双写缓冲区)
- 作用 :解决“部分写失效”(Partial Page Write)问题,确保数据页写入磁盘的原子性。
- 流程 :脏页刷盘前,先写入 Double Write Buffer,再写入实际数据文件。
4. 流程图解
修改操作执行
│
▼
1. 修改 Buffer Pool 中的数据页(标记为脏页)
│
▼
2. 生成 Redo Log 并写入 Log Buffer
│
▼
3. 事务提交时,根据策略将 Redo Log 刷盘
│
▼
4. 后台线程异步将脏页刷到磁盘(Checkpoint 触发)
│
▼
5. 刷盘完成后,脏页标记为干净页
5. 总结
- 核心逻辑 : 先修改 Buffer Pool(内存),再异步刷盘(磁盘) 。
- 关键保障 :通过 Redo Log 保证事务持久性,通过异步刷盘提升性能。
- 设计哲学 :用内存加速写操作,用日志保证可靠性,用异步机制平衡性能与安全。