MySQL事务隔离级别以及MVCC(多版本并发控制机制)

1.隔离级别

读未提交:脏读(读取其它事务未提交的数据),不可重复读,幻读

读已提交:不可重复读(一个事务的两次读取数据出现不同的结果,主要是修改操作),幻读

可重复读:幻读(一个事务的两次读取数据出现不同的结果,主要是添加和删除操作)

可序列化:串行操作,每个读取的数据行加上共享锁

2.MVCC:

当前读:基于悲观锁的实现,读到的是最新版本的数据,且会对数据上锁

快照读:基于MVCC的实现,不会对读取的内容上锁,提高并发性能,可能会读到数据的旧版本

MVCC模型:为了实现读-写冲突不加锁,这个读就是指快照读,具体实现通过3个隐式字段,undo日志,Read View等去完成。但不能解决写-写的更新丢失问题,写-写冲突需要悲观锁或乐观锁去解决。

MVCC实现原理:

1.隐式字段:DB_TRX_ID(最近修改的事务ID), DB_ROLL_PTR(回滚指针,指向这条记录的上一个版本), DB_ROW_ID(隐含的自增ID,如果数据表没有主键,InnoDB会自动以该ID产生一个聚簇索引)

实际上还有一个删除flag隐藏字段,当更新或删除时不是真的删除,而是删除flag变了

2.undo日志:

主要分为两种:insert undo log,update undo log

insert undo log代表事务在insert新纪录时产生的undo log,只在事务回滚时需要,并在事务提交后可以被立即丢弃(问题:RR级别的MVCC为什么解决不了幻读 推测:Read View是针对被读取数据产生的,第二次的快照读发现新插入的数据没有产生过Read View,所以针对它产生新的Read View判断其可见性)

update undo log事务在进行update或delete时产生的undo log,不仅在事务回滚时需要,在快照读时也需要,只有在快照读或事务回滚不涉及该日志时,才会被purge线程清除

purge:purge线程自己维护了一个read view(相当于系统中最老活跃事务的read view),如果某个记录的delete_bit为true并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录可以被安全删除

对MVCC实质上有帮助的是update undo log,undo log实际上就是旧记录链表,链首是最新的旧纪录

3.Read View:

事务进行快照读操作时为读取数据生成的读视图,记录并维护系统当前的活跃事务ID,把它比作条件判断当前事务能看到哪个版本的数据。

4.判断流程:

Read View可以简单的理解成有三个全局属性,trx_list(Read View生成时刻,系统内活跃事务的id), up_limit_id(trx_list列表中最小的事务ID), low_limit_id(Read View生成时刻,系统尚未分配的下一个事务ID,也就是已出现过的事务ID的最大值+1)

当进行快照读生成Read View后,判断1)首先会比较被读取数据的DB_TRX_ID和up_limit_id,如果小于,则判断为可见,反之进入下一个判断,判断2)比较DB_TRX_ID和low_limit_id,如果大于,则判断为不可见,反之进入下一个判断,判断3)判断DB_TRX_ID是否存在于trx_list中,如果在,代表Read View生成时刻,这个事务仍在活跃,还未提交,则不可见,反之可见。

5.RC和RR级别下InnoDB快照读的区别:

RR级别下对某条记录的前后两次快照读使用的都是第一次快照读的Read View,RC级别下每一个快照读都会生成新的Read View

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值