InnoDB併發插入,居然使用意向鎖?
今天,將要介紹InnoDB另外三種:共享/排他鎖,意向鎖,插入意向鎖。
一,共享/排它鎖(Shared and Exclusive Locks)
《 InnoDB併發為何這麼高? 》一文介紹了通用的共享/排它鎖,在InnoDB裡當然也實現了標準的行級鎖(row-level locking),共享/排它鎖:
(1)事務拿到某一行記錄的共享S鎖,才可以讀取這一行;
(2)事務拿到某一行記錄的排它X鎖,才可以修改或者刪除這一行;
其相容互斥表如下:
S X
S 相容 互斥
X 互斥 互斥
即:
(1)多個事務可以拿到一把S鎖,讀讀可以並行;
(2)而只有一個事務可以拿到X鎖,寫寫/讀寫必須互斥;
共享/排它鎖的潛在問題是,不能充分的並行,解決思路是資料多版本,具體思路在《 InnoDB併發為何這麼高? 》裡介紹過,這裡不再深入展開。
二,意向鎖(Intention Locks)
InnoDB支援多粒度鎖(multiple granularity locking),它允許行級鎖與表級鎖共存,實際應用中,InnoDB使用的是意向鎖。
意向鎖是指,未來的某個時刻,事務可能要加共享/排它鎖了,先提前宣告一個意向。
意向鎖有這樣一些特點:
(1)首先,意向鎖,是一個表級別的鎖(table-level locking);
(2)意向鎖分為:
-
意向共享鎖(intention shared lock, IS),它預示著,事務有意向對錶中的某些行加共享S鎖
-
意向排它鎖(intention exclusive lock, IX),它預示著,事務有意向對錶中的某些行加排它X鎖
舉個例子:
select ... lock in share mode,要設定IS鎖;
select ... for update,要設定IX鎖;
(3)意向鎖協議(intention locking protocol)並不複雜:
-
事務要獲得某些行的S鎖,必須先獲得表的IS鎖
-
事務要獲得某些行的X鎖,必須先獲得表的IX鎖
(4)由於意向鎖僅僅表明意向,它其實是比較弱的鎖,意向鎖之間並不相互互斥,而是可以並行,其相容互斥表如下:
IS IX
IS 相容 相容
IX 相容 相容
(5)額,既然意向鎖之間都相互相容,那其意義在哪裡呢?它會與共享鎖/排它鎖互斥,其相容互斥表如下:
S X
IS 相容 互斥
IX 互斥 互斥
畫外音:排它鎖是很強的鎖,不與其他型別的鎖相容。這也很好理解,修改和刪除某一行的時候,必須獲得強鎖,禁止這一行上的其他併發,以保障資料的一致性。
三,插入意向鎖(Insert Intention Locks)
對已有資料行的修改與刪除,必須加強互斥鎖X鎖,那對於資料的插入,是否還需要加這麼強的鎖,來實施互斥呢?插入意向鎖,孕育而生。
插入意向鎖,是間隙鎖(Gap Locks)的一種(所以,也是實施在索引上的),它是專門針對insert操作的。
畫外音:有點尷尬,間隙鎖下一篇文章才會介紹,暫且理解為,它是一種實施在索引上,鎖定索引某個區間範圍的鎖。
它的玩法是:
多個事務,在同一個索引,同一個範圍區間插入記錄時,如果插入的位置不衝突,不會阻塞彼此。
畫外音:官網的說法是
Insert Intention Lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.
這樣,之前挖坑的例子,就能夠解答了。
在MySQL,InnoDB,RR下:
t(id unique PK, name);
資料表中有資料:
10, shenjian
20, zhangsan
30, lisi
事務A先執行,在10與20兩條記錄中插入了一行,還未提交:
insert into t values(11, xxx);
事務B後執行,也在10與20兩條記錄中插入了一行:
insert into t values(12, ooo);
(1)會使用什麼鎖?
(2)事務B會不會被阻塞呢?
回答:雖然事務隔離級別是RR,雖然是同一個索引,雖然是同一個區間,但插入的記錄並不衝突,故這裡:
-
使用的是插入意向鎖
-
並不會阻塞事務B
思路總結
(1)InnoDB使用共享鎖,可以提高讀讀併發;
(2)為了保證資料強一致,InnoDB使用強互斥鎖,保證同一行記錄修改與刪除的序列性;
(3)InnoDB使用插入意向鎖,可以提高插入併發;
結尾
假設不是插入併發,而是讀寫併發,又會是什麼樣的結果呢?
MySQL,InnoDB,預設的隔離級別(RR)。
t(id unique PK, name);
資料表中有資料:
10, shenjian
20, zhangsan
30, lisi
事務A先執行,查詢了一些記錄,還未提交:
select * from t where id>10;
事務B後執行,在10與20兩條記錄中插入了一行:
insert into t values(11, xxx);
這裡:
(1)會使用什麼鎖?
(2)事務B會不會被阻塞呢?
下回分解。
【本文轉載自微信公眾號“架構師之路”,公眾號ID:road5858,作者:58沈劍】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31077337/viewspace-2212421/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- InnoDB意向鎖和插入意向鎖
- 論 MySql InnoDB 如何通過插入意向鎖控制併發插入MySql
- 詳解 MySql InnoDB 中意向鎖的作用MySql
- 《淺入淺出MySQL》表鎖 行鎖 併發插入MySql
- mysql innodb 主鍵INT、BIGINT、VARCHAR併發插入效能對比MySql
- 意向共享鎖與意向排它鎖:詳解與應用
- MySQL鎖(讀鎖、共享鎖、寫鎖、S鎖、排它鎖、獨佔鎖、X鎖、表鎖、意向鎖、自增鎖、MDL鎖、RL鎖、GL鎖、NKL鎖、插入意向鎖、間隙鎖、頁鎖、悲觀鎖、樂觀鎖、隱式鎖、顯示鎖、全域性鎖、死鎖)MySql
- MYSQL意向鎖的作用MySql
- Mysql鎖之行級鎖和表級意向鎖MySql
- 高併發(鎖)
- 併發:死鎖
- MySQL的事務機制和鎖(InnoDB引擎、MVCC多版本併發控制技術)MySqlMVC
- 『MySQL』搞懂 InnoDB 鎖機制 以及 高併發下如何解決超賣問題MySql
- Innodb中有哪些鎖?
- 聊聊併發控制鎖
- 聊聊併發(七)——鎖
- Java併發4:鎖Java
- MySQL鎖:03.InnoDB行鎖MySql
- MySQL 配置InnoDB的併發執行緒MySql執行緒
- InnoDB併發如此高,原因竟然在這?
- Redis在.net中的使用(6)Redis併發鎖Redis
- Java併發程式設計-鎖及併發容器Java程式設計
- Innodb 鎖子系統
- Mysql innodb引擎(二)鎖MySql
- [Java併發]避免死鎖Java
- 淺談併發加鎖
- Java併發:樂觀鎖Java
- 併發控制——樂觀鎖和悲觀鎖
- MySQL鎖:InnoDB行鎖需要避免的坑MySql
- Java併發-顯式鎖篇【可重入鎖+讀寫鎖】Java
- Java併發基礎-鎖的使用及原理(可重入鎖、讀寫鎖、內建鎖、訊號量等)Java
- Java併發之顯式鎖Java
- MySQL如何加鎖控制併發MySql
- Java併發——讀寫鎖ReentrantReadWriteLockJava
- InnoDB學習(五)之MVCC多版本併發控制MVC
- 併發請求的重複插入問題
- InnoDB 事務加鎖分析
- InnoDB鎖衝突案例演示