跳转至

5. 日志系统

MySQL 的日志系统是数据安全和高可用的基石。

5.1 Redo Log:Crash-safe 的基石

  • 作用:确保事务的**持久性**。防止数据库宕机导致数据丢失。
  • 特点
    • 物理日志:记录的是“在某个数据页上做了什么修改”。
    • 循环写:空间固定,写满后会覆盖旧日志。
    • WAL (Write-Ahead Logging):先写日志,再写磁盘。
  • 刷盘策略 (innodb_flush_log_at_trx_commit)
    • 0:每秒写入磁盘一次(性能最好,可能丢 1 秒数据)。
    • 1:每次事务提交都写入磁盘(最安全,默认)。
    • 2:每次事务提交写入 OS Cache,每秒刷盘(介于两者之间)。

5.2 Binlog:主从复制的纽带

  • 作用:用于**主从复制**和**数据恢复**。
  • 特点
    • 逻辑日志:记录的是 SQL 语句的原始逻辑。
    • 追加写:文件写满后切换新文件,不会覆盖。
  • 格式
    • Statement:记录 SQL 语句。优点是日志小,缺点是某些函数(如 now())可能导致主从不一致。
    • Row:记录每一行数据的变化。优点是数据一致性高,缺点是日志大。
    • Mixed:混合模式。

5.3 两阶段提交 (Two-Phase Commit)

为了保证 Redo Log 和 Binlog 的逻辑一致性,MySQL 使用了两阶段提交。

  1. Prepare 阶段:InnoDB 将 Redo Log 写入磁盘,并标记为 prepare 状态。
  2. Binlog 阶段:Server 层将 Binlog 写入磁盘。
  3. Commit 阶段:InnoDB 将 Redo Log 标记为 commit 状态。

崩溃恢复逻辑: * 如果 Binlog 没写完就崩了 -> 回滚事务。 * 如果 Binlog 写完了,Redo Log 还是 prepare -> 提交事务。