ACID特性的实现原理
ACID是衡量事务的四个特性:
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
MySQL的事务是如何实现这个特性的呢?
持久性
持久性相对简单一点。Innodb为例。
定义
持久性是指事务一旦提交,它对数据库的改变是永久性的,如果出现故障也不会改变。
实现原理
Innodb引擎为了读写数据的效率,引入了一个叫做Buffer Pool
的缓冲区,是对磁盘中一部分数据的映射,查询修改的时候会先对这个缓冲区就行操作,过一段时间后,会将修改刷入到磁盘。这样做的弊端是缓冲区还没刷新修改的时候,服务宕机,导致修改不能落盘,也就丢失了数据。
故使用redo log,当数据修改的时候,除了修改Buffer Pool
,也在redo log中记录这个操作,当事务提交后,首先会对redolog刷盘,重启服务后,会读redolog,重做这个操作,保证数据不会丢失。wal(write-ahead logging)先写日志,再更新buffer pool,刷脏成功后,redlog也就没用了
。
redolog写入磁盘快:redolog每次都是追加日志,没有随机io,每次只刷修改部分,而不是整个16kb的页。
隔离性
定义
隔离性事务内部的操作与其他事务是隔离的,并发执行的事务也不应该相互影响。
主要分为两个方面:
- 一个事务的写操作对另一个事务写操作的影响(锁机制保证)
- 一个事务的写操作对另一个事务的读操作的影响(MVCC保证)
原理
锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。
原子性
定义
原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。
原理
基于重做日志undo log实现,当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。
undo log记录的是逻辑操作,是实际数据操作的反操作,比如insert语句,则会记上delete,回滚的时候,直接执行日志。
一致性
定义
一致性是指事务执行结束后,数据库的完整性不能有变化,比如:实体完整性、主键完整性、列完整性、外键约束等。
实现
实现一致性的措施包括:
- 保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证
- 数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等
- 应用层面进行保障,业务逻辑要保证正确