0、前言
上一篇從MySQL層面上了解鎖,那么這篇我們從存儲引擎上來了解, 以MySQL默認存儲引擎Innodb來說,看看有哪些鎖?(MySQL版本為8)
1、Shared and Exclusive Locks -- 共享鎖和排他鎖
兩者都是行級鎖;
Shared Lock -- 共享鎖(S), 也稱為讀鎖。允許多個事務同一時刻並發讀取同一記錄,互不干擾。但不允許再加排他鎖。
加鎖方式:select * from table where xxx for share;
Exclusive Lock -- 排他鎖(X),也稱寫鎖。一個寫鎖會阻塞其它的寫鎖或讀鎖,保證同一時刻只有一個事務可以寫入數據。
加鎖方式:select * from table where xxx for update;
這里要注意下:
-
如果沒有指定某行,而掃描了表中的所有記錄,則相當於表級鎖了。
-
在其他事務中沒有操作的前提下,同一事務中是可以同時擁有某行的共享鎖和排他鎖的。
下面是的排他鎖和共享鎖的兼容性。
X |
S |
|
X |
互斥 |
互斥 |
S |
互斥 |
兼容 |
2、Intention Locks -- 意向鎖
表級鎖,指示事務稍后對表中的行需要哪種類型的鎖(排他鎖或共享鎖)。所以又分為兩種類型的意向鎖。
IS(Intention Shared Lock):意向共享鎖,表示事務打算在表中的各個行上設置共享鎖。
IX(Intention Exclusive Lock): 意向排他鎖,表示事務打算在表中的各個行上設置排他鎖。
意向鎖定協議如下:
在事務可以獲取表中某行上的共享鎖/排他鎖之前,它必須首先獲取該表上的意向共享鎖/意向排他鎖。例如:
-
select ... for share 需要先獲取IS鎖
-
select ... for update 需要先獲取IX鎖
下面是表級別的鎖類型兼容性。
X |
IX |
S |
IS |
|
X |
互斥 |
互斥 |
互斥 |
互斥 |
IX |
互斥 |
兼容 |
互斥 |
兼容 |
S |
互斥 |
互斥 |
兼容 |
兼容 |
IS |
互斥 |
兼容 |
兼容 |
兼容 |
如果鎖與現有鎖沖突,則不授予該鎖。
特別注意:
-
意向鎖除了全表請求(例如:Lock tables ... write)外,不阻止任何其他內容。
-
意向鎖的主要目的是表明有人正在鎖定表中的行,或者將要鎖定表中的行。
3、Record Locks -- 記錄鎖
記錄鎖是對索引記錄的鎖定。例如
select c1 from t where c1 = 10 for update;
表示防止任何其他事務插入、更新或刪除t.c1=10的行。
4、Gap Locks -- 間隙鎖
間隙鎖是對索引記錄之間的間隙的鎖定。例如:
select c1 from t where c1 between 10 and 20 for update;
表示防止其他事務動(插入、更新或刪除)t.c1在10~20中的記錄。
特別注意:
-
間隙鎖是可以共存的。例如:事務A在間隙上添加一個間隙共享鎖(Gap S-Lock),事務B可以在同一間隙上增加間隙排他鎖(Gap X-Lock)
-
間隙鎖可以禁用。修改事務隔離級別至RC 或者 啟用系統變量innodb_locks_unsafe_for_binlog
5、Next-Key Locks -- 下一個鍵鎖
下一個鍵鎖又稱臨界鎖,是索引記錄上的記錄鎖和索引記錄之前的間隙上的間隙鎖的組合。即Next-Key Lock 包含 Record Lock 和 Gap Lock。
默認情況下,InnoDB在可重復讀取事務隔離級別下運行。在這種情況下,InnoDB使用next鍵鎖進行搜索和索引掃描,從而防止幻讀。
6、Insert Intension Locks -- 插入意向鎖
插入意向鎖是在行插入之前由插入操作設置的一種間隙鎖。
7、AUTO-INC Locks -- 自增鎖
AUTO-INC鎖是一種特殊的表級鎖,由插入到具有自動增量列的表中的事務使用。
8、總結
本次只是說明下相關概念, 下篇文章說下各種鎖的實際用法,怎么查看加了什么鎖,什么情況下會加什么鎖。