事务的 ACID 特性是数据库系统保证数据一致性和可靠性的基石。ACID 是四个特性的首字母缩写:原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolation) 和 持久性 (Durability)。
在 MySQL 中,这些特性主要由 InnoDB 存储引擎通过一系列复杂的内部机制来保障。
1. 原子性 (Atomicity)
- 定义:事务是一个不可分割的最小工作单元。事务中的所有操作要么全部成功提交,要么全部失败回滚。不存在部分成功的情况。
- 保障机制:Undo Log (回滚日志)
- 作用:记录数据被修改之前的值(旧值)。
- 工作原理:
- 当事务对数据进行修改(INSERT, UPDATE, DELETE)时,InnoDB 会先将修改前的数据写入 Undo Log。
- 如果事务执行失败或执行了
ROLLBACK,InnoDB 就可以利用 Undo Log 中的旧值,将数据恢复到事务开始前的状态,实现“回滚”。
- 关键点:Undo Log 保证了事务的“全有或全无”。
2. 一致性 (Consistency)
- 定义:事务执行前后,数据库都必须处于一致的状态。这意味着数据必须满足预定义的约束(如主键、外键、唯一性、数据类型等),不会破坏数据的完整性。
- 保障机制:综合机制
- 原子性 (Undo Log):防止因部分操作失败导致数据处于中间状态。
- 隔离性 (锁机制 & MVCC):防止并发事务相互干扰导致数据不一致。
- 持久性 (Redo Log):确保已提交的事务结果不会丢失。
- 约束检查:在事务执行过程中,MySQL 会检查主键、外键、唯一索引、NOT NULL 等约束。如果违反约束,事务会失败并回滚。
- 关键点:一致性是最终目标,由 A、I、D 共同保障。它不是由单一机制实现,而是通过其他三个特性的协同作用来达成的。
3. 隔离性 (Isolation)
- 定义:多个并发执行的事务之间是相互隔离的,一个事务的执行不应影响其他事务。这可以防止“脏读”、“不可重复读”、“幻读”等问题。
- 保障机制:锁机制 (Locking) 和 MVCC (多版本并发控制)
- 锁机制:
- 共享锁 (S Lock / 读锁):允许多个事务同时读取同一资源,但阻止写操作。
- 排他锁 (X Lock / 写锁):阻止其他任何事务读取或写入被锁定的资源。
- InnoDB 会自动为事务涉及的数据行或页加锁,确保串行化访问。
- MVCC (Multi-Version Concurrency Control):
- 核心思想:为数据行保存多个版本(通过
Undo Log实现)。 - 工作原理:当一个事务读取数据时,InnoDB 会根据该事务的“快照”(Read View)找到一个合适的历史版本(可能来自 Undo Log),而不是直接读取最新的、可能被其他事务修改但未提交的数据。
- 优势:读操作不需要加锁,极大提高了并发性能。写操作只锁定修改的行。
- 核心思想:为数据行保存多个版本(通过
- 隔离级别:MySQL 提供了四种隔离级别(
READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE),通过调整锁和 MVCC 的行为来平衡一致性和并发性。InnoDB 默认使用REPEATABLE READ。
- 锁机制:
4. 持久性 (Durability)
- 定义:一旦事务成功提交,其对数据库的修改就是永久性的,即使系统发生故障(如断电、崩溃),数据也不会丢失。
- 保障机制:Redo Log (重做日志)
- 作用:记录数据被修改之后的值(新值)以及如何重做这些修改。
- 工作原理 (Write-Ahead Logging - 预写日志):
- 当事务修改数据时,InnoDB 会先将修改操作(如“将某行的值从 A 改为 B”)写入 Redo Log Buffer(内存中)。
- 在事务提交时,Redo Log Buffer 中的内容会被强制刷新 (fsync) 到磁盘上的 Redo Log File(如
ib_logfile0,ib_logfile1)。 - 只有 Redo Log 成功写入磁盘,事务才被认为已提交。
- 后续,InnoDB 的后台线程会将内存中(Buffer Pool)的脏页(被修改过的数据页)异步刷新到磁盘数据文件(
.ibd)。
- 崩溃恢复:如果系统崩溃,重启后,InnoDB 会读取 Redo Log 文件,将已提交但未写入数据文件的事务重新执行一遍(重做),从而保证数据不丢失。
- 关键点:Redo Log 的写入是顺序 I/O,比随机写入数据文件(
.ibd)快得多,这保证了提交性能。
总结:ACID 与 MySQL 机制对应表
| ACID 特性 | 定义简述 | MySQL (InnoDB) 保障机制 |
|---|---|---|
| A 原子性 | 全做或全不做 | Undo Log (记录修改前的值,用于回滚) |
| C 一致性 | 数据始终有效、完整 | 综合机制 (A + I + D + 约束检查) |
| I 隔离性 | 并发事务互不干扰 | 锁机制 (S/X Lock) + MVCC (多版本并发控制) |
| D 持久性 | 提交后永不丢失 | Redo Log (预写日志,先写日志后写数据) |
核心思想:InnoDB 通过 Undo Log 保证原子性,通过 Redo Log 保证持久性,通过 锁和 MVCC 保证隔离性,最终共同实现数据的一致性。这些机制协同工作,构成了 MySQL 可靠性的核心。