天天看點

MySQL 與InnoDB 下的鎖做朋友 (三)意向鎖

前言  

該篇談談 意向鎖。

正文

InnoDB supports multiple granularity locking which permits coexistence of row locks and table locks.

For example, a statement such as LOCK TABLES ... WRITE takes an exclusive lock (an X lock) on the specified table.

To make locking at multiple granularity levels practical, InnoDB uses intention locks.

Intention locks are table-level locks that indicate which type of lock (shared or exclusive) a transaction requires later for a row in a table. 

翻譯:

InnoDB支援多粒度鎖,允許行鎖和表鎖共存。

例如,LOCK TABLES之類的語句。。。WRITE在指定的表上采用獨占鎖(X鎖)。

為了實作多粒度級别的鎖定,InnoDB使用了意向鎖。

意向鎖是表級鎖,用于訓示事務稍後對表中的行需要哪種類型的鎖(共享或獨占)。

看這些文字,感覺就是比較模糊, 那麼我認為我應該寫一點小白文,能讓大家稍微了解一下。

1.意向鎖是表級鎖。

   但是 這個意向鎖是個特殊的表級鎖,由存儲引擎去維護, 它不跟行鎖沖突,意向鎖直接也不沖突因為引擎級别的特殊表級概念。

2.我們要清楚  正常的表鎖和行鎖是沖突的。

是以舉個例子:

那麼如果一個事務 A 對  使用者表内資料 進行了 行鎖排他鎖操作;

事務B去擷取這個使用者表的寫鎖 排他鎖時,第一步回去檢測這個使用者表是否上了表鎖,如果沒有,就會去檢測這個使用者表内資料有行鎖鎖定操作,導緻 表&行鎖沖突(如果存在沖突,就會進入等待行鎖釋放)。

問題就是在這, innodb 有行鎖,有表鎖,都支援。

如果說按照上面的例子,使用者表 确實沒有上 表鎖鎖定, 但是上了行鎖鎖定。

是以事務B為了檢測裡面是否真的有行鎖鎖定, 會對使用者表做 行周遊,去找每一行是不是都沒鎖定操作,這樣才能 擷取表級寫鎖。

這樣看上去效率就很低。

是以設計者 搞出了意向鎖。

當一個事務A 準備對 使用者表進行 行級鎖定操作,InooDB 會先擷取該資料行所在的表的對應意向鎖,進行意向鎖鎖定操作。

這樣事務B過來嘗試對 使用者表做表鎖鎖定操作時,申請鎖資源時,隻需要看下 使用者表是否存在 意向鎖鎖定 ,如果有,直接去等待資源就行,這樣就不需要周遊了(以免遍了N久才知道有沖突,還是需要等待)。

了解了這個意向鎖的作用後,我們再來回歸意向鎖的一些介紹。

意向鎖 分兩種:

意向共享鎖 (IS)

意向排他鎖(IX)

我們對某個表 做行鎖操作時, 行鎖也分 S鎖和 X鎖 (上一篇我們有說到)。

是以,innodb引擎 在知道我們對某個表資料準備使用 S (共享讀鎖,我上篇有講過的)行級鎖定時,就會去對這些行 所在的表,做  意向共享鎖 (IS) 鎖定操作。

同樣,innodb引擎 在知道我們對某個表資料準備使用X (排他寫鎖,我上篇有講過的)行級鎖定時,就會去對這些行 所在的表,做 意向排他鎖(IX)鎖定操作。

最後放出一個小表格,結束我們的意向鎖簡單介紹篇(看久了都快不認識兼字了):

(簡單總結就是,意向鎖互相不沖突。 意向鎖和表級鎖之間的沖突,滿足我上一篇所說的 共享讀鎖和排他寫鎖之間的沖突規則)

标題 意向共享鎖(IS) 意向排他鎖(IX) 表級共享鎖(S) 表級排他鎖(X)
意向共享鎖(IS) 相容 相容 相容 不相容
意向排他鎖(IX) 相容 相容 不相容 不相容
表級共享鎖(S) 相容 不相容 相容 不相容
表級排他鎖(x) 不相容 不相容 不相容 不相容

ps:

小明:教練,我想 上意向鎖!

繼續閱讀