日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql数据库的各种锁_关于MySQL各类锁的总结

發布時間:2023/12/10 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql数据库的各种锁_关于MySQL各类锁的总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

想要用好 MySQL,索引與鎖是一個繞不開的話題。最近一直在維護以前的業務系統,線上頻繁報出數據庫死鎖的異常警告,為了排查以及規避死鎖的問題,因此對 MySQL 的鎖(Innodb引擎)做了一個比較深入學習,順便加深自己對 MySQL 的理解程度。個人感覺 MySQL 中的鎖還是非常的雜,官網對于鎖的介紹也是和盤托出,并沒有分門別類的羅列出來,下面分別從鎖的模式與算法來分析。

鎖的模式

MySQL 中有鎖的模式這個概念,在 Innodb 中鎖的模式有共享鎖(S鎖)、排它鎖(X鎖)兩大類。除了這兩大類,還有一個意向鎖的概念,意向鎖在鎖模式中有意向共享鎖(IS鎖)、意向排它鎖(IX鎖)兩類。

共享鎖(行級別)

共享鎖也叫讀鎖,對于同一個資源,大家都可以同時加上共享鎖,可以理解成非獨家的資源,大家都可以獲取。共享鎖與排它鎖互斥,在 MySQL 中可以使用“lock in share mode”語法顯式的加共享鎖。

1select * from test where id = 1 lock in share mode;

排它鎖(行級別)

排它鎖也叫寫鎖,排它鎖不僅與共享鎖互斥,排它鎖與排它鎖也互斥,在 MySQL 中可以使用“for update”語法顯示的加排它鎖。

1select * from test where id = 1 for update;

意向鎖(表級別)

InnoDB 存儲引擎支持多粒度鎖定,當數據庫對行記錄進行加鎖時,首先會在粗粒度的表級別加上意向鎖。意向鎖的主要目的是為了提升表鎖的加鎖效率,假設沒有意向鎖,數據庫在對表進行加鎖時,需要掃描表中所有的記錄,查看是否有行鎖與當前要加的表鎖沖突。意向鎖之間是沒有沖突的,意向鎖與普通的表鎖之間有沖突。

意向共享鎖

意向共享鎖無法通過語法顯式的操作,當加上行級別的共享鎖時,意向共享鎖就會存在,意向共享鎖與排它鎖(表級)沖突。

意向排它鎖

意向排它鎖與上面的意向共享鎖類似,它與共享鎖(表級)、排它鎖(表級)都沖突。

普通鎖(表級別)

表級別的鎖因為粒度更粗,所以在判斷是否有沖突時不僅要考慮表級別下的其它鎖,還要考慮表中的行鎖。

共享鎖

除了對行可以加共享鎖,也可以對表加共享鎖,通過“lock table read”語法來對表加共享鎖。表級別的共享鎖不僅與表級別的排它鎖沖突,而且與行級別的排它鎖沖突。

1lock table test read;

排它鎖

除了對行可以加排它鎖,也可以對表加排它鎖,通過“lock table write”語法來對表加共享鎖。表級別的排它鎖不僅與表級別的共享鎖、排它鎖沖突,而且與行級別的排它鎖也沖突。

1lock table test write;

鎖的算法

鎖的模式側重鎖的意圖,鎖的算法更加偏重鎖的范圍,例如下面列舉的這些鎖都是跟鎖住的范圍區間有關系。為了更好的演示鎖住的區間,下面給出測試的表結構以及數據方便論證。

表結構:

1

2

3

4

5

6

7

8CREATE TABLE `test_info` (

`id` int(11) NOT NULL,

`no` int(20) NOT NULL AUTO_INCREMENT,

`description` varchar(255) NOT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `idx_no` (`no`) USING BTREE,

KEY `idx_description` (`description`(191)) USING BTREE

);

數據:

1

2

3

4

5INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (1, 10, '100');

INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (2, 20, '200');

INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (5, 50, '500');

INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (10, 100, '1000');

INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (11, 110, '1000');

記錄鎖

記錄鎖作用在精確匹配的唯一索引上,它與間隙鎖最大的差別在于間隙鎖鎖住的是不存在的區間。

記錄鎖 SQL 示例:

主鍵索引加鎖

事物一:

1select * from test_info where id = 1 for update;

事物二:

1select * from test_info where id = 1 for update;

事物二阻塞。

唯一索引加鎖

事物一:

1select * from test_info where no = 10 for update;

事物二:

1select * from test_info where no = 10 for update;

事物二阻塞

普通索引加鎖

事物一:

1select * from test_info where description = 1000 for update;

事物二:

1select * from test_info where id = 10 for update;

事物二阻塞,結束事物二,執行事物三

事物三:

1select * from test_info where id = 11 for update;

事物三阻塞,結束事物三,執行事物四

事物四:

1select * from test_info where id = 5 for update;

事物四未被阻塞。

普通索引作為二級索引被加鎖時,對應的主鍵索引也是會被加鎖的,所以可以看到 id 為 10、11 的記錄都會被阻塞住。

間隙鎖

間隙鎖一般存在于 RR 的隔離級別,MySQL 在 RR 隔離級別下可以解決部分幻讀的問題,依靠的就是間隙鎖。間隙鎖的上界、下界都是開區間,間隙鎖存在的目的主要是為了阻塞插入操作,這樣就不會存在相同的條件下查詢的結果集不一致的情況。

間隙鎖示例(RR隔離級別):

普通索引加鎖(未命中記錄)

事物一:

1select * from test_info where description = 300 for update;

事物二:

1INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (3, 21, '210');

事物二會阻塞,因為示例中的事物隔離級別為 RR,并且在事物一中沒有查詢到記錄,為了避免幻讀發生,所以將 (200,500) 的期間鎖住了。上面的介紹中有提到間隙鎖一般存在于 RR 的隔離級別中,所以上面的示例在 RC 隔離級別下執行事物二是不會被阻塞的。

普通索引加鎖(命中記錄)

事物一:

1select * from test_info where description = 200 for update;

事物二:

1select * from test_info where description = 210 for update;

事物二阻塞,結束事物二,執行事物三

事物三:

1select * from test_info where description = 190 for update;

事物三阻塞。

如果普通索引命中了記錄,那么被鎖定的區間不僅有 (200,500),還有 (100,200],所以普通索引的前后都會被鎖住。

唯一索引加鎖

對于唯一索引如果命中記錄,那么會加上記錄鎖(臨間鎖退化為記錄鎖,記錄鎖已演示這種場景),如果沒有命中記錄則會加上間隙鎖。

事物一:

1select * from test_info where no = 21 for update;

事物二:

1INSERT INTO `test_info`(`id`, `no`, `description`) VALUES (3, 22, '210');

事物二阻塞

臨鍵鎖

臨鍵鎖是由記錄鎖與間隙鎖組成的(區間為左開右閉),所以記錄鎖與間隙鎖可以理解成特殊場景下的臨鍵鎖。Innodb 引擎行鎖默認采用的就是臨鍵鎖的算法,只是在不同的場景下會退化成記錄鎖或者間隙鎖。

特殊場景的鎖

插入操作

插入操作加鎖的操作是一個復雜的過程,并不會只存在一把鎖。插入過程中首先會加插入意向鎖,接著檢查是否有唯一鍵沖突的問題,針對唯一性沖突還有可能會加上 S GAP(RC的隔離級別也會存在),當記錄插入成功時還會對該條記錄加上 X 的記錄鎖。

事物一:

1

2

3delete from test_info where no = 50;

insert into `test_info`(`id`, `no`, `description`) values (5, 50, 500);

事物二:

1insert into `test_info`(`id`, `no`, `description`) values (3, 30, 300);

事物二阻塞

總結

以上是生活随笔為你收集整理的mysql数据库的各种锁_关于MySQL各类锁的总结的全部內容,希望文章能夠幫你解決所遇到的問題。

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