了解下Mysql的間隙鎖及產生的原因


什么是間隙鎖
當我們用范圍條件而不是相等條件檢索數據,並請求共享或排他鎖時,InnoDB會給符合條件的已有數據記錄的索引項加鎖;對於鍵值在條件范圍內但不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制就是所謂的間隙鎖(NEXT-KEY)鎖。
危害
因為Query執行過程中通過范圍查找的話,他會鎖定整個范圍內所有的索引鍵值,即使這個鍵值並不存在。
間隙鎖有一個比較致命的弱點,就是當鎖定一個范圍鍵值之后,即使某些不存在的鍵值也會被無辜的鎖定,而造成在鎖定的時候無法插入鎖定值范圍內的任何數據,在某些場景下這可能會針對性造成很大的危害。

准備

DROP TABLE IF EXISTS `innodb_lock`; CREATE TABLE `innodb_lock` ( `a` int(10) NOT NULL, `b` varchar(255) NOT NULL DEFAULT '', KEY `index_a` (`a`), KEY `index_b` (`b`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- ----------------------------
-- Records of innodb_lock -- ---------------------------- INSERT INTO `innodb_lock` VALUES ('1', 'b2'); INSERT INTO `innodb_lock` VALUES ('3', '3'); INSERT INTO `innodb_lock` VALUES ('4', '4000'); INSERT INTO `innodb_lock` VALUES ('5', '5000'); INSERT INTO `innodb_lock` VALUES ('6', '6000'); INSERT INTO `innodb_lock` VALUES ('7', '7000'); INSERT INTO `innodb_lock` VALUES ('8', '8000'); INSERT INTO `innodb_lock` VALUES ('9', '9000'); INSERT INTO `innodb_lock` VALUES ('1', 'b1');
MySQL [test_db]> select * from innodb_lock; +---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 3    |
| 4 | 4000 |
| 5 | 5000 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9000 |
| 1 | b1   |
+---+------+

注意表中的數據,a是int型,假如表示id,包含1,3,4,5,6,6...當然缺少2,沒有連續下來。一般在公司里做雲計算大數據分析最好是連續的,有可能有的公司數據很珍貴,所謂的刪除其實是邏輯刪除,只是做了狀態更改。

操作(打開兩個Mysql終端,分別設置autocommit自動提交為0,也就是關閉自動提交功能,事務隔離級別處於可重復讀狀態)

在第一個終端執行update操作,執行成功

MySQL [test_db]> update innodb_lock set b = '1234' where a > 1 and a < 6; //也就是對1,3,4,5這四條數據做修改。注意這里沒有2

在第二個終端執行insert操作,發現被阻塞

MySQL [test_db]> insert into innodb_lock values (2,'2000');

反思:按說在InnoDB的行級鎖,兩個不同的終端操作不同的行數據,不會造成阻塞。可以看看這篇文章詳細了解下http://www.cnblogs.com/wt645631686/p/8323963.html。但是阻塞出現了。

接下來在第一個終端執行commit提交之后發現,第二個終端也執行成功了,然后第二個終端也commit提交。查詢表數據,觀察下數據的變化。

MySQL [test_db]> select * from innodb_lock; +---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 1234 |
| 4 | 1234 |
| 5 | 1234 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9000 |
| 1 | b1   |
| 2 | 2000 |
+---+------+

通過最開始的介紹和案例操作,也就是Mysql會寧可錯殺也不會放過,沒有無所謂,有就不放過,只要給定的范圍,統統鎖了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM