首页 > 编程知识 正文

mysql树形结构深度,mysql间隙锁与mvcc

时间:2023-05-06 05:32:02 阅读:166619 作者:3877

1. MVCC的基本概念

1.1类数据库并发方案

读取-读取:没有问题,也不需要同时控制

读-写:有线进程的安全问题可能会导致事务分离问题,可能会遇到污读、幻读和不可重复的读取

写入:可能存在有线流程安全问题、更新丢失问题

什么是1.2mvcc

MVCC、全称多版本控制(multi-versionconcurrencycontrol )或多版本并发控制是乐观锁定的一种实现方式,可以实现无读写冲突、解决读写冲突的无锁定并发控制

注意:

MVCC仅在两个隔离级别上运行:读命令和读命令。

1.3快照引线和当前引线的解释

快照读取:

简单的select操作不需要上锁,基于MVCC和undo log来实现,读取记录的可视版本(可能是历史版本)。

当前加载:

特殊读取操作必须锁定,这是一种悲观锁定,它读取记录的最新版本,并锁定当前读取并返回的记录,以防止其他事务同时修改此记录。

插入/更新/删除

select .for update

select . lock in share mode

2. MVCC的基础实现

MVCC的目的是多版本并发控制,在数据库中的实现是为了解决读写的冲突,其实现原理主要依靠记录中的3个隐含字段,undo log,Read View来实现。

InnoDB MVCC的实现基于还原日志,通过回滚指针来构建所需的版本记录。 确定ReadView将显示哪些版本的数据。 Purge线程还会在ReadView中清理旧版本的数据。

2 .一个隐式字段

DB_TRX_ID

6byte,最近更改事务ID (更改/插入) :创建记录/上次修改记录的事务ID

DB_ROLL_PTR

与7byte、undo log一起使用的回滚指针,用于指向此记录的上一个版本

DB_ROW_ID

6如果6byte、隐式自增量ID (隐藏主键)或数据表中没有主键,InnoDB会自动使用DB_ROW_ID生成聚簇索引

注意:

实际上,每个记录的标头信息(record header )都有一个特殊的位(deletedflag ),用于指示当前记录是否已被删除

2.2还原日志

2.2.1基本概念

还原日志主要记录数据的逻辑变化,要在发生错误时回滚上一个操作,必须记录所有上一个操作,然后才能在发生错误时回滚。

角色:

回滚事务处理

还原日志用于保留数据更改前的值。 如果此更改出现异常,可以使用还原日志执行回滚操作以确保事务完整性。

还原日志只是在逻辑上将数据库恢复到其原始状态,在回滚时实际上执行的是相反的任务

MVCC用

还原日志的类型主要包括:

插入还原日志

更新还原日志

2.2.2插入还原日志

插入还原日志是由插入操作生成的还原日志。 因为insert操作的记录只显示在事务本身中,而不显示在其他事务中。 因此,可以在提交事务后直接删除此还原日志,而不需要purge操作。

2.2.3更新还原日志

update undo log记录为delete和update操作生成的undo log。 由于此还原日志必须提供MVCC机制,因此如果事务不再可提交,请将其删除。 在提交时放入还原日志链表,等待purge线程进行最后的删除。

具体工作原理应分以下情况进行研究

2.2.3.1更新主键

集群索引和辅助索引都不能进行in place update。 将生成这两个版本

update分两个阶段运行,首先删除该行,然后插入所需的行

2.2.3.2更新非主键

聚簇索引可以输入放置更新,辅助索引生成两个版本

聚集索引记录还原日志,而辅助索引不记录还原日志

必须更新二级索引,才能确定是否要更改索引页的MAX_TRX_ID

2.2.3.3删除操作

删除操作实际上并不直接删除,只是标记为删除,最后的删除操作由purge线程完成

2.2.4 purge线程的主要作用有以下两个:

清除还原日志

清除page中具有Delete_Bit标志的数据行。 在InnoDB中是指

务中的Delete操作实际上并不是真正的删除掉数据行,而是一种Delete Mark操作,在记录上标识删除,真正的删除工作需要后台purge线程去完成。

2.3 Read View(读视图)

2.3.1 什么是Read View

Read View就是事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)

2.3.2 作用

Read View主要是用来做可见性判断的, 即当我们某个事务执行快照读的时候,对该记录创建一个Read View读视图,把它用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。

2.3.3 核心算法(可见性算法)

Read View的三个属性trx_ids

一个数值列表,用来维护Read View生成时刻系统正活跃的事务ID

up_limit_id

记录trx_ids列表中事务ID最小的ID

low_limit_id

ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1

可见性判断的流程

遍历DB_TRX_ID执行以下步骤,直到找到当前事务可见的最新数据:

遍历方法:如果当前DB_TRX_ID这条记录不满足当前事务的可见性,可通过这条记录的DB_ROLL_PTR回滚指针去取出undo log中前一个版本的DB_TRX_ID

step1:比较DB_TRX_ID 小于 up_limit_id

如果小于,则当前事务能看到DB_TRX_ID 所在的记录;即该记录是可见的最新的记录

如果大于等于进入step2

step2:判断 DB_TRX_ID 大于等于 low_limit_id

如果大于等于则代表DB_TRX_ID 所在的记录在Read View生成后才出现的,那对当前事务肯定不可见,继续遍历下一个DB_TRX_ID

如果小于则进入step3

step3:判断DB_TRX_ID 是否在活跃事务之中

如果在,则代表当前事务的Read View生成时刻,DB_TRX_ID这个事务还在活跃,还没有Commit,DB_TRX_ID这个事务修改的数据,当前事务也是看不见的;即对当前事务不可见,继续遍历下一个DB_TRX_ID

如果不在,则说明,DB_TRX_ID这个事务在当前事务的Read View生成之前就已经Commit了,DB_TRX_ID这个事务修改的结果,对于当前事务是可见的

3. MVCC的工作原理

3.1 MVCC查询的工作流程

3.1.1 查询主键索引

生成Read View读视图

通过主键查找记录,根据记录里的DB_TRX_ID与Read View读视图进行可见性判断

配合DB_ROLL_PTR回滚指针和undo log来找到当前事务可见的数据记录

3.1.2 查询二级索引

生成Read View读视图

比较读视图的up_limit_id与MAX_TRX_ID大小

如果MAX_TRX_ID  小于本次Read View的up_limit_id,则全部可见,过滤记录中的有效记录

否则,无法通过二级索引判断可见性,需要一次遍历每条记录,反查到聚簇索引记录,通过聚簇索引记录来判断可见性

3.2 MVCC与隔离级别

MVCC 只在 Read Commited 和 Repeatable Read两种隔离级别下工作。在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;

这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。

即RR级别下,快照读生成Read View时,Read View会记录此时所有其他活动事务的快照,这些事务的修改对于当前事务都是不可见的。而早于Read View创建的事务所做的修改均是可见

4. 参考

https://www.cnblogs.com/AlmostWasteTime/p/11466520.html

https://www.jianshu.com/p/8845ddca3b23

https://www.zhihu.com/question/27674363/answer/38034982

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html

https://www.cnblogs.com/xibuhaohao/p/11947041.html

https://blog.csdn.net/qiuyepiaoling/article/details/8054346

https://blog.csdn.net/shaochenshuo/article/details/76137652

https://www.cnblogs.com/stevenczp/p/8018986.html

https://www.cnblogs.com/rongdi/p/13378892.html

https://www.jianshu.com/p/336e4995b9b8

http://mysql.taobao.org/monthly/2015/04/01/

https://www.pianshen.com/article/50271826706/#Innodb__2

http://mysql.taobao.org/monthly/2018/11/04/

https://www.jianshu.com/p/8845ddca3b23

https://www.cnblogs.com/micrari/p/8144339.html更多的干货好文,欢迎关注公众号:小青菜的技术博客

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。