【mysql】- 鎖篇(下)
阿新 • • 發佈:2020-07-14
InnoDB儲存引擎中的鎖
- 表級鎖
- 表級別的
S鎖
、X鎖
- 在對某個表執行
SELECT
、INSERT
、DELETE
、UPDATE
語句時,InnoDB
儲存引擎是不會為這個表新增表級別的S鎖
或者X鎖
的
- 在對某個表執行
- 表級別的
IS鎖
、IX鎖
- 當我們在對使用
InnoDB
儲存引擎的表的某些記錄加S鎖
之前,那就需要先在表級別加一個IS鎖
,當我們在對使用InnoDB
儲存引擎的表的某些記錄加X鎖
之前,那就需要先在表級別加一個IX鎖
。IS鎖
和IX鎖
的使命只是為了後續在加表級別的S鎖
和X鎖
時判斷表中是否有已經被加鎖的記錄,以避免用遍歷的方式來查看錶中有沒有上鎖的記錄
- 當我們在對使用
- 表級別的
AUTO-INC鎖
- 在使用
MySQL
過程中,我們可以為表的某個列新增AUTO_INCREMENT
- 在使用
- 表級別的
- 行級鎖:
行鎖
,也稱為記錄鎖
,顧名思義就是在記錄上加的鎖行鎖
型別Record Locks
:有S鎖
和X鎖
之分,當一個事務獲取了一條記錄的S型記錄鎖
後,其他事務也可以繼續獲取該記錄的S型記錄鎖
,但不可以繼續獲取X型記錄鎖
;當一個事務獲取了一條記錄的X型記錄鎖
後,其他事務既不可以繼續獲取該記錄的S型記錄鎖
,也不可以繼續獲取X型記錄鎖
Gap Locks
:可以用於解決可重複讀級別下的幻讀問題,防止插入幻影記錄Next-Key Locks
: 鎖住某條記錄同時又可以阻止其他事務在該條記錄前邊的間隙
插入新紀錄,其是Record Locks
gap Locks
的合體它既能保護該條記錄,又能阻止別的事務將新記錄插入被保護記錄前邊的間隙
Insert Intention Locks
:一個事務在插入一條記錄時需要判斷一下插入位置是不是被別的事務加了所謂的gap鎖
,若存在,插入操作需要等待,直到擁有的gap鎖
對應的事務提交,事務在等待的時候也需要在記憶體中生成一個鎖結構
,表明有事務想在某個間隙
中插入新紀錄,但是現在在等待。這種型別的鎖命名為Insert Intention Locks
,也成為插入意向鎖
隱式鎖
:一個事務在執行INSERT
操作時,如果即將插入的間隙已經被其他事務加了gap
鎖,那麼本次INSERT
操作會阻塞,並且當前事務會在該間隙上加一個插入意向鎖
INSERT
操作是不加鎖的
記憶體結構
- 加鎖的本質就是在記憶體中建立一個
鎖結構
與之關聯- 對於需要放在同一個
鎖結構
中的情況- 在同一個事務中進行加鎖操作
- 被加鎖的記錄在同一個頁面中
- 加鎖的型別是一樣的
- 等待狀態是一樣的
- 對於需要放在同一個
- 鎖結構
鎖所在的事務資訊
: 不論是表鎖
還是行鎖
,都是在事務執行過程中生成的,哪個事務生成了這個鎖結構
,這裡就記載著這個事務的資訊。其本質是一個指標,通過該指標可以找到記憶體中關於該事務的更多資訊索引資訊
:對於行鎖
來說,需要記錄一下加鎖的記錄是屬於哪個索引的表鎖/行級資訊
:表鎖
:記載著這是對哪個表加的鎖,還有其他的一些資訊行鎖
:記載了三個重要的資訊- Space ID :記錄所在表空間。
- Page Number :記錄所在頁號。
- n_bits :對於行鎖來說,一條記錄就對應著一個位元位,一個頁面中包含很多記錄,用不同的位元位來區分到底是哪一條記錄加了鎖。為此在行鎖結構的末尾放置了一堆位元位,這個
n_bits
屬性代表使用了多少位元位
type_mode
:這是一個32位的數,被分成了lock_mode
、lock_type
和rec_lock_type
三個部分- 鎖的模式( lock_mode ),佔用低4位
LOCK_IS
(十進位制的0
):表示共享意向鎖,也就是IS鎖
。LOCK_IX
(十進位制的1
):表示獨佔意向鎖,也就是IX鎖
。LOCK_S
(十進位制的2
):表示共享鎖,也就是S鎖
。LOCK_X
(十進位制的3
):表示獨佔鎖,也就是X鎖
。LOCK_AUTO_INC
(十進位制的4
):表示AUTO-INC鎖
。
- 鎖的型別( lock_type ),佔用第5〜8位,不過現階段只有第5位和第6位被使用:
LOCK_TABLE
(十進位制的16
),也就是當第5個位元位置為1時,表示表級鎖。LOCK_REC
(十進位制的32
),也就是當第6個位元位置為1時,表示行級鎖
- 行鎖的具體型別(
rec_lock_type
),使用其餘的位來表示。只有在lock_type
的值為LOCK_REC
時,也就是隻有在該鎖為行級鎖時,才會被細分為更多的型別:LOCK_ORDINARY
(十進位制的0
):表示next-key
鎖 。LOCK_GAP
(十進位制的512
):也就是當第10個位元位置為1時,表示gap鎖
。LOCK_REC_NOT_GAP
(十進位制的1024
):也就是當第11個位元位置為1時,表示記錄鎖
。LOCK_INSERT_INTENTION
(十進位制的2048
):也就是當第12個位元位置為1時,表示插入意向鎖
- 鎖的模式( lock_mode ),佔用低4位