事务的ACID特性

参考:https://baijiahao.baidu.com/s?id=1625607423998953705&wfr=spider&for=pc

mysql逻辑架构图

  • 第一层:处理客户端连接,授权认证等
  • 第二层:服务器层,负责查询语句的解析、优化、缓存。
  • 第三层:存储引擎,负责数据的存储和提取,事务由存储引擎实现的。

ACID(Atomicity原子性,Consistency一致性,Isolation隔离性,Durability持久性)是衡量事务的4个特性。原则上,只有同时满足ACID特性才是事务,但是在各大数据库厂商实现中,真正满足ACID的事务少之又少。

1 原子性

原子性是指一个事务是一个不可分割的工作单位,其中要么都做,要么都不做。

实现原理undo log

InnoDB存储引擎提供了两种事务日志,redo logundo log。其中redo log用于保证事务持久性,undo log保证事务原子性和隔离性。

InnoDB实现回滚,靠的是undo log

  • a当事务对数据库进行修改时,InnoDB会生成对应的undo log
  • b如果事务回滚,则利用undo log将数据回滚到修改之前的样子。

2 持久性

持久性是指,事务一旦提交,它对数据库的改变就应该是永久性的。

实现原理,redo log

InnoDB为了减少磁盘IO次数,提供了Buffer Pool(缓存),作为访问数据库的缓冲。

a当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool

b当向数据库写入数据时,会首先写入Buffer PoolBuffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)

Buffer Pool大大提高了读写性能,但是带来了新的问题,如果mysql宕机,数据有丢失的风险,持久性无法保证。

因此,redo log被引来解决这个问题,当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。

所有修改先写入redo log,再更新到Buffer Pool,保证了数据不会因宕机而丢失。从而满足了持久性的要求。

2.1 redo log和binlog

作用不同:redo log是用于crash recovery的,保证宕机也不会影响持久性。Binlog是用于point-in-time recovery的,保证服务器可以基于时间点恢复数据,此外binlog还用于主从复制。

层次不同:redo logInnoDB存储引擎实现的;binlogMySql服务器层实现的,同时支持InnoDB和其他存储引擎

内容不同:redo log是物理日志,内容基于磁盘的pagebinlog是逻辑日志,内容是一条条sql

写入时机不同:redo log的写入时机相对多元,默认情况下,当事务提交时会调用fsyncredo log进行刷盘。除了事务提交时,还有其他刷盘时机。Binlog在事务提交时写入。

3 隔离性

隔离性针对的是不同事务之间的相互影响。隔离性是指事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

严格的隔离性,对应了事务隔离级别中的可串行化,但实际应用中出于性能的考虑很少使用可串行化。

3.1 锁机制

隔离性要求同一时刻只能有一个事务对数据进行写操作,InnoDB通过锁机制来保证。

  • a 事务在修改数据之前,需要先获得相应的锁。
  • b 获得锁之后,事务便可以修改数据
  • c 该事务操作期间,这部分数据是锁定的,其他事务必须等待。

InnoDB支持行锁和表锁。Myisam只支持表锁。

锁会消耗资源,因此在锁定数据较多的情况下,使用表锁可以节省大量资源。

我们可以通过如下命令查看InnoDB整体状态,其中就包含锁的情况。

mysql> show engine innodb status;

如下是模拟开启两个客户端,开启事务修改同一行数据,但不提交,查询InnoDB状态的信息

我们可以看到事务25812580占用锁的情况。

3.2 脏读

事务A读取到事务B未提交的数据。

3.3 不可重复读

事务A中先后两次读取同一数据,两次读取到的结果不一样。

和脏读的区别,脏读:事务A读到的是事务B未提交的数据。而不可重复读:事务A读取到事务B已提交的数据

3.4 幻读

在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同。

3.5 事务的隔离级别

读未提交、读已提交、可重复读、可串行化

InnoDB默认的隔离级别:可重复读

3.6 MVCC

Multi-Version Concurrency Control,即多版本并发控制。

通过MVCC可以解决脏读、不可重复读、幻读问题。

MVCC最大的优点是读不加锁,读写不冲突,并发性能好。

InnoDB实现MVCC,使得多个版本的数据可以共存,其主要是依靠数据的隐藏列和undo log

数据的隐藏列包含了该数据的版本号、删除时间、指向undo log的指针等等。当读数据时,InnoDB可以根据隐藏列判断是否需要回滚并找到回滚需要的undo log,从而实现MVCC

4 一致性

一致性是事务追求的终极目标。

一致性是指事务执行结束后,数据库的完整性约束没有被破坏。

数据库的完整性约束:实体完整性、列完整性、外键约束、用户自定义完整性。

一致性需要数据库层面的保障和应用程序层面的保障。两者合力才能够尽量确保一致性。比如说如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现有多完美,也无法保证状态的一致。

 

posted @ 2022-12-07 07:33  zhenjingcool  阅读(85)  评论(0编辑  收藏  举报