1、全局鎖
加上全局鎖后整個數據庫就處于只讀狀態了,這時其他線程執行以下操作,都會被阻塞:
- 對數據的增刪改操作,比如 insert、delete、update等語句;
- 對表結構的更改操作,比如 alter table、drop table 等語句。
全局鎖的使用場景
- 邏輯備份:全局鎖的典型使用場景是進行全庫邏輯備份,例如使用?
mysqldump
?工具。在備份期間,整個庫處于只讀狀態,確保備份的數據是一致的。 - 主從切換:在重新配置主從復制時,可以使用全局鎖來確保不會有其他線程對數據庫進行更新,從而保持數據一致性。
可以看出再加上全局鎖后數據庫的除查詢外的其他所有業務都被阻塞住了,性能一定很低下。我們可以再可重復讀的隔離級別下進行數據備份,備份的數據都是再開啟事務那一刻的數據,就不要開啟全局鎖來控制并發操作,防止破壞數據庫一致性了。
2、表鎖
? 2.1表鎖
- 表鎖是一種粗粒度的鎖,它會鎖定整個表,除了會限制別的線程的讀寫外,也會限制本線程接下來的讀寫操作。
- 表鎖適用于特定的場景,但通常不推薦使用,因為它會影響并發性能。
?2.2意向鎖
- 意向鎖是一種表級鎖,用于指示其他事務是否已經持有了行級鎖或表級鎖。
- 意向鎖不會阻塞其他事務,只是作為一種標記。
- 什么時候加意向鎖:
-
在獲取行級鎖之前,在獲取表級鎖之前都需要先加上意向鎖。
- 意向鎖的存在表示其他事務可能已經在該表上加了表鎖/行級鎖,因此事務在獲取表級鎖/行鎖之前需要先檢查意向鎖。
-
- 意向鎖的目的是為了快速判斷表里是否有記錄被加鎖。
2.3?元數據鎖(MDL)
這個鎖其實是為了防止再操作數據庫表中數據時,表的結構發生了改變。
- 對一張表進行 CRUD 操作時,加的是?MDL 讀鎖;
- 對一張表做結構變更操作的時候,加的是?MDL 寫鎖;
- 讀鎖和讀鎖不互斥,讀寫鎖互斥。再MDL鎖等待隊列中,寫鎖優先級高于讀鎖。
MDL 是在事務提交后才會釋放,這意味著事務執行期間,MDL 是一直持有的。
?2.4 AUTO-INC 鎖
-
AUTO-INC 鎖是特殊的表鎖機制,鎖不是再一個事務提交后才釋放,而是再執行完插入語句后就會立即釋放。
-
在插入數據時,會加一個表級別的 AUTO-INC 鎖,然后為被?
AUTO_INCREMENT
?修飾的字段賦值遞增的值,等插入語句執行完成后,才會把 AUTO-INC 鎖釋放掉。 -
nnoDB 存儲引擎提供了個 innodb_autoinc_lock_mode 的系統變量,是用來控制選擇用 AUTO-INC 鎖,還是輕量級的鎖。
- 當 innodb_autoinc_lock_mode = 0,就采用 AUTO-INC 鎖,語句執行結束后才釋放鎖;
- 當 innodb_autoinc_lock_mode = 2,就采用輕量級鎖,申請自增主鍵后就釋放鎖,并不需要等語句執行后才釋放。
- 當 innodb_autoinc_lock_mode = 1:
- 普通 insert 語句,自增鎖在申請之后就馬上釋放;
- 類似 insert … select 這樣的批量插入數據的語句,自增鎖還是要等語句結束后才被釋放;
3、行鎖
?3.1 記錄鎖(Record Lock)
? ? ? ? 這個鎖,鎖的是一條記錄,有S鎖(共享鎖)和X鎖(排它鎖)之分。其中SS不互斥,SX互斥、XX互斥。普通的select查詢語句不會加鎖。他是通過MVCC進行快照讀。像快照讀才會進行加鎖,具體加的是S鎖還是X鎖要看執行的語句。
SELECT ... LOCK IN SHARE MODE;????????????????加共享鎖
SELECT ... FOR UPDATE;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 加互斥鎖
select * from t_test where id = 1 for update;? ?給id為1的記錄加上互斥鎖,待事務結束釋放鎖
? 3.2 間隙鎖(Gap Lock )
????????只存在于可重復讀隔離級別,目的是為了解決可重復讀隔離級別下幻讀的現象。
假設,表中有一個范圍 id 為(3,5)間隙鎖,那么其他事務就無法插入 id = 4 這條記錄了,這樣就有效的防止幻讀現象的發生。
????????間隙鎖雖然存在 X 型間隙鎖和 S 型間隙鎖,但是并沒有什么區別,間隙鎖之間是兼容的,即兩個事務可以同時持有包含共同間隙范圍的間隙鎖,并不存在互斥關系,因為間隙鎖的目的是防止插入幻影記錄而提出的。
?3.3 Next-Key Lock(臨鍵鎖)
? 臨鍵鎖是 Record Lock + Gap Lock 的組合,鎖定一個范圍,并且鎖定記錄本身。
????????假設,表中有一個范圍 id 為(3,5] 的 next-key lock,那么其他事務即不能插入 id = 4 記錄,也不能修改 id = 5 這條記錄。next-key lock 是包含間隙鎖+記錄鎖的,如果一個事務獲取了 X 型的 next-key lock,那么另外一個事務在獲取相同范圍的 X 型的 next-key lock 時,是會被阻塞的。
?3.4?插入意向鎖
????????一個事務在插入一條記錄的時候,需要判斷插入位置是否已被其他事務加了間隙鎖(next-key lock 也包含間隙鎖)。
? ? ? ??如果有的話,插入操作就會發生阻塞,直到擁有間隙鎖的那個事務提交為止(釋放間隙鎖的時刻),在此期間會生成一個插入意向鎖,表明有事務想在某個區間插入新記錄,但是現在處于等待狀態。
????????當事務 A 還沒提交的時候,事務 B 向該表插入一條 id = 4 的新記錄,這時會判斷到插入的位置已經被事務 A 加了間隙鎖,于是事物 B 會生成一個插入意向鎖,然后將鎖的狀態設置為等待狀態。此時事務 B 就會發生阻塞,直到事務 A 提交了事務。
插入意向鎖名字雖然有意向鎖,但是它并不是意向鎖,它是一種特殊的間隙鎖,屬于行級別鎖。
如果說間隙鎖鎖住的是一個區間,那么「插入意向鎖」鎖住的就是一個點。因而從這個角度來說,插入意向鎖確實是一種特殊的間隙鎖。
PS:MySQL 加鎖時,是先生成鎖結構,然后設置鎖的狀態,如果鎖狀態是等待狀態,并不是意味著事務成功獲取到了鎖,只有當鎖狀態為正常狀態時,才代表事務成功獲取到了鎖。