InnoDB默认支持事务且无需额外开启,ACID通过undo log(原子性)、redo log(持久性)、MVCC(隔离性)和锁机制(一致性)协同实现,建表时需确认引擎确为InnoDB。

InnoDB 默认支持事务,无需额外开启
MySQL 5.5 及以后版本中,InnoDB 是默认存储引擎,且**事务支持是内置开启的**。只要建表时没显式指定 ENGINE=MyISAM 等不支持事务的引擎,就自动具备事务能力。不需要手动执行 SET AUTOCOMMIT=1 或调用 START TRANSACTION 来“启用”事务——它们只是控制事务边界的行为,不是开关。
ACID 中的 A(原子性)靠 undo log 实现
执行 UPDATE、DELETE 或 INSERT 时,InnoDB 会先写入 undo log,再修改数据页。如果事务中途失败或执行 ROLLBACK,就靠 undo log 回滚到之前状态。
-
undo log存在ibdata1或独立表空间里,不是用户直接管理的文件 - 长事务会阻止 undo log 清理,可能引发
Undo tablespace is full报错 -
SELECT不加锁时读的是快照(MVCC),不是最新物理数据,所以不会被未提交事务阻塞
隔离级别影响可见性与锁行为
InnoDB 支持全部四种 SQL 标准隔离级别,但默认是 REPEATABLE READ,这点和 PostgreSQL、SQL Server 不同。它通过 next-key lock(间隙锁 + 行锁)防止幻读,但也因此更容易出现死锁。
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 此后该连接的 SELECT 将看到其他已提交事务的变更 -- UPDATE/DELETE 仍只锁匹配到的行,不锁间隙
-
READ UNCOMMITTED:极少用,可能读到未提交的脏数据,InnoDB 不推荐 -
READ COMMITTED:每次SELECT都生成新快照,适合高并发读场景 -
REPEATABLE READ:事务内多次SELECT结果一致,但需注意UPDATE ... WHERE可能锁住更大范围 -
SERIALIZABLE:隐式为所有SELECT加共享锁,基本等于串行执行,性能损耗大
崩溃恢复靠 redo log 保证 D(持久性)
事务提交前,InnoDB 先把变更写入内存中的 redo log buffer,再刷盘到磁盘上的 ib_logfile0 和 ib_logfile1。即使数据库异常宕机,重启时也能根据 redo log 重放未落盘的已提交事务。
-
innodb_flush_log_at_trx_commit = 1(默认):每次COMMIT都强制刷盘,最安全但有 I/O 开销 -
= 0:每秒刷一次,崩溃可能丢一秒事务 -
= 2:写入 OS cache 即返回,不强制 fsync,崩溃可能丢数据(OS 崩溃时) - 不要仅靠
sync_binlog控制持久性,它管的是 binlog,不是 redo log
InnoDB 的 ACID 不是抽象概念,而是由 undo log、redo log、buffer pool、lock system 这几块具体机制协同实现的。最容易被忽略的是:事务是否生效,首先得确认表引擎确实是 InnoDB,而不是因为建表语句漏写引擎、或者被 ALTER TABLE ... ENGINE=MyISAM 意外改掉。










