mysql8 Record Locks ,Gap Locks, Next-Key Locks实验2 唯一索引和非唯一索引,无索引情况
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 唯一索引和非唯一索引,无索引情况相关推荐
- Mysql 死锁过程及案例详解之记录锁与间隔锁Record Lock Gap Lock
记录锁Record Lock与间隔锁GAP Lock 记录锁Record Lock 记录锁Record Locks又称为行锁,它同时包含索引和间隔锁.记录锁可以是共享锁也可能是排他锁.可以通过perf ...
- 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。...
题目描述 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出. 输入描述: 先输入键值对的个数 然后输入成对的index和value ...
- STM32F103标准库开发:KEY按键实验
KEY按键实验程序源码链接 STM32F103标准库开发-目录 一.硬件电路分析 按键的具体硬件电路原理图如下: 大致就这两种: KEY1 带上拉电路的,按键按下,PB12接地,输入低电平. KEY2 ...
- 数据库键(key)、主键(primaryKey)、索引(index)、唯一索引(uniqueIndex)区别
1.键:key,数据库的物理结构,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的).包括:primary key, unique key, foreign key(主键/唯一键 ...
- InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
MySQL InnoDB支持三种行锁定方式: l 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. l 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙 ...
- MySQL8高级优化,持续更新......
索引 索引可以高效获取数据,避免对数据进行全盘扫描(查询速度很慢),索引就是一种数据结构(树) MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序).在数据之 ...
- MySQL InnoDB 锁介绍及不同 SQL 语句分别加什么样的锁
作者:iceman1952(本文来自作者投稿) 本文中,我们详细介绍MySQL InnoDB存储引擎各种不同类型的锁,以及不同SQL语句分别会加什么样的锁. 阅读提示 1. 本文所参考的MySQL文档 ...
- delete select语句_MySQL InnoDB锁介绍及不同SQL语句分别加什么样的锁
作者:iceman1952 链接:https://blog.csdn.net/iceman1952/article/details/85504278 本文中,我们详细介绍MySQL InnoDB存储引 ...
- MySQL学习笔记 04、MySQL进阶(索引、事务、锁)
文章目录 前言 一.MySQL的目录结构 1.1.认识目录文件 1.2.配置文件设置 windows平台下设置 linux环境下设置 二.MySQL的系统架构 2.1.MySQL系统的逻辑架构: 2. ...
最新文章
- 大战三回合:XGBoost、LightGBM和Catboost一决高低 | 程序员硬核算法评测
- 【Android NDK 开发】Android.mk 配置静态库 ( Android Studio 配置静态库 | 配置动态库与静态库区别 | 动态库与静态库打包对比 )
- 121. Leetcode 5. 最长回文子串 (动态规划-子序列问题)
- k8s中graphite_在Graphite中存储Hystrix的几个月历史指标
- win2008r2 AD用户账户的批量导入方法
- 映客都是互刷礼物吗_仿映客刷礼物效果 代码优化
- 指令由电子计算机,电子计算机主要是以
- SpiderData 2019年2月4日 DApp数据排行榜
- Python 实现单例模式的一些思考
- SQLyog备份数据库
- java recv failed,java.sql.SQLException: I/O Error: Software caused connection abort: recv failed
- qt实现简易的画图,鼠标事件
- notebook使用技巧
- Cortex-M3 (NXP LPC1788)之IIC控制器
- 如何在 Mac 操作系统上安装打印驱动程序【富士施乐/胶片】
- 关于cocos2d引擎写的手游加速
- Python爬虫-爬取豆瓣TOP250
- php去除emoji,php去除emoji表情
- eve模拟器上虚拟服务器,没有真机怎么做实验?EVE模拟器了解一下
- docker删除无用容器、镜像
热门文章
- 替换空格 ——《剑指offer》
- JAVA自定义信件消息模板内容
- 锐龙r3 4100核显 r3 4100参数 r3 4100评测
- 龚鹏:我是怎么从程序员成为全栈GEEK的
- 事半功倍追求卓越:人生找位的“TONS法则”
- RNA-seq:最长转录本提取
- 数据结构之霍夫曼压缩,更易理解文件压缩过程
- ProxySQL 配置详解及读写分离(+GTID)等功能说明2 (完整篇)
- android模拟器游戏大全,安卓模拟器游戏大全_小鸡模拟器
- python如何读取二进制文件为图片_Python二进制文件读取并转换