1. redo log、binlog、undo log 的区别?(必考)

对比 redo log(重做) binlog(归档) undo log(回滚)
层级InnoDB 存储引擎层MySQL Server 层InnoDB 存储引擎层
内容物理日志:页级别的修改逻辑日志:SQL 语句/行变更逻辑:反向操作(旧值)
作用崩溃恢复(持久性)主从复制、数据恢复(备份/时间点恢复)事务回滚(原子性)+ MVCC 版本链
写入事务执行中持续写,环形复用事务提交时写事务执行中持续写

为什么需要 redo log(WAL 机制):写磁盘太慢,每次修改先写内存缓冲池(Buffer Pool),把"页的变更"顺序写入 redo log(顺序 IO 快)。提交时 redo 落盘即可,脏页异步刷盘。崩溃后从 redo 重放恢复。WAL = Write Ahead Log,先写日志再改数据。

🎯 面试要点

  • redo 是物理的("页 5 偏移 100 改成 xxx"),binlog 是逻辑的("UPDATE ... WHERE")——两者格式不同
  • redo 保证不丢(持久性),binlog 保证能恢复和复制
  • 刷盘策略:innodb_flush_log_at_trx_commit=1(每次提交刷盘,安全)/0(每秒刷,可能丢 1 秒)

2. 为什么 binlog 和 redo log 要两阶段提交?

redo log 在引擎层、binlog 在 Server 层,两个日志独立写。若不协调,崩溃时可能:redo 已提交但 binlog 没写(从库丢数据),或 binlog 写了但 redo 没提交(主从不一致)。

两阶段提交(prepare → commit):

  1. 事务执行:写 undo(回滚用)→ 改 Buffer Pool → 写 redo(prepare 状态)
  2. 提交时:先写 binlog(落盘)
  3. 再写 redo 的 commit 状态(此时才算真提交)

崩溃恢复规则:redo 是 prepare 且 binlog 完整 → 提交;redo prepare 但 binlog 不完整 → 回滚。保证 redo 与 binlog 状态一致。

🎯 面试要点

  • binlog 是判断依据:binlog 完整才提交(因为从库靠 binlog 同步)
  • MySQL 8.0 的两阶段提交没有被取消(仍是 redo prepare → 写 binlog → redo commit);8.0 的改进是组提交与 binlog 事务依赖跟踪(writeset),以及 redo 日志文件重构
  • 阿里 canal 等中间件监听 binlog 做数据同步/增量,依赖的就是 binlog

3. MySQL 主从复制的原理?

  1. 主库 binlog 写入:事务提交时写 binlog
  2. 从库 IO 线程:连主库,请求 binlog,写入从库的 relay log(中继日志)
  3. 从库 SQL 线程:读取 relay log 并重放执行,数据同步完成

三种复制格式:

复制延迟:主库写快、从库串行重放慢 → 延迟。常见:大事务、从库承担读压力、DDL。延迟会导致读写分离下的"刚写完读不到"。

🎯 面试要点

  • 从库线程演进:MySQL 5.6 起支持并行复制(多线程 SQL 线程,按库/按事务)
  • 主从延迟的缓解:缩小事务、读写分离路由强一致性走主库、半同步复制(等一个从库 ack)
  • binlog 格式 + 隔离级别的关系:STATEMENT 下 RR 更安全(历史原因,MySQL 默认 RR 的由来)

🎤 常见面试追问

  1. redo log 和 binlog 有什么区别?——redo 是引擎层物理日志(页级修改,崩溃恢复用,环形复用);binlog 是 Server 层逻辑日志(语句/行变更,主从复制和数据恢复用,追加写)。
  2. 为什么要两阶段提交(redo 和 binlog)?——两个日志独立写,不协调会主从不一致(redo 提交了但 binlog 没写,从库丢数据)。先写 binlog 再提交 redo,崩溃恢复以 binlog 为准。
  3. WAL 机制是什么?——Write Ahead Log:先写日志再改数据页。写日志是顺序 IO(快),数据页异步刷盘(攒批)——redo log 存在的意义。
  4. 主从延迟怎么缓解?——缩短大事务、并行复制(多线程 SQL 线程)、强一致读走主库、半同步复制(等一个从库 ack)、读写分离路由优化。
  5. binlog 三种格式选哪个?——ROW(默认):记录行变更精确,主从不一致风险最低,推荐;STATEMENT 记录 SQL(快但有非确定函数问题);MIXED 混合。

📖 名词解释(本页术语)

术语 大白话解释
redo log(重做日志)记录"页的修改"的物理日志(先写它再改数据)。崩溃后用它在重启时重放,保证提交的数据不丢(持久性)。
binlog(归档日志)记录所有变更的 Server 层日志:主从复制靠它、误删恢复靠它(时间点恢复)。追加写,可设置过期时间。
undo log(回滚日志)记录"修改前的旧值":事务回滚时恢复旧值(原子性),同时是 MVCC 版本链的来源。
两阶段提交事务提交时先写 binlog(prepare)再提交 redo(commit),保证两个日志一致——主从不乱。
WAL(预写日志)先写日志后改数据的机制:日志顺序写快,数据页可以攒着异步刷。
主从复制主库把 binlog 同步给从库重放:从库 IO 线程拉日志写 relay log,SQL 线程重放。用于读写分离和容灾。
relay log(中继日志)从库暂存主库 binlog 的中间日志,再由 SQL 线程执行。
半同步复制主库提交前至少等一个从库确认收到,减少主从切换时的数据丢失。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。