日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

發布時間:2024/4/11 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL(七)关于MySQL不同版本下临键锁锁定范围不同 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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不同版本下临键锁锁定范围不同的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。