Mysql ACID实现原理
重温MySQL的ACID实现原理:深入探索底层设计与机制_数据库acid如何实现-CSDN博客
ACID 是数据库事务正确执行的四个基本要素的缩写,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。以下是 MySQL 中 ACID 原理的详细介绍:
一、原子性(Atomicity)
- 定义
- 原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。就好像一个原子,它是构成物质的基本单位,不能再被细分。
- 在 MySQL 中的实现机制
- MySQL 通过事务日志(redo log 和 undo log)来实现原子性。当一个事务开始时,MySQL 会记录该事务的操作到事务日志中。
- redo log(重做日志):用于记录事务中对数据库的修改操作。如果在事务执行过程中出现故障(如系统崩溃),在系统恢复后,可以根据 redo log 中的记录重新执行这些操作,以保证事务的修改能够被正确地应用到数据库中。
- undo log(回滚日志):用于存储事务执行前的数据状态。如果事务在执行过程中需要回滚,MySQL 可以利用 undo log 中的信息将数据恢复到事务开始之前的状态。例如,在一个转账事务中,从账户 A 转出 100 元到账户 B,undo log 会记录账户 A 原来的余额,当事务需要回滚时,就可以根据 undo log 把账户 A 的余额恢复到转账之前的状态。
二、一致性(Consistency)
- 定义
- 一致性是指事务执行前后,数据库的完整性约束没有被破坏。例如,在一个包含账户余额表的数据库中,转账事务前后,总金额应该保持不变,即数据要符合现实世界中的业务规则和约束。
- 在 MySQL 中的维护方式
- MySQL 通过数据库的约束机制(如主键约束、外键约束、唯一约束等)和事务的原子性来维护一致性。
- 约束机制:在创建表时定义的各种约束条件可以防止非法数据进入数据库。例如,一个表的主键列不能有重复的值。如果一个事务试图插入一条违反主键约束的数据,MySQL 会拒绝该操作,从而保证数据的一致性。
- 结合原子性:当事务中的部分操作违反了一致性规则时,整个事务会回滚,以保证数据库状态不会因为部分错误操作而导致不一致。例如,在一个订单处理事务中,如果在更新库存时出现错误(如库存数量变为负数),整个订单处理事务会回滚,包括订单状态的更新等操作,从而使数据库恢复到事务开始前的一致状态。
三、隔离性(Isolation)
- 定义
- 隔离性是指多个事务并发执行时,一个事务的执行不能被其他事务干扰,多个事务之间要相互隔离。每个事务都感觉不到有其他事务在并发地执行。
- 在 MySQL 中的实现级别和问题
- MySQL 提供了多种隔离级别来控制事务之间的隔离程度,包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。
- 读未提交(Read Uncommitted):这是隔离性最低的级别。在这个级别下,一个事务可以读取到另一个事务未提交的数据,这可能会导致脏读(Dirty Read)问题。例如,事务 A 修改了一条数据但尚未提交,事务 B 却读取了事务 A 修改后的数据,若事务 A 后来回滚了修改,事务 B 读取的数据就是无效的 “脏数据”。
- 读已提交(Read Committed):在这个级别下,一个事务只能读取到其他事务已经提交的数据。可以避免脏读问题,但可能会出现不可重复读(Non - Repeatable Read)的情况。例如,事务 A 在两次读取同一数据的过程中,事务 B 对该数据进行了修改并提交,导致事务 A 两次读取的数据不一致。
- 可重复读(Repeatable Read):这是 MySQL 的默认隔离级别。在这个级别下,一个事务在执行过程中多次读取同一数据时,会得到相同的结果,即使其他事务对该数据进行了修改并提交。不过,在这个级别下可能会出现幻读(Phantom Read)问题。幻读是指一个事务在按照某个条件进行读取操作时,没有读取到某些行,但另一个事务插入了满足该条件的新行,当第一个事务再次按照相同条件读取时,就会出现 “幻行”。
- 串行化(Serializable):这是隔离性最高的级别。在这个级别下,事务是串行执行的,就像排队一样,一个事务执行完另一个事务才能开始,这样可以完全避免脏读、不可重复读和幻读问题,但会导致并发性能下降。
四、持久性(Durability)
- 定义
- 持久性是指一旦事务提交,它对数据库的修改就应该永久保存下来,即使系统出现故障(如断电、磁盘损坏等)也不应该丢失。
- 在 MySQL 中的保障措施
- MySQL 通过将事务的修改记录到磁盘等持久化存储介质来实现持久性。当事务提交时,MySQL 会确保 redo log 中的修改记录被安全地写入磁盘。
- 数据库系统通常会采用一些技术,如日志写入策略、数据文件的同步机制等。例如,MySQL 的 InnoDB 存储引擎采用预写式日志(Write - Ahead Logging,WAL)策略,在修改数据页之前,先将修改操作记录到 redo log 中,并且定期将 redo log 中的内容同步到磁盘的数据文件中,这样即使在数据文件还没有来得及更新的情况下系统出现故障,也可以根据 redo log 来恢复数据,保证事务的持久性。