mysql中InnoDB存储引擎的事务支持与ACID特性

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

mysql中innodb存储引擎的事务支持与acid特性

InnoDB 默认支持事务,无需额外开启

MySQL 5.5 及以后版本中,InnoDB 是默认存储引擎,且**事务支持是内置开启的**。只要建表时没显式指定 ENGINE=MyISAM 等不支持事务的引擎,就自动具备事务能力。不需要手动执行 SET AUTOCOMMIT=1 或调用 START TRANSACTION 来“启用”事务——它们只是控制事务边界的行为,不是开关。

ACID 中的 A(原子性)靠 undo log 实现

执行 UPDATEDELETEINSERT 时,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(间隙锁 + 行锁)防止幻读,但也因此更容易出现死锁。

播记

播记

播客shownotes生成器 | 为播客创作者而生

下载

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_logfile0ib_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 logredo logbuffer poollock system 这几块具体机制协同实现的。最容易被忽略的是:事务是否生效,首先得确认表引擎确实是 InnoDB,而不是因为建表语句漏写引擎、或者被 ALTER TABLE ... ENGINE=MyISAM 意外改掉。

https://www.php.cn/faq/1963839.html

发表回复

Your email address will not be published. Required fields are marked *