MySQL三种log的作用

54 阅读2分钟

核心组件

  • Buffer Pool: 主内存中的一个区域,用于缓存表和索引数据。所有的读写操作都首先在buffer pool中进行。
  • Undo Log: 记录数据被修改前的旧版本。用于保证事务的原子性和一致性(MVVC)。
  • Redo Log: 记录数据页的物理修改。用于保证事务的持久性。
  • Bin Log: Mysql Server层的日志,记录的是语句的逻辑日志,用于主从复制和数据恢复。
  • .ibd数据文件: 最终存储表和索引数据的磁盘文件。

MySQL更新操作流程

graph TD
    A[执行UPDATE语句] --> B{数据页在Buffer Pool?}
    B -- 否 --> C[从磁盘加载数据页到Buffer Pool]
    B -- 是 --> D[继续]
    C --> D

    subgraph "事务执行与提交 (同步/快速)"
        D --> E[写Undo Log: 记录旧数据镜像]
        E --> F[在Buffer Pool中更新数据, 产生脏页]
        F --> G[写Redo Log Buffer: 记录物理修改]
        G --> H[事务提交?]
        H -- 是 --> I[两阶段提交开始]
        I --> J[Redo Log刷盘: PREPARE状态]
        J --> K[Binlog刷盘]
        K --> L[Redo Log刷盘: COMMIT状态]
    end

    subgraph "数据落盘 (异步/后台)"
        L --> M[事务提交完成, 返回客户端]
        M --> N[Page Cleaner线程异步将脏页刷回磁盘]
    end

事务执行与日志写入

  1. 加载数据页(如果需要);
  2. 记录undo log;
  3. 修改buffer pool中的数据;
  4. 写入redo log buffer;
  5. 写入redo log file(prepare)和写入bin log cache;
  6. 事务最终提交(Commit);

我理解这里的prepare/commit两阶段提交是用来控制redo log/bin log两者的一致性。

后台异步处理(后台线程负责)

  1. 脏页刷盘;

MySQL崩溃恢复流程

重做(Redo)- 前滚

  1. InnoDB启动后,首先检查Redo log file;
  2. 重放Redo log中的修改操作,无论是prepare/commit状态;

归档(Binlog)检查与提交/回滚

  1. 重做之后,Redo log存在2种状态,prepare和commit状态。commit状态无需处理;prepare状态的需检查bin log再做决定;
  2. InnoDB根据事务的XID去bin log文件中查找,来判断这个事务的bin log是否已经被写入。bin log存在且完整:在redo log中补充commit标记即可;bin log缺失或不完整:认为这个事务是无效的,使用undo log来回滚这个事务的所有修改;

注意:undo log是存在innoDB表空间里的,undo log也是通过redo log来持久化的。

graph TD
    A[MySQL服务启动] --> B[崩溃恢复流程开始]
    B --> C[扫描Redo Log,重做所有Page修改<包括PREPARE和COMMIT状态>]
    C --> D[重做完毕,数据库状态=宕机前的内存状态]
    
    D --> E{开始两阶段提交扫描}
    E --> F[情况1: Redo Log中事务状态为COMMIT]
    F -- 事务已完整提交 --> G[无需操作, 事务有效]

    E --> H[情况2: Redo Log中事务状态为PREPARE]
    H --> I[查找该事务对应的Binlog]
    I --> J{Binlog是否存在且完整?}
    J -- 是 --> K[事务有效, 在Redo Log中<br>标记为COMMIT<提交>]
    J -- 否 --> L[事务无效, 用Undo Log<br>回滚该事务<回滚>]

    K & L & G --> M[恢复流程结束<br>数据库达到一致性状态]

bin log的作用

  • 主从复制
  • 按时间点恢复
  • 数据归档

MySQL的“双1”配置

“双1”配置提供最高级别的数据安全性和一致性保证,尤其是在数据库崩溃或断电的情况下。

  • innodb_flush_log_at_trx_commit:控制redo log刷盘行为;
  • sync_binlog:控制bin log刷盘行为;

innodb_flush_log_at_trx_commit: image.png

1是默认值,最安全;0性能佳,最不安全;2折中。

sync_binlog:

作用
0写入bin log cache就直接返回,不主动fsync,依赖操作系统来刷binglog到磁盘
1每次提交事务都强制bin log缓存写入操作系统缓存,并执行fsync强制刷盘
N每N次提交事务才会将bin log缓存写入操作系统缓存,并执行fync强制刷盘

1是默认值,最安全;0性能佳,最不安全;N折中。