innodb通过redo log、undo log、行级锁与mvcc协同实现acid:redo log保障持久性,undo log支撑原子性与一致性,行级锁+mvcc保障隔离性;redo与binlog通过两阶段提交协调;undo log记录旧版本供回滚和mvcc读取;next-key lock(行锁+间隙锁)防止幻读,唯一索引等值查询存在时才优化为record lock。
事务的ACID特性在InnoDB中靠什么落地
InnoDB不是靠“声明式支持”来提供事务,而是用一套协同工作的底层机制硬实现的:redo log 保证持久性(D),undo log 保证原子性(A)和一致性(C),而行级锁 + MVCC 一起支撑隔离性(I)。这四者缺一不可,删掉任意一个,START TRANSACTION 就只剩个空壳。
redo log 和 binlog 的分工与协作
很多人误以为 commit 成功 = 数据已刷盘。实际是:事务提交时,InnoDB 只确保 redo log 写入磁盘(由 innodb_flush_log_at_trx_commit 控制),而数据页(ibd 文件)可能还在 buffer pool 中延迟写入。这样既快又安全——崩溃后可用 redo log 重放已提交但未落盘的变更。
binlog 是 Server 层日志,不参与崩溃恢复,只用于主从复制和归档。MySQL 用两阶段提交(2PC)协调二者:prepare 阶段写 redo log 并标记为 prepared;commit 阶段先写 binlog,再将 redo log 标记为 commit。任一环节失败,crash recovery 都能靠这个状态判断是否回滚。
undo log 如何支撑回滚和 MVCC
每次 UPDATE 或 DELETE,InnoDB 不直接覆盖旧数据,而是把原记录写进 undo log,并用 roll_pointer 指向它。这样: