Skip to content

Innodb是如何实现事务的

以下是 InnoDB 通过 Buffer Pool、Log Buffer、Redo Log、Undo Log 实现事务(以 UPDATE 为例)的核心机制总结:


1. Buffer Pool(缓冲池)

  • 作用:内存缓存区,缓存磁盘中的表/索引数据页(Page)。
  • UPDATE 流程
    1. 从磁盘读取目标数据页到 Buffer Pool(若不存在)。
    2. 在 Buffer Pool 中修改数据页内容(此时页变为 脏页 Dirty Page)。
    3. 延迟写入磁盘:脏页不会立即刷盘,由后台线程异步处理(提高性能)。

2. Undo Log(回滚日志)

  • 作用
    • 回滚:记录数据修改前的值,用于事务回滚(ROLLBACK)。
    • MVCC:构建多版本数据链,支持非锁定读(SELECT 读取旧版本)。
  • UPDATE 流程
    1. 修改数据前,将旧值写入 Undo Log(生成回滚记录)。
    2. 若事务回滚,则用 Undo Log 恢复原始数据。
    3. 事务提交后,Undo Log 不会立即删除(可能被其他事务的 MVCC 读引用)。

3. Redo Log(重做日志)

  • 作用:保证事务的 持久性(Durability)
    • 记录数据页的 物理修改(如 Page ID、偏移量、修改值)。
    • 崩溃恢复时重放未落盘的修改。
  • UPDATE 流程
    1. 修改 Buffer Pool 数据页前,生成 Redo Log 记录。
    2. Redo Log 暂存于内存的 Log Buffer
    3. 事务提交时,Log Buffer 按策略刷盘(innodb_flush_log_at_trx_commit 控制):
      • =1:同步写磁盘(确保不丢失)。
      • =0/2:延迟写(性能更高,但可能丢失部分数据)。

4. Log Buffer(日志缓冲区)

  • 作用:Redo Log 的临时内存缓冲区。
  • UPDATE 流程
    1. Redo Log 记录先写入 Log Buffer。
    2. 事务提交时触发刷盘(由参数控制策略)。
    3. 避免每次修改都写磁盘,提升性能。

UPDATE 操作完整流程


崩溃恢复机制

  1. Redo Log 重做
    • 重放已提交事务的 Redo Log,恢复 Buffer Pool 中的脏页。
  2. Undo Log 回滚
    • 对未提交的事务,用 Undo Log 回滚修改。

关键设计思想

  1. Write-Ahead Logging (WAL)
    Redo Log 先于数据页落盘(确保持久性)。
  2. 随机写转顺序写
    数据页修改(随机写) → Redo Log 追加(顺序写),大幅提升 IO 效率。
  3. 异步刷脏页
    事务提交只需保证 Redo Log 落盘,脏页由后台线程批量写入磁盘。
  4. 两阶段提交(2PC)
    与 Binlog 协作时,通过 Redo Log 的 preparecommit 状态保证一致性。

核心组件对比

组件作用持久化时机是否崩溃恢复必需
Buffer Pool缓存数据页异步刷脏页
Log Buffer缓存 Redo Log事务提交时控制刷盘
Redo Log保证事务持久性事务提交时强制刷盘✔️
Undo Log支持回滚与 MVCC随 Redo Log 间接持久化✔️

关键结论

  • 提交性能:由 Redo Log 刷盘效率决定(顺序写远快于随机写)。
  • 数据安全:事务提交后即使脏页未落盘,Redo Log 也能保证数据不丢失。
  • 回滚能力:Undo Log 使得任意时刻回滚成为可能。

Released under the MIT License.