InnoDB 使用的 鎖類型html
共享鎖和排它鎖mysql
意向鎖算法
記錄鎖sql
間隙鎖數據庫
Next-key 鎖併發
插入意向鎖高併發
AUTO-INC 鎖性能
共享鎖和排他鎖spa
InnoDB實現了倆個標準的行級鎖,共享鎖和排它鎖。code
共享鎖容許持有者讀取一行
排它鎖容許持有者更新或者刪除一行
若是一個事物T1在 r 行持有一把共享鎖,則來自於不一樣的事物T2在 r 行上的鎖請求將按照以下方法處理:
T2請求共享鎖能夠當即被受權,所以T1和T2都持有了在 r 行上的共享鎖
T2請求排它鎖不能夠當即被受權。
若是一個事物T1在 r 行持有一把排它鎖,則來自與不一樣事物T2在r上的任何鎖請求將不會當即被受權。
意向鎖
InnoDB支持多粒度鎖:指容許表級鎖和行級鎖共存。爲了實如今多粒度級別上鎖,額外的鎖類型(意向鎖)被使用。意向鎖是一個表級鎖,它代表將來在那張表上會有哪種鎖類型(排他或者共享)被事物請求。
InnoDB有倆種類型的意向鎖(假設事物未來會在某張表t上請求鎖):意向共享鎖,意向排他鎖。
意向共享鎖:指事物意圖在表t上的某些行上加S鎖
意向排它鎖:指事物意圖在表t上的某些行上加X鎖
意向鎖協議描述以下:
事物在表t上的一行上加S鎖以前,他必須獲取IS鎖或者在t上更強的鎖(指表級鎖)
事物在表t上的一行上加X鎖以前,他必須獲取IX鎖
上述鎖規則協議能夠方便的歸納以下的兼容性矩陣:
X |
IX |
S |
IS |
|
---|---|---|---|---|
X |
Conflict | Conflict | Conflict | Conflict |
IX |
Conflict | Compatible | Conflict | Compatible |
S |
Conflict | Conflict | Compatible | Compatible |
IS |
Conflict | Compatible | Compatible | Compatible |
注:意向鎖是MySQL本身自動處理,爲了解決表級鎖和行級鎖的衝突,即提前檢測鎖衝突。
S、X、IS、IX鎖兼容性矩陣爲何是這樣子呢?
一、意向鎖之間彼此不會衝突,由於它們都只是「有意」,而不是真幹,因此是能夠兼容的。在加行鎖以前,會使用意向鎖判斷是否衝突;二、IX和X的關係等同於X和X之間的關係,爲何呢?由於事務得到了IX鎖,接下來就有權利獲取X鎖,這樣就會出現兩個事務都獲取X鎖的狀況,這和咱們已知的X鎖和X鎖之間互斥是矛盾的;三、S和IS、X和IS、IX和IS也能夠由此推導出來。
一個鎖被授予一個事物,是在該鎖與事物已獲取的鎖兼容的時候,而不是與現有鎖衝突的時候。事物等待直到衝突的鎖被釋放。若是一個鎖請求與現有的鎖衝突,而且由於死鎖不能被授予,一個錯誤會發生,MySQL本身決定哪一個事物回滾。
所以意向鎖不阻塞任何事物,除了全表鎖請求。IX鎖和IS鎖是用來代表某我的或者事物正在持有鎖或者將要持有鎖。
記錄鎖
一個記錄鎖是在索引記錄上的鎖,僅鎖住一行。例如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 阻止任何其餘事物插入、更新、刪除c1=10的行,前提是c1有索引。
記錄鎖鎖住的只是記錄的索引「記錄」,及時一個表沒有定義任何索引,InnoDB也會默認建立一個聚簇索引,並用來加鎖。
不符合where條件的記錄鎖會被釋放。
間隙鎖
間隙鎖是指鎖住索引記錄之間的空隙(並不鎖住索引記錄,即開區間),或者明確指定索引記錄的第一個和最後一個,例如:SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止任何其餘事物的插入、更新和刪除
Gap能夠僅有一個值,多個值或者爲空。
Gap鎖是在性能和併發度上權衡的結果,並被某些事物隔離級別使用。
Gap鎖在一些使用惟一索引的來檢索惟一行的語句中是沒有必要的,由於索引的結果是惟一的,沒有間隙,不會妨礙其餘會話(事物)插入記錄。注,那些語句中包含惟一索引和二級索引的仍然適用Gap鎖。
值得注意的是,在不一樣事物中,鎖衝突能夠發生在同一個間隙裏,例如一個事物A持有一把共享GAP鎖在Gap間隙中,同時事物B持有一把排他的Gap鎖,倆個Gap屬於同一個。
注,舉一個例子,假設數據庫存在id爲1,2,3,5,7;事物1:select * from student where id between 3 and 9 for update; 事物2:select * from student where id = 8; 倆個事物共享(7-9)這個間隙鎖,但互不影響。
衝突Gap被容許的緣由是若是一個記錄從索引中被清除了,不一樣事物在這個記錄上的Gap鎖必須合併。
注:上述狀況未實驗成功,首先是不太明白其意思,其次是若是刪除索引記錄,意味着加X鎖,然而這個鎖的排他性已是衝突了,並不能驗證成功。若是有人直銷煩請告知,不勝感激!
Gap鎖在InnoDB中是純抑制做用,意思是Gap鎖僅阻止其餘事物插入這個gap間隙,他們不阻止不一樣的事物在相同的gap上獲取gap鎖。所以,GapX鎖和GapS鎖有相同的效果。
Gap鎖能夠被禁用,經過設置RC隔離級別,或者啓用 innodb_locks_unsafe_for_binlog系統變量(當前已標記爲了棄用),此時,在檢索和掃描的時候Gap鎖被禁用,且僅被用做外鍵檢查和重複值檢測。
注:當用惟一索引時,三種方法可能產生間隙鎖:
1. 惟一檢索值不存在,此時會在索引中尋找「最小區間」加間隙鎖;
2. between and 條件篩選肯定索引間隙加鎖;
3. 檢索值和比較操做符,例如大於小於檢索值(此時符合的記錄也會加記錄鎖,不只僅是間隙鎖)
Next-key Locks
Next-key鎖是記錄鎖和Gap鎖的結合。
InnoDB 執行行級鎖,所以,當檢索或掃描表索引時,他設置S或者X鎖到遇到的索引記錄上。所以,行級鎖其實是記錄鎖,一個索引記錄上的next-key鎖,一樣影響索引記錄以前的gap。就是說next-key鎖是一個記錄鎖,加上一個gap(記錄以前)鎖。
假設索引裏面有10,11,13,20。則可能的next-key鎖是:
(negative infinity, 10] (10, 11] (11, 13] (13, 20] (20, positive infinity)
默認地,InnoDB提供的事物隔離級別是RR,此時InnoDB使用的是next-key鎖,在檢索和掃描的時候。以阻止幻讀。next-key在使用惟一索引時會降級爲記錄鎖,提升併發度。
插入意向鎖(一種特殊的gap鎖):
插入意向鎖是當插入操做執行時,設置的一種特殊的gap類型鎖。這個lock標誌一種插入行爲:若是每一個事物插入gap中的位置不同時在多事物插入相同的gap狀況不須要互相等待。這主要是提升併發插入效率。
AUTO-INC鎖
該鎖類型是一種特殊的表級鎖,在事物插入自動增加字段時使用。若是一個事物插入列值(自動增加列)到表中,任何其餘的事物必須等待,所以插入的字段纔會是連續的值。
innodb_autoinc_lock_mode配置選項,控制自動增加鎖使用的算法,它容許你選擇插入操做時,如何來權衡可預測的自動增加值和最大併發度
注:
排它鎖和共享鎖是指鎖的性質,意圖鎖是意圖。
記錄鎖和Gap鎖是鎖的範圍,這就會出現是在必定的範圍加特定性質的鎖的問題。