mysql-mvcc知识点总结

ACID

  1. Atomicity 原子性: 指整个操作要么都成功,要么都失败,不能有些操作成功有些操作失败。
  2. Consistency 一致性: 指事务的执行结果必须使数据库从一个一致性到另一个一致性状态。什么是不一致性状态?就是当一个事务因某种原因中断时,这个事务对数据库的一些操作被写入到了数据库,这是数据库就是一种不一致性状况。
  3. Isolation 隔离性: 多个同时并发执行的事务不会互相影响,它们最后对数据库造成的结果和它们串行执行结果是一样的。
  4. Durability 持久性:事务提交后,对于数据库的数据的影响是持久的,不会在因为其他故障而造成数据丢失或改变。

事务异常

丢失更新

多个事务都对同一个数据进行修改,后面修改的会覆盖前面修改掉的,仿佛前面的修改就不存在一样。主要有回滚丢失和覆盖丢失两种,一般回滚丢失都不被允许出现。

脏读

事务A读取了事务B尚未提交的更改数据,并在这个读取的数据上继续进行操作。如果这时候事务B进行了回滚,事务A读取的数据就不被承认。

不可重复读

事务A和事务B都读取了同一个数据,事务B对这个数据进行了修改并提交,这时事务A重新在读取一次这个数据,和上一次读取结果不一样。

幻读

事务A在两次读取数据间,发生了事务B提交了新增数据,那么事务A的两次读取结果不一致,大多发生在数据统计中。

隔离级别

读未提交(READ UNCOMMITTED)

事务A 能够读取到事务B未提交却修改了的数据。存在脏读、不可重复读、幻读问题。

读已提交(READ COMMITTED)-oracle默认的级别

事务只能读取提交了的数据。解决了脏读问题,还存在不可重复读和幻读问题。

可重复读(REPEATABLE READ)-MySQL默认的级别

事务A读取了一个数据,事务B也读取了同一个数据并进行修改提交,事务在进行读取这个数据,还会是原来那个数据。

序列化(SERIALIZABLE)

解决了脏读、可重复读和幻读的问题。

隔离级别越高,数据越安全,性能越差。

shared lock共享锁> 允许事务去读取数据,不允许其他事务获得该数据的排他锁。行锁

exclusive lock排他锁> 允许持有的事务对该数据进行修改,禁止其他事务获得该数据的共享锁和排他锁。行锁

Is lock意向共享锁> 在给数据行加共享锁前,要先获得意向共享锁。表锁

Ie lock意向排他锁> 在给数据行加排他锁前,要先获得意向排他锁。表锁

Record Locks 行锁> 锁索引

gap lock 间隙锁> 开区间锁 要RR级别 不互斥

next-key lock 临键锁> 左开右闭锁 在发生在RR级别下,InnoDB对于行的查询都是采用了Next-Key
Lock,还会对辅助索引下一个键值加上gap lock。当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。

insert intention lock 插入意向锁> 用于并发插入。

AUTO-INC lock 自增锁> 用于事务插入自增字段。

悲观锁机制

添加共享锁方式 select x from xx lock in share mode;
添加排他锁方式 select x from xx for update;

乐观锁机制

在表中添加timestamp字段,只有在插入或修改时才会更新字段。
进行修改时,会进行查询timestamp,判断此次查询是否为旧版本。

日志

Redo log
redo log是InnoDB引擎实现的,是一种大小固定的物理日志,用循环顺序的方式记录数据修改变化。MySQL先在内存中保存数据,在事务提交后才修改磁盘数据。在数据库发生异常停止时,可以通过redo log 将已提交的未同步到磁盘的事务数据存到磁盘中,保证事务数据不会丢失,让ACD(原子性、一致性、持久性)原则得到保证。
bin log
binlog是一种逻辑日志,在server层上实现的,和redo log有着相同的功能。但不像redo log有固定大小的空间,不会出现日志覆盖,而且能在所有引擎中使用,可以用于数据恢复、或主从架构的数据复制等。
Undo log
在数据进行修改的时候,会记录下与操作相对应的Undo log,以方便后面进行数据回滚。它是一种逻辑日志,可以认为当你修改了一条数据,那么在Undo log中记录的是将这条数据变回修改前数据的操作。每Undo log采用segment的方式,每一个操作在记录时都是一个undo log segment。事务在insert操作时,会产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃。而updafe、delete等操作产生的日志不仅在回需要,在快照读等其他情况也需要,所以只在不需要了才会删除。有个专门的purge线程会根据delete_id来清理日志信息。

MVCC

Multi-Version Concurrency Control 多版本控制
MVCC只会在READ COMMITTEDREPEATABLE READ两个隔离级别中使用。

当前读
读取数据的最新版本,且会对数据进行加锁。
快照读
读取的可能会是旧版本,基于mvcc来实现,能够有效提高性能,避免加锁。

在innoDB中会在数据库的每一行数据后面添加3个字段。
DB_ROW_ID(6Bytes)

当表中没有主键且没有非NULL的唯一键时,InnoDB会自己创建聚集索引,而这个索引值就是DB_ROW_ID。

DB_TRX_ID(6Bytes)

记录操作这条记录的最新事务id。

DB_ROLL_PTR(7Bytes)

可以理解为指向undo log segment的undo log,是一个回滚指针。

readView
readView是在事务开启时,记录当前还存活的事务的一个集合。
在readView中记录有集合中事务id最大,这里称为max,以及同理的min,还有创建这个readView的事务creatTrxaId,当每个事务创建时,其事务Id是呈递增的。

RC级别下readView会在每一次语句的执行后,重新进行构建一个新的,所以存在不可重复读。
RR级别下readView在事务创建的过程中被创建出来,一直存活到事务结束。

mvcc的比较方式
-> 当对一条数据进行操作时,根据trx_id与readView集合中max进行比较,如果trex_id大于max,说明这条数据是在当前事务生产readView后产生的,不能被访问。
-> 将trx_id与readView集合中min进行比较,如果trex_id小于min,说明这条数据是在当前事务生产readView前产生的,可以被访问。
-> 如果trx_id在min和max之间,就进行判断是否存在于readView,如果存在,说明其对应的事务操作还没结束,不应该被访问。
-> 如果trx_id和creatTrxaId一致,说明这条数据是自己操作,可以直接访问,
-> 当上述条件都不满足时,当前事务就会根据roll_ptr来查找符合自己条件的版本数据。

roll_ptr会指向undoLog中的更早版本的信息
在这里插入图片描述

有什么不足请在评论指出,将不定期补充。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值