Mysql日志篇(Undo log)

122 阅读3分钟

流程图

image.png

Undo log 概念

Undo log是逻辑日记、回滚日记。比如一条修改+3的逻辑语句,Undo log会记录对应一条-3的逻辑日记,一条插入语句则会记录一条删除语句,这样发生错误时,根据执行Undo log就可以回滚到事务之前的数据状态。

作用

  1. 回滚数据,当程序发生异常错误时等,根据执行Undo log就可以回滚到事务之前的数据状态,保证原子性,要么成功要么失败。
  2. MVCC一致性视图:通过Undo log找到对应的数据版本号,是保证MVCC视图的一致性的必要条件。
  3. 在系统崩溃时,未提交的事务需要通过 Undo Log 回滚以确保数据一致性。

Undo log 的存储位置

  • 内存:事务开始时,Undo log 记录最初的数据状态,并存储在内存中。
  • 磁盘:当内存中的 Undo log 需要持久化时,写入到磁盘中的 undo tablespace

Undo Log 的类型

根据操作类型,Undo Log 主要分为以下两种:

  1. Insert Undo Log

    • 用于记录事务中新增记录的操作。
    • 事务未提交前,如果新增的记录被回滚,则通过 Insert Undo Log 删除记录。
    • 提交后,Insert Undo Log 通常会立即被清理(因为不会被 MVCC 使用)。
  2. Update Undo Log

    • 用于记录事务中更新或删除记录前的旧数据版本。
    • 提供 MVCC 支持,为未提交事务或快照读提供一致性视图。
    • 需要等所有事务不再访问该版本时,由 Purge 线程清理

Undo Log 的清理机制

  1. 事务提交后清理

    • 对于 Insert Undo Log,事务提交后可以立即清理。
    • 对于 Update Undo Log,清理需要等待不再有其他事务访问它。
  2. Purge 线程

    • 专门用于清理不再使用的 Undo Log
    • Purge 线程会定期检查是否有可以清理的 Undo Log

Undo Log 的工作流程

1. 事务开始

  • 当事务开始修改数据时,InnoDB 会先记录被修改数据的当前状态到 Undo Log 中。
  • Undo Log 与事务 ID 绑定,用于区分不同事务的操作。

2. 数据修改

  • 修改数据时:

    1. 将数据页加载到缓冲池中进行操作。
    2. Undo Log 中记录被修改数据的快照(旧值)。
    3. 修改后的新值写入缓冲池,并通过 redo log 保证提交后的持久化。

3. 事务提交

  • Undo Log 不会立即删除,提交后的数据可能仍然被其他事务需要(MVCC)。
  • 对于 Insert Undo Log,通常在事务提交后即可清理。
  • 对于 Update Undo Log,需要等待所有引用该版本的事务结束,由后台的 Purge 线程清理。

4. 事务回滚

  • 如果事务需要回滚,InnoDB 会通过 Undo Log 中存储的旧版本数据,将数据恢复到修改前的状态。

5. MVCC 的支持

  • 快照读时,读取数据时如果遇到未提交的事务(Read View中的活跃事务集合列表判断),会通过 Undo Log 查找旧版本,直到找到事务开始时的一致性版本。

undo log和redo log的举例:

假设有A、B两个数据,值分别为1,2。

  1. 事务开始
  2. 记录A=1 到undo log中
  3. 修改A=3记录到redo log
  4. 记录B=2 到undo log中
  5. 修改B=4记录到redolog
  6. 将undo log写到磁盘 -------undo log持久化
  7. redo log写入到磁盘 ----- redo log持久化
  8. bin log写入到磁盘 ----- binlog持久化
  9. 将数据写到磁盘 -------数据持久化
  10. 事务提交 -------提交事务