ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Mysql锁、锁区间,MVCC以及zookeeper分布式锁面试要点解析

2021-02-08 21:57:34  阅读:185  来源: 互联网

标签:语句 事务 记录 版本号 Mysql zookeeper MVCC test id


1.Mysql锁

行级:

共享锁:

只允许读和继续加共享锁,直到commit释放完所有共享锁后才可以写

排它锁:

某一事务加上排它锁后,只有该事务才可以进行增删改查,其他并发事务不可以

表级:

意向锁:

我的理解是:意向锁不是锁。怎么说呢?例如,当我们要进行表中某字段所有行进行更改时,比如说:update table set sal = sal+1时,要确保其他事务不会在当中的任意一行进行读写操作,也就是说要确保每一行都没有事务在对该记录进行操作,因此我们需要一种提示,意向锁就应运而生了,当有一个及一个以上的事务对表中记录操作时,意向锁就自动产生了,这时就不能进行update table set sal = sal+1或者其他有当前事务在读取的操作,直至每一行记录都没有事务在读取,此时,意向锁就释放了,这样就可以update table set sal = sal+1了。意向锁分为意向共享锁和意向排它锁

锁的区间:

在这里插入图片描述
如上图所示:
假设test表中有四行记录,分别以1,4,7,10作为id,

Record Lock(记录锁):

事务1:

begin;
select * from test where id=1 for update;
commit;

仅执行:

begin;
select * from test where id=1 for update;

此时事务2就不能再对id=1的记录进行任何操作包括查看。

Gap Lock(间隙锁,仅存在于RR隔离级别):

事务1:

begin;
select * from test where id>4 and id<7 for update;
commit;

仅执行:

begin;
select * from test where id>4 and id<7 for update;

此时事务2就不能再对在id>4 and id<7区间内的记录进行任何操作包括查看。
注意:

select * from test where id>15 for update;

这条语句锁的区间落在图中Gap的(10,+∞),也就是说锁住的是id>10的这个区间,其他事务就不能再对在(10,+∞)区间内的记录进行任何操作包括查看。

Next-key(临键锁):

begin;
select * from test where id>4 and id<10 for update;
commit;

仅执行:

begin;
select * from test where id>4 and id<10 for update;

id>4 and id<10这个范围包括了作为记录的7,此时触发临键锁,锁住的区间为(4,10],记住:当区间右边临界值为记录时,是闭区间,反之,开区间。其他事务就不能再对在(4,10]区间内的记录进行任何操作包括查看。重点:触发临键锁的条件:上锁sql语句的操作范围必须包括记录

总结:当sql语句的上锁范围小于数据库的划分间隙,则上锁范围必扩大为数据库所划分的上锁范围。

自增锁:

并发:
在这里插入图片描述
在这里插入图片描述
有三个级别,分别是0(表级,一个事务结束另一个才开始,有序,并发率低),1,2,官方默认1,2效率最高但是会出现复制。

MVCC深层理解:

期望:在同一个事务中保证多次查询的结果一样。
思想:每个事务系统版本号不变(执行第一条sql语句时加1后),将同一条记录的数据行版本号与事务系统版本号对比,怎么个对比法?由于不确定其他事务会不会对该记录进行除查看以外的其他操作,这样就可以看成该事务对同一条记录做了修改,上一个事务只要对同一条记录做了修改,也就是使记录变得跟以前不一样了,该记录的数据行版本号就会加1,由于在同一个事务中系统版本号不变,我们就以此为参考,找出同一条记录数据行版本号小于系统版本号的那个版本,也就保证了同一个事务中保证多次查询的结果一样。
大思想下的就实现细节

  • 每个事务系统版本号为什么在执行第一条sql语句时就会加1呢?因为你不确定该事务是否会进行对同一条记录做了修改,而做了修改的记录版本号会加1,而在同一事务中我们期望查询到的是自己修改后的版本,因此根据InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),每个事务系统版本号在执行第一条sql语句时就会加1就成为了必然。
  • 更新=删除+插入,删除操作将系统版本号作为该记录的删除标记,同时也将系统版本号作为新插入的记录的创建版本号(数据行版本号)。
  • 删除操作在每个事务开启的时候首先是系统版本号在上一个事务系统版本号基础上加1再将系统版本号作为该记录的删除标记。
  • 如果读到该条记录有删除标记的版本,就会读空,即什么也没读到。
    设计:每个事务在开启执行第一条sql语句时系统版本号在上一个事务的基础上+1,注意,同一个事务系统版本号只增加一次,查询语句不会改变数据行版本号,其他语句对数据行版本号的影响如2,3所示。
    MVCC实现可重复读惊天真相

zookeeper分布式锁:

  • 带序号:
    create /aaa
    aaa_00000…1
    create /aaa
    aaa_00000…2
  • 不带序号:
    create /aaa
    aaa
    create /aaa
    error报错
    在这里插入图片描述

在这里插入图片描述

标签:语句,事务,记录,版本号,Mysql,zookeeper,MVCC,test,id
来源: https://blog.csdn.net/m0_48333563/article/details/113753927

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有