事务工作原理

2022-01-25 19:13:43

redo log 的应用

redo log 重做日志如何应用:

  1. 用户发起 update 事务语句,将磁盘数据页加载到内存(buffer_pool)缓冲区。
  2. 在内存中发生数据页修改,形成脏 页,更改中数据页的变化,记录到 redo buffer 中,加入对应字节大小的日志,更新 LSN。
  3. commit 语句执行时,基于 WAL 机制,等到 redo buffer 中的日志完全落盘到 ib_logfileN 中,commit 正式完成。
  4. 最终 ib_logfileN 中记录了一条日志,内容为某数据页发生了变化,生成了新的 LSN 号。

情景: 当 redo 日志被刷写到磁盘,但数据页依旧是脏页,此时宕机了。

  1. MySQL CR(自动故障恢复)工作模式,启动数据库时,自动检查 redo log 的 LSN 和原数据页 LSN。
  2. 如果发现 redoLSN > 原数据页的 LSN ,加载 原始数据页+变化 redo log 到内存。使用 redo log 重构脏页(前滚)。
  3. 如果确认此次事务已经提交(commit 标签),立即触发 CKPT 动作,将脏页刷写到磁盘上。

补充一点:

redo log 主要保证了 ACID 中是 D(持久性) 的特性,另外 A(原子性)、C(一致性) 也有间接关联。

undo log 的应用

  1. 事务发生数据页修改之前,会申请一个 undo 事务操作,保存事务回滚日志(逆向操作的逻辑日志)。
  2. undo log 写完之后,事务会修改内存中数据页头部(会记录 DB_TRX_ID+DB_ROLL_PTR),这个信息也会被记录的 redo log。

情景 1:当执行 rollback 命令时。根据数据页的 DB_TRX_ID+DB_ROLL_PTR 信息,找到 undo log,进行回滚。

情景2:事务未执行完毕宕机。

假设: undo log 有,redo log 没有。

假设:undo log 有,redo log也有(没有 commit 标签。)

  1. MySQL CR(自动故障恢复)工作模式,启动数据库时,自动检查 redo log 的 LSN 和数据页 LSN。

  2. 如果发现 redoLSN > 数据页的LSN ,加载 原始数据页+变化 redo log 到内存。使用 redo log 重构脏页(前滚)。

  3. 如果确认此次事务没有 commit 标记,立即触发回滚操作,根据 DB_TRX_ID+DB_ROLL_PTR 信息,找到 undo log ,实现回滚。

以上流程被称之为 InnoDB 的核心特性:自动故障恢复(Crash Recovery)。先前滚再回滚,先应用 redo 再应用 undo。

undo log 在 ACID 中主要保证了主要保证事务的 A(原子性)的特性,同时 C(一致性) 和 I(隔离性) 的特性也有关系。

事务中的 C 特性怎么保证?

mysqld process crash in the middle of a page write, InnoDB can find a good copy of the page from the doublewrite buffer during crash recovery.