ACID
2023-04-11 17:30:29 0 举报
MySQL ACID
作者其他创作
大纲/内容
脏读(Dirty Read)
隔离性(Isolation)
幻读(Phantom Read)
在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。
MVCC仅适用于Read Committed和Repeatable Read隔离级别。Read Uncommitted与MVCC不兼容,是因为查询不会读取适合其事务版本的行版本,而是不管怎样都读最新版本。Serializable与MVCC也不兼容,是因为读取会锁定它们返回的每一行。
一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。
产生
读写锁
一致性(Consistency)
Undo Log
数据库会为每个事务创建一个视图 (ReadView),访问的时候以视图的逻辑结果为准在【读已提交】隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的在【可重复读】隔离级别下,这个视图是在事务启动时就创建的,整个事务存在期间都用这个视图(这就是为什么说在可重复读隔离级别下,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的)
原子性(Atomicity)
持久性(Durability)
多事务并行执行产生的问题
undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作:对于每个insert,回滚时会执行delete;对于每个delete,回滚时会执行insert;对于每个update,回滚时会执行一个相反的update,把数据改回去。实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。
MVCC(Multi-Version Concurrency Control)
读未提交(Read Uncommitted)
可串行化(Serializable)
在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。
原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。
可重复读(Repeatable Read)
redo log属于物理日志,它记录的是数据库中每个页的修改。InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。于是,redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。
解决问题定义的隔离级别
事务的ACID
隔离性是指事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。
强制事务串行执行,对于同一行记录,“写” 会加 “写锁”,“读” 会加 “读锁”,当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。这样可以避免并发一致性问题,解决丢失更新、脏读、不可重复读和幻读问题(所谓幻读,和不可重复读差不多,不过幻读侧重于记录数量的增减,不可重复读侧重于记录的修改)。
Redo Log
不可重复读(Unrepeatable Read)
当前事务A中可以读到其他事务B未提交的数据(脏数据),这种现象是脏读。
读已提交(Read Committed)
持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
0 条评论
下一页