欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答

问题

问题原文是这样的:

假如在MySQL事务里,给某个表的一行加了 共享锁,理论上这个表本身会自动加上意向共享锁,那么能不能用 sql 查出这个表加了意向锁?

回答

答案是肯定的,当然可以执行SQL查询表上的IS锁加锁状态。

先声明,我们本次讨论的是MySQL里的InnoDB引擎表,下面讨论的内容都是基于这个前提。

在揭晓答案之前,多介绍点InnoDB引擎锁相关的一些知识吧。主要有以下几点

  • InnoDB引擎表既支持表级锁,也支持行级锁。

  • 加表级锁的方法和MyISAM表是一样的,执行 LOCK TABLE READ/WRITE 即可。

  • InnoDB表的行锁是加在索引上的,因此如果没有合适的索引,是会导致表里所有记录都被加上行锁,其后果等同于表级锁,但产生的影响比表级锁可就大多了。因为锁对象数量大了很多,消耗的内存也多很多。

  • 加上行锁时,同时还需要对表加上相应的意向锁。例如,想要对一行数据加上共享锁(S锁),则相应的要对表加上意向共享锁(IS锁);同样地,想要对一行数据加上排他锁(X锁),则相应的要对表加上意向排他锁(IX锁)。

  • 意向锁是加在聚集索引的根节点上的,因此无论锁定多少行,只需要加一个意向锁。

  • 下面是几个锁之间的兼容矩阵

好了,接下来我们来看下怎么查看表级IS锁。其实很简单,只需要查看 PFS.data_locks 表就可以了。另一个表 PFS.metadata_locks 表可以查看MDL锁的详情。

查询结果例如下面这样:

[root@yejr.run] [(none)]>select * from performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140701134495048:1350:140701396637648
ENGINE_TRANSACTION_ID: 422176111205704
THREAD_ID: 87
EVENT_ID: 95
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140701396637648
LOCK_TYPE: TABLE
LOCK_MODE: IS
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140701134495048:267:4:9:140701409130528
ENGINE_TRANSACTION_ID: 422176111205704
THREAD_ID: 87
EVENT_ID: 95
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 140701409130528
LOCK_TYPE: RECORD
LOCK_MODE: S,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 1

此时我们能看到t1表上共有两个锁,一个是表级IS锁,另一个是c1=1上的共享锁。

同样地,我们也可以观察IX锁或其他锁。

- session1执行下面的SQL
[root@yejr.run] [yejr]>begin; update t1 set c4=rand()*1024 where c1=1; - session2查询PFS.data_locks
[root@yejr.run] [(none)]>select * from performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140701134495888:1350:140701396639728
ENGINE_TRANSACTION_ID: 104536
THREAD_ID: 89
EVENT_ID: 43
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140701396639728
LOCK_TYPE: TABLE
LOCK_MODE: IX <-- 这个就是IX锁了
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140701134495888:267:4:9:140701409135136
ENGINE_TRANSACTION_ID: 104536
THREAD_ID: 89
EVENT_ID: 43
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 140701409135136
LOCK_TYPE: RECORD
LOCK_MODE: X,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 1

进一步,我们简单看下MDL锁。加共享行锁:

- session1加一个共享行锁
[root@yejr.run] [yejr]>begin; select * from t1 where c1=1 for share; - session2查询表上有哪些MDL锁
[root@yejr.run] [(none)]>select * from performance_schema.metadata_locks\G
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
COLUMN_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140701215694512
LOCK_TYPE: SHARED_READ <- 共享读锁,可以同时加多个共享行锁
LOCK_DURATION: TRANSACTION
LOCK_STATUS: GRANTED
SOURCE: sql_parse.cc:5761
OWNER_THREAD_ID: 87
OWNER_EVENT_ID: 100

也看下加排他行锁:

- session1加一个排他行锁
[root@yejr.run] [yejr]>begin; update t1 set c4=rand()*1024 where c1=1; - session2查询表上有哪些MDL锁
[root@yejr.run] [(none)]>select * from performance_schema.metadata_locks\G
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: yejr
OBJECT_NAME: t1
COLUMN_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140701215694640
LOCK_TYPE: SHARED_WRITE <- 共享写锁,可以同时加多个排他行锁(不同数据行)
LOCK_DURATION: TRANSACTION
LOCK_STATUS: GRANTED
SOURCE: sql_parse.cc:5761
OWNER_THREAD_ID: 89
OWNER_EVENT_ID: 43

好了,方法已有,更多的情形可以自己去玩了 :)

测试环境

Server version: 8.0.23 MySQL Community Server - GPL

上述PFS查看行锁、MDL锁的功能应该是8.0以上就开始支持了。

Enjoy MySQL :)

文章推荐:

技术分享 | MGR最佳实践(MGR Best Practice)

https://mp.weixin.qq.com/s/66u5K7a9u8GcE2KPn4kCaA

技术分享 | 万里数据库MGR Bug修复之路

https://mp.weixin.qq.com/s/IavpeP93haOKVBt7eO8luQ

Macos系统编译percona及部分函数在Macos系统上运算差异

https://mp.weixin.qq.com/s/jAbwicbRc1nQ0f2cIa_2nQ

技术分享 | 利用systemd管理MySQL单机多实例

https://mp.weixin.qq.com/s/iJjXwd0z1a6isUJtuAAHtQ

产品 | GreatSQL,打造更好的MGR生态

https://mp.weixin.qq.com/s/ByAjPOwHIwEPFtwC5jA28Q

产品 | GreatSQL MGR优化参考

https://mp.weixin.qq.com/s/5mL_ERRIjpdOuONian8_Ow

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee:

https://gitee.com/GreatSQL/GreatSQL

GitHub:

https://github.com/GreatSQL/GreatSQL

微信&QQ群:

可扫码添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群,亦可直接扫码加入GreatSQL/MGR交流QQ群。

本文由博客一文多发平台 OpenWrite 发布!

万答#1,MySQL中如何查询某个表上的IS(意向共享)锁的更多相关文章

  1. 【面经】面试官:如何以最高的效率从MySQL中随机查询一条记录?

    写在前面 MySQL数据库在互联网行业使用的比较多,有些小伙伴可能会认为MySQL数据库比较小,存储不了很多的数据.其实,这些小伙伴是真的不了解MySQL.MySQL的小不是说使用MySQL存储的数据 ...

  2. MySQL中基本的多表连接查询教程

    一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如: SELECT * FROM table1 CROSS JOIN ...

  3. mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

  4. 【原创】7. MYSQL++中的查询结果获取(各种Result类型)

    在本节中,我将首先介绍MYSQL++中的查询的几个简单例子用法,然后看一下mysqlpp::Query中的几个与查询相关的方法原型(重点关注返回值),最后对几个关键类型进行解释. 1. MYSQL++ ...

  5. mysql中如何查询最近24小时、top n查询

    MySQL中如何查询最近24小时. where visittime >= NOW() - interval 1 hour; 昨天. where visittime between CURDATE ...

  6. Mysql中分页查询两个方法比较

    mysql中分页查询有两种方式, 一种是使用COUNT(*)的方式,具体代码如下 1 2 3 SELECT COUNT(*) FROM foo WHERE b = 1;   SELECT a FROM ...

  7. mysql中in查询中排序

    mysql中in查询条件的时候,很多时候排序是不规则的,如何按照in里面的条件进行排序呢? mysql中给出了办法,在in后面加order by field,order by field的首个条件是按 ...

  8. mysql 中合并查询结果union用法 or、in与union all 的查询效率

    mysql 中合并查询结果union用法 or.in与union all 的查询效率 (2016-05-09 11:18:23) 转载▼ 标签: mysql union or in 分类: mysql ...

  9. 下面介绍mysql中模糊查询的四种用法:

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

随机推荐

  1. unity---给物体施加普通力和位置力

    普通力 让物体沿着某一方向获得一个力,vector3方向 addForceObj.GetComponent<Rigidbody>().AddForce(1000,0,1000); 位置力 ...

  2. iview 酸爽debug: subMenu默认选中无效的解决方法

    一. 在iview中写一个submenu <Col span="3" type="flex" v-if="showCids"> ...

  3. 0-1knapsack

    Python 实现0-1背包问题(回溯法) 题目 解题思路 回溯法:为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来处死那些实际上不可能产生所需 ...

  4. 小样本利器1.半监督一致性正则 Temporal Ensemble & Mean Teacher代码实现

    这个系列我们用现实中经常碰到的小样本问题来串联半监督,文本对抗,文本增强等模型优化方案.小样本的核心在于如何在有限的标注样本上,最大化模型的泛化能力,让模型对unseen的样本拥有很好的预测效果.之前 ...

  5. 前端4BOM与DOM

    内容概要 BOM操作(了解) DOM操作 DOM操作标签 获取值操作 属性操作 事件 -事件案例 内容详情 BOM操作(了解)

  6. 定制.NET 6.0的依赖注入

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 在本章中,我们将学习ASP.NET Core的依赖项注入(DI)以及如何自定义它. ...

  7. ExtJS 同行表单域对齐有误处理办法

    更新记录 2022年5月29日 第一次编辑.使用的ExtJS版本:ExtJS 7.4 问题 原本都是显示正常的表单域,比如这些文本框.选择框都是正常. 在用户进行操作,然后显示验证提示后,明显出现了问 ...

  8. BUUCTF-webshell后门

    webshell后门 老方法,D盾直接查杀. flag{ba8e6c6f35a53933b871480bb9a9545c}

  9. 命令行工具tabby--gi t仓库Token的使用

    命令行工具tabby--git仓库Token的使用 欢迎关注H寻梦人公众号 前言 再见 Xshell !这款开源的终端工具逼格更高! 终端神器--Tabby Terminal electerm is ...

  10. Leetcode--Last Stone Weight II

    Last Stone Weight II 欢迎关注H寻梦人公众号 You are given an array of integers stones where stones[i] is the we ...