我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【Gap锁】Mysql的Gap锁在中文列下间隙怎样确定?

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【Gap锁】Mysql的Gap锁在中文列下间隙怎样确定?

通过本文记录一次Gaplock的验证,网上大多gaplock是基于明确是数字型列来测试gaplock的,这里不再重复,随便贴个相关地址:https://www.cnblogs.com/crazylqy/p/7821481.html 

我的疑问是如果所在的列是非数字型的列,比如说是列值是中文的话,mysql是如何确定间隙的,下面开始进行验证。

 

查看mysql间隙锁是否开启,默认"OFF"表示开启  => show variables like "innodb_locks_unsafe_for_binlog";

 

准备一张表,3个字段分别是 => id(主键索引),name,key(普通索引)    ,    然后随便搞几条数据。

CREATE TABLE `test_gaplock` (
`id` varchar(32) CHARACTER SET utf8 NOT NULL,
`name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
`key` varchar(32) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

 

 

 

通过mysql的客户端工具开3个会话窗口

  1)目标1:验证按照name列(无索引)更新的gaplock问题。

    结论:name列无索引作为where条件更新会锁表(全表GAP锁,这里因为我对锁的理解还不透彻,所以才多做了这次试验

  2)  目标2:验证按照id列(主键索引)更新的gaplock问题。

    结论:这里我也懒得验证了,mysql的next-key lock(gap lock+record lock)机制就是,对于任何的当前读(如果对快照度和当前读有疑惑,请自行百度)操作,产不产生间隙锁取决于该列的索引是否能唯一确定一行数据(主键索引或者唯一索引),如果是,会升级成记录锁,也即普通行锁

  3)目标3:验证按照key列(普通索引),理论上普通索引会产生gap锁,key列现在存的是中文,他的间隙是怎么确定的,是按照自然排序(mysql默认按照主键排序),还是where的筛选列排序来确定间 隙?这里要直接引入一个结论就是,插入间隙区间是左闭合,又开启的区间即这种 [ ) 。意思就是比如你的列值是2,4,6,然后你更新的条件是4,那么你锁住的间隙是[2,6) ,操作2会被锁住,操作6是不受影响的。大家可自行验证,欢迎纠正。

         

 

 

先插入这么一条数据 => insert into test_gablock values("6","a4","李"); 然后查看两种排序的展示情况

(下面的图表示自然排序)                                                                 

   

(下面的图表示按照key列排序)                   

 

 

删除掉这行新增的记录这里有个猜想就是要么是按照主键来排序,然后确定间隙,要么是按照筛选列来排序,确定间隙,根据上面的排序,更新name为a3,key为"强"的记录。

情况1:若是按照自然排序,那么间隙应该是[广,马)

情况2:若是按照key列排序,那么间隙应该是[广,陈)

 然后现在再插入这条记录 => insert into test_gablock values("6","a4","李"); 

按照上面那个直接引入的结论,如果是情况1,那么是不会阻塞的,如果是情况2,那么是会阻塞的。

--------------------会话1(开启事务后不提交锁住记录)---------------------

set autocommit=0; 
begin;
update test_gaplock t1 set t1.`name` = a3" where t1.key = "强";

 --------------------会话2(插入后不提交直接回滚,只是不想把验证数据弄坏而已)---------------------

set autocommit=0;  
begin;
insert into test_gaplock values("6","a4","李");
rollback;

 --------------------会话3(只是用来方便查看实时数据)---------------------

select * from test_gaplock  t1 order by t1.name

 

结论:经过验证执行 => insert into test_gablock values("6","a4","李"); 命令会被阻塞,所以情况2是正确的

 

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【Gap锁】Mysql的Gap锁在中文列下间隙怎样确定?

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

【Gap锁】Mysql的Gap锁在中文列下间隙怎样确定?

通过本文记录一次Gaplock的验证,网上大多gaplock是基于明确是数字型列来测试gaplock的,这里不再重复,随便贴个相关地址:https://www.cnblogs.com/crazylqy/p/7821481.html 我的疑问是如果所在的列是非数
【Gap锁】Mysql的Gap锁在中文列下间隙怎样确定?
2020-04-01

编程热搜

目录