mysql8 Record Locks ,Gap Locks, Next-Key Locks 实验1

mysql8 Record Locks ,Gap Locks, Next-Key Locks 实验3

上文讨论了 RR 隔离级别 主键索引的加锁情况,
本文接着讨论 RR 隔离级别下 二级唯一索引和普通二级索引 以及无索引时的加锁情况。

4.3 二级唯一索引等值查询

这次我们对 f1 字段操作,这是一个二级 唯一索引字段

4.3.1 锁定存在的值

-- 查询存在的值 11
START TRANSACTION;
SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f1=11  FOR UPDATE ;
-- 当前线程THREAD_ID=44
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 11 | 11 | 11 | 11 |
+-----------+----+----+----+----+
1 row in set (0.0 sec)

查询锁的信息,发现有3个锁,如下图所示:

【行号1】 是一个表级的意向锁

【行号2】 是一个加在 二级唯一索引 ui_f1上的 record 锁,锁类型为 X(排他),REC_NO__GAP 说明没有对间隙加锁

值得注意的是 LOCK_DATA为【11,11】 ,我们知道二级索引的record 组成为(key,主键),所以第一个11 是二级索引字段f1 的值,而第二个11 是主键的值

【行号3】 是一个主键索引上的 排他record 锁

4.3.2 锁定不存在的值

-- 查询存在的值 12
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f1=12  FOR UPDATE;
Empty set (0.00 sec)

查询加锁情况:

【行2】 对ui_f1 在数据(13,13)上添加了 X,GAP 锁,这其实就是一个 record lock和gap lock 的组合

这是个 next key lock,锁定的范围应该是 (11,13]

我们再开启一个连接验证一下锁定的范围:

-- 插入9 ok
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (9,9,9,9);
Query OK, 1 row affected (0.00 sec)
-- 插入12 阻塞
INSERT INTO locktest (id,f1,f2,f3) VALUES (12,12,12,12);
-- 插入 14 ok
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (14,14,14,14);
Query OK, 1 row affected (0.00 sec)

4.4 二级唯一索引范围查询

验证完唯一索引的等值查询加锁情况,我们开始验证范围查询

4.4.1 单范围查询

START TRANSACTION;
mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f1>11  FOR UPDATE;
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 13 | 13 | 13 | 13 |
|        44 | 20 | 20 | 20 | 20 |
+-----------+----+----+----+----+
2 rows in set (0.00 sec)

加锁信息如下:

4.4.2 双范围查询

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f1>11 AND t.f1<20  FOR UPDATE;
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 13 | 13 | 13 | 13 |
+-----------+----+----+----+----+
1 row in set (0.00 sec)

加锁信息如下图:

4.4.3 不存在的双范围查询

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> -- 记录 12 和21 都不存在
mysql> SELECT * FROM locktest t WHERE t.f1>=12 AND t.f1<=21 FOR UPDATE;
+----+----+----+----+
| id | f1 | f2 | f3 |
+----+----+----+----+
| 13 | 13 | 13 | 13 |
| 20 | 20 | 20 | 20 |
+----+----+----+----+
2 rows in set (0.00 sec)

加锁信息如下:

4.5 非唯一索引等值查询

这次我们对 f2 字段操作,这个一个二级非唯一索引字段

4.5.1 锁定存在的值

-- 查询存在的值 11
START TRANSACTION;SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f2=11  FOR UPDATE ;
-- 当前线程THREAD_ID=44
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 11 | 11 | 11 | 11 |
+-----------+----+----+----+----+
1 row in set (0.0 sec)

查询锁的信息,发现有4个锁,如下图所示:

【行号1】 是一个表级的意向锁

【行号2】 是一个加在 二级索引 i_f2 上的 record 锁,锁类型为 X(排他), 值得注意的是 LOCK_DATA为【11,11】 ,我们知道二级索引的record 组成为(key,主键),所以第一个11 是二级索引字段f1 的值,而第二个11 是主键的值

【行号3】 是一个主键索引上的 排他record 锁

【行号4】 是一个 next key lock,因为 这是一个组合锁(X,GAP),锁定的数据为(13,13),也因为 13 是我们查询条件11 的下一个key

综上来看,加锁的范围是 (11,13]

也就是说对于二级非唯一索引的等值查询也会产生 next key lock

我们用以下sql 验证以下加锁范围

-- 启动一个新窗口执行以下操作-- 插入 <11 的数据
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (9,9,9,9);
Query OK, 1 row affected (0.00 sec)-- 插入 =11 的数据 ,阻塞
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (111,111,11,11);

注意 【行2】 的 X,GAP,INSERT_INTENTION 无法获取锁 正在WATING

-- 插入>11 的数据,阻塞START TRANSACTION;
INSERT INTO locktest (id,f1,f2,f3) VALUES (12,12,12,12);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ozkmj4KQ-1651735032664)(./assets/20220505141220-image.png)]

-- 插入 =13 的数据,不阻塞,这说明  在13 上的X,GAP 锁并不阻止 13 的插入mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (1313,1313,13,13);
Query OK, 1 row affected (0.00 sec)-- 插入>13 的数据,不阻塞
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (14,14,14,14);
Query OK, 1 row affected (0.00 sec)

4.5.2 锁定不存在的值

-- 查询存在的值 12mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f2=12  FOR UPDATE;
Empty set (0.00 sec)

查询加锁情况:

【行2】 对 i_f2 在数据(13,13)上添加了 X,GAP 锁,这其实就是一个 record lock和gap lock 的组合

这是个 next key lock,锁定的范围应该是 (11,13]

4.6 非唯一索引范围查询

验证完 非唯一索引的等值查询加锁情况,我们开始验证范围查询

4.6.1 单范围查询

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f2>11  FOR UPDATE;
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 13 | 13 | 13 | 13 |
|        44 | 20 | 20 | 20 | 20 |
+-----------+----+----+----+----+
2 rows in set (0.00 sec)

加锁信息如下:

4.6.2 双范围查询

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f2>11 AND t.f2<20  FOR UPDATE;
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 13 | 13 | 13 | 13 |
+-----------+----+----+----+----+
1 row in set (0.00 sec)

加锁信息如下图:

4.6.3 不存在的双范围查询

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> -- 记录 12 和21 都不存在
mysql> SELECT * FROM locktest t WHERE t.f2>=12 AND t.f2<=21 FOR UPDATE;
+----+----+----+----+
| id | f1 | f2 | f3 |
+----+----+----+----+
| 13 | 13 | 13 | 13 |
| 20 | 20 | 20 | 20 |
+----+----+----+----+
2 rows in set (0.00 sec)

加锁信息如下:

4.7 无索引等值查询

这次我们对 f3 字段操作,这个一个 无索引字段

4.7.1 锁定存在的值

-- 查询存在的值 11
START TRANSACTION;SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f3=11  FOR UPDATE ;
-- 当前线程THREAD_ID=44
+-----------+----+----+----+----+
| THREAD_ID | id | f1 | f2 | f3 |
+-----------+----+----+----+----+
|        44 | 11 | 11 | 11 | 11 |
+-----------+----+----+----+----+
1 row in set (0.0 sec)

查询锁的信息,发现数据库中的数据都添加了锁,如下图所示:

我们用以下sql 验证以下加锁范围

-- 启动一个新窗口执行以下操作-- 插入 <11 的数据  阻塞 无法插入
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (9,9,9,9);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLTiJz19-1651735032673)(./assets/20220505150509-image.png)]

注意 【行2】 的 X,GAP,INSERT_INTENTION 无法获取锁 正在WATING

-- 插入 =11 的数据 ,阻塞
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (111,111,11,11);

-- 插入>11 的数据,阻塞START TRANSACTION;
INSERT INTO locktest (id,f1,f2,f3) VALUES (12,12,12,12);

-- 插入 =13 的数据,阻塞mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO locktest (id,f1,f2,f3) VALUES (1313,1313,13,13);
Query OK, 1 row affected (0.00 sec)

4.7.2 锁定不存在的值

-- 查询存在的值 12mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PS_CURRENT_THREAD_ID() THREAD_ID ,t.* FROM locktest t WHERE t.f3=12  FOR UPDATE;
Empty set (0.00 sec)

查询加锁情况:

4.8 无索引范围查询

这里就不一一验证了,因为在无索引的情况下都是全表锁定。这也说明了加索引的重要性

mysql8 Record Locks ,Gap Locks, Next-Key Locks实验2 唯一索引和非唯一索引,无索引情况相关推荐

  1. Mysql 死锁过程及案例详解之记录锁与间隔锁Record Lock Gap Lock

    记录锁Record Lock与间隔锁GAP Lock 记录锁Record Lock 记录锁Record Locks又称为行锁,它同时包含索引和间隔锁.记录锁可以是共享锁也可能是排他锁.可以通过perf ...

  2. 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。...

    题目描述 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出. 输入描述: 先输入键值对的个数 然后输入成对的index和value ...

  3. STM32F103标准库开发:KEY按键实验

    KEY按键实验程序源码链接 STM32F103标准库开发-目录 一.硬件电路分析 按键的具体硬件电路原理图如下: 大致就这两种: KEY1 带上拉电路的,按键按下,PB12接地,输入低电平. KEY2 ...

  4. 数据库键(key)、主键(primaryKey)、索引(index)、唯一索引(uniqueIndex)区别

    1.键:key,数据库的物理结构,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的).包括:primary key, unique key, foreign key(主键/唯一键 ...

  5. InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    MySQL InnoDB支持三种行锁定方式: l   行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. l   间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙 ...

  6. MySQL8高级优化,持续更新......

    索引 索引可以高效获取数据,避免对数据进行全盘扫描(查询速度很慢),索引就是一种数据结构(树) MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序).在数据之 ...

  7. MySQL InnoDB 锁介绍及不同 SQL 语句分别加什么样的锁

    作者:iceman1952(本文来自作者投稿) 本文中,我们详细介绍MySQL InnoDB存储引擎各种不同类型的锁,以及不同SQL语句分别会加什么样的锁. 阅读提示 1. 本文所参考的MySQL文档 ...

  8. delete select语句_MySQL InnoDB锁介绍及不同SQL语句分别加什么样的锁

    作者:iceman1952 链接:https://blog.csdn.net/iceman1952/article/details/85504278 本文中,我们详细介绍MySQL InnoDB存储引 ...

  9. MySQL学习笔记 04、MySQL进阶(索引、事务、锁)

    文章目录 前言 一.MySQL的目录结构 1.1.认识目录文件 1.2.配置文件设置 windows平台下设置 linux环境下设置 二.MySQL的系统架构 2.1.MySQL系统的逻辑架构: 2. ...

最新文章

  1. 大战三回合:XGBoost、LightGBM和Catboost一决高低 | 程序员硬核算法评测
  2. 【Android NDK 开发】Android.mk 配置静态库 ( Android Studio 配置静态库 | 配置动态库与静态库区别 | 动态库与静态库打包对比 )
  3. 121. Leetcode 5. 最长回文子串 (动态规划-子序列问题)
  4. k8s中graphite_在Graphite中存储Hystrix的几个月历史指标
  5. win2008r2 AD用户账户的批量导入方法
  6. 映客都是互刷礼物吗_仿映客刷礼物效果 代码优化
  7. 指令由电子计算机,电子计算机主要是以
  8. SpiderData 2019年2月4日 DApp数据排行榜
  9. Python 实现单例模式的一些思考
  10. SQLyog备份数据库
  11. java recv failed,java.sql.SQLException: I/O Error: Software caused connection abort: recv failed
  12. qt实现简易的画图,鼠标事件
  13. notebook使用技巧
  14. Cortex-M3 (NXP LPC1788)之IIC控制器
  15. 如何在 Mac 操作系统上安装打印驱动程序【富士施乐/胶片】
  16. 关于cocos2d引擎写的手游加速
  17. Python爬虫-爬取豆瓣TOP250
  18. php去除emoji,php去除emoji表情
  19. eve模拟器上虚拟服务器,没有真机怎么做实验?EVE模拟器了解一下
  20. docker删除无用容器、镜像

热门文章

  1. 替换空格 ——《剑指offer》
  2. JAVA自定义信件消息模板内容
  3. 锐龙r3 4100核显 r3 4100参数 r3 4100评测
  4. 龚鹏:我是怎么从程序员成为全栈GEEK的
  5. 事半功倍追求卓越:人生找位的“TONS法则”
  6. RNA-seq:最长转录本提取
  7. 数据结构之霍夫曼压缩,更易理解文件压缩过程
  8. ProxySQL 配置详解及读写分离(+GTID)等功能说明2 (完整篇)
  9. android模拟器游戏大全,安卓模拟器游戏大全_小鸡模拟器
  10. python如何读取二进制文件为图片_Python二进制文件读取并转换