MySQL InnoDB底层的锁实现算法分为三种 :

记录锁,间隙锁,临键锁。

之前在验证MySQL的临键锁的时候使用docker安装的最新版本的MySQL镜像,发现其临键锁在最新的MySQL的表现和低版本(5.7)不一致,后面又自己验证了一下,并整理成博客

本文使用的高低版本MySQL分别为:
高版本MySQL: 8.0.18
低版本MySQL : 5.7.10

CREATE TABLE `t2` (`id` int(11) NOT NULL,`name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `t2` (`id`, `name`) VALUES (1, '1');
INSERT INTO `t2` (`id`, `name`) VALUES (5, '5');
INSERT INTO `t2` (`id`, `name`) VALUES (9, '9');
INSERT INTO `t2` (`id`, `name`) VALUES (14, '14');

高版本下执行

使用临键锁:

在事务2里试验一下插入和查询操作

mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into t2 values(8,'8');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values (13,'13');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values (15,'15');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t2 values (9,'9');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (14,'14');
ERROR 1062 (23000): Duplicate entry '14' for key 'PRIMARY'mysql> select * from t2 where id = 13 for update;
Empty set (0.00 sec)mysql> select * from t2 where id = 14 for update;
+----+------+
| id | name |
+----+------+
| 14 | 14   |
+----+------+
1 row in set (0.00 sec)
mysql> select * from t2 where id = 9 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
如果命中的刚好的查询范围内最大的记录
#事务1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t2 where id > 6 and id < = 9 for update;
+----+------+
| id | name |
+----+------+
|  9 | 9    |
+----+------+
1 row in set (0.00 sec)#事务2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into t2 values(8,'8');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (10,'10');
Query OK, 1 row affected (0.00 sec)mysql> select * from t2 where id = 14 for update;
+----+------+
| id | name |
+----+------+
| 14 | 14   |
+----+------+
1 row in set (0.00 sec)

通过SQL试验结论:
1)select * from t2 where id > 6 and id < 10 for update;// 锁住范围是(5,9],(9,14)
在(5,9],(9,14)区间对于插入是阻塞的,但是对于查询操作,只有查询事务1中SQL命中的记录id=9才会阻塞,查询其他记录均不会阻塞

2)select * from t2 where id > 6 and id <= 9 for update;// 锁住范围是(5,9]
在(5,9]区间对于插入是阻塞的,但是对于查询操作,只有查询事务1中SQL命中的记录id=9才会阻塞,查询其他记录均不会阻塞

在低版下执行

#事务1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t2 where id > 6 and id < 10 for update;
+----+------+
| id | name |
+----+------+
|  9 | 9    |
+----+------+
1 row in set (0.00 sec)
如果在事务1执行select * from t2 where id > 6 and id < = 9 for update;
其锁定范围和上面的SQL是一致的#事务2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into t2 values(8,'8');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (9,'9');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (13,'13');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (14,'14');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> insert into t2 values (15,'15');
Query OK, 1 row affected (0.01 sec)mysql> select * from t2 where id = 13 for update;
Empty set (0.00 sec)mysql> select * from t2 where id = 14 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> select * from t2 where id = 9 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

结论:在(5,9],(9,14]区间对于插入是阻塞的,但是对于查询操作,只有在查询区间(5,9],(9,14]中存在的记录才会阻塞,查询其他记录均不会阻塞

比较高低版本下的SQL执行结果区别,发现其区别主要是在对id=14的操作上

低版本:

mysql> insert into t2 values (14,'14');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> select * from t2 where id = 14 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

高版本:

mysql> insert into t2 values (14,'14');
ERROR 1062 (23000): Duplicate entry '14' for key 'PRIMARY'
mysql> select * from t2 where id = 14 for update;
+----+------+
| id | name |
+----+------+
| 14 | 14   |
+----+------+
1 row in set (0.00 sec)

所以MySQL在8.0对临键锁算法进行了优化
1)对于在SQL执行时没有命中的记录,在同个事务中
执行相同SQL的时候也不会查询到,对于插入和查询没必要阻塞
2)对于临键锁的锁定范围做了优化,如果查询的时候SQL可能查询到的最大值刚好是Next-Key的右闭区间的值,那么也就不需要锁住下一个临键区间

简单来说MySQL 8.0中临键锁的锁定范围是命中的Record和包含当前查询范围的最小Gap的并集,这样其实跟我们理解的需要锁定的范围更加一致

MySQL(七)关于MySQL不同版本下临键锁锁定范围不同相关推荐

  1. Linux下yum安装MySQL yum安装MySQL指定版本

    yum 安装MySQL 1. 检查安装情况 查看有没有安装过: yum list installed MySQL* (有存在要卸载yum remove MySQL*) rpm -qa | grep m ...

  2. 32linux下安装mysql5.7_【Linux】【MySQL】安装MySQL,版本5.7

    本文环境:CentOS7,安装包放在/home/mysql 或者直接在Linux上wget https://downloads.mysql.com/archives/get/p/23/file/mys ...

  3. 无法找到来自源 mysql 的事件 id 100 的描述_更新到1709版本下会出现:无法找到来自源 nvlddmkm 的事件 ID 14 的描述 的问题...

    更新到1709版本下会出现:无法找到来自源 nvlddmkm 的事件 ID 14 的描述 的问题 这个问题出现在新的windows版本1709(OS内部版本16299.125)中,在更新时如果我连接两 ...

  4. Hadoop集群搭建(七:MySQL的安装配置)

    实验 目的 要求 目的: 1.掌握MySQL在集群平台中的安装 要求: 完成MySQL的集群版的安装: MySQL集群的相关服务进程能够正常启动: MySQL集群的SQL服务能够作为系统服务开机自动启 ...

  5. 虚拟机开启mysql密码报错_Linux虚拟机下mysql 5.7安装配置方法图文教程

    一. 下载mysql5.7 Linux下载: 输入命令:wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5 ...

  6. centos mysql 5.5 art_Linux CentOS6.5下编译安装MySQL 5.5.51''''

    一.编译安装MySQL前的准备工作 安装编译源码所需的工具和库 yum install gcc gcc-c++ ncurses-devel perl 安装cmake,从http://www.cmake ...

  7. linux 打版本包,mysql官网下载linux版本安装包

    今天在Linux上部署项目,用到了Mysql,因此想要下载适用于Linux的安装版本,在Mysql官网找了半天,终于找到怎样下载了,这里写出来,以后大家找的时候就好找了. 第一步:在百度输入Mysql ...

  8. MySQL数据库,从入门到精通:第七篇——MySQL单行函数应用

    MySQL数据库,从入门到精通:第七篇--MySQL单行函数应用 第七篇_单行函数 1. 函数的理解 1.1 什么是函数 1.2 不同DBMS函数的差异 2. 数值函数 2.1 基本函数 2.3 三角 ...

  9. .tar.gz mysql 安装_mysql tar.gz 版本 linux系统的安装-Go语言中文社区

    mysql下载地址: https://dev.mysql.com/downloads/mysql/ 1.  上传下载的tar.gz文件发送到linux 上传的路径: /usr/local/mysql/ ...

最新文章

  1. linux 安装java10
  2. 2016年 1月15号 cocoapods的导入
  3. 慕课网上的星级评分--学习视频后模仿实现
  4. 吃是为了肉体,喝是为了灵魂
  5. Linq = MyMetal = SqlMetal Include 自定义(Linq to sql )生成
  6. android actionbar tab,ActionBar+Fragment实现Tab
  7. 台式计算机 行业标准,GBT 9813.3-2017 计算机通用规范 第3部分:服务器国家标准...
  8. R语言之dpqr概率函数
  9. ICA算法的数学原理
  10. 独秀日记:童道自然大夫山徒步
  11. uva 10099 The Tourist Guide nyoj 1019 亲戚来了【单个路线最大流【最短路算法】】
  12. VS将复制过来的文件或文件夹显示到解决方案管理
  13. Python 二次指数平滑法 预测
  14. DAEFRHDSGYEVHHQKLVFFAEDV|138648-77-8
  15. 有感而发:总结很重要
  16. JAVA基础(一)——什么是java
  17. TreeView和数据库
  18. dB dBm dBFs 理解
  19. s7300的db块详细说明_西门子db数据块详解
  20. P2327 [SCOI2005]扫雷 - 模拟

热门文章

  1. java 仿百度文库源码_java开发_模仿百度文库_SWFTools_源码下载
  2. Spring AbstractBeanFactory
  3. Shell循环与结构化命令
  4. brother标签打印软件_标签打印软件如何设计食品留样标签模板
  5. 电脑word在哪_怎么将图片转换成Word?学会这3种方法,轻松将图片转文字!
  6. data中的数据如何在innerhtml中调用_Vuex中调用state数据
  7. UCloud想吃科创板的“第一个螃蟹”
  8. 问题:linux系统经常出现断网的情况,重启之后系统恢复正常
  9. tomcat配置文件详解
  10. tableview的reloadData 产生的问题