詳解 MySql InnoDB 中意向鎖的作用

2021-09-11 15:40:22 字數 3977 閱讀 3891

innodb 支援多粒度鎖(multiple granularity locking),它允許行級鎖表級鎖共存,而意向鎖就是其中的一種表鎖

需要強調一下,意向鎖是一種不與行級鎖衝突表級鎖,這一點非常重要。意向鎖分為兩種:

即:意向鎖是有資料引擎自己維護的,使用者無法手動操作意向鎖,在為資料行加共享 / 排他鎖之前,inoodb 會先獲取該資料行所在在資料表的對應意向鎖。

如果另乙個任務試圖在該錶級別上應用共享或排它鎖,則受到由第乙個任務控制的表級別意向鎖的阻塞。第二個任務在鎖定該錶前不必檢查各個頁或行鎖,而只需檢查表上的意向鎖。

設想這樣一張users表:mysqlinnodbrepeatable-read:users(id pk,name)

idname

1roadhog

2reinhardt

3tracer

4genji

5hanzo

6mccree

事務 a 獲取了某一行的排他鎖,並未提交:

select * from

users

where

id = 6

forupdate;

複製**

事務 b 想要獲取users表的表鎖:

lock

tables

users

read;

複製**

因為共享鎖與排他鎖互斥,所以事務 b 在檢視對users表加共享鎖的時候,必須保證:

為了檢測是否滿足第二個條件,事務 b 必須在確保users表不存在任何排他鎖的前提下,去檢測表中的每一行是否存在排他鎖。很明顯這是乙個效率很差的做法,但是有了意向鎖之後,情況就不一樣了:

意向鎖是怎麼解決這個問題的呢?首先,我們需要知道意向鎖之間的相容互斥性:

意向共享鎖(is)

意向排他鎖(ix)

意向共享鎖(is)相容

相容意向排他鎖(ix)相容

相容 即意向鎖之間是互相相容的,emmm......那你存在的意義是啥?

雖然意向鎖和自家兄弟互相相容,但是它會與普通的排他 / 共享鎖互斥:

意向共享鎖(is)

意向排他鎖(ix)

共享鎖(s)相容

互斥排他鎖(x)互斥

互斥注意:這裡的排他 / 共享鎖指的都是表鎖!!!意向鎖不會與行級的共享 / 排他鎖互斥!!!

現在我們回到剛才users表的例子:

事務 a獲取了某一行的排他鎖,並未提交:

select * from

users

where

id = 6

forupdate;

複製**

此時users表存在兩把鎖:users表上的意向排他鎖與 id 為 6 的資料行上的排他鎖

事務 b 想要獲取 users 表的共享鎖:

lock

tables

users

read;

複製**

此時事務 b檢測事務 a 持有users表的意向排他鎖,就可以得知事務 a必然持有該表中某些資料行的排他鎖,那麼事務 busers表的加鎖請求就會被排斥(阻塞),而無需去檢測表中的每一行資料是否存在排他鎖。

這就牽扯到我前面多次強調的一件事情:

意向鎖不會與行級的共享 / 排他鎖互斥!!!

意向鎖不會與行級的共享 / 排他鎖互斥!!!

意向鎖不會與行級的共享 / 排他鎖互斥!!!

重要的話要加粗說三遍,正因為如此,意向鎖並不會影響到多個事務對不同資料行加排他鎖時的併發性(不然我們直接用普通的表鎖就行了)。

最後我們擴充套件一下上面 users 表的例子來概括一下意向鎖的作用(一條資料從被鎖定到被釋放的過程中,可能存在多種不同鎖,但是這裡我們只著重表現意向鎖):

idname

1roadhog

2reinhardt

3tracer

4genji

5hanzo

6mccree

事務 a先獲取了某一行的排他鎖,並未提交:

select * from

users

where

id = 6

forupdate;

複製**

事務 a獲取了users表上的意向排他鎖

事務 a獲取了 id 為 6 的資料行上的排他鎖

之後事務 b想要獲取users表的共享鎖

lock

tables

users

read;

複製**

事務 b檢測到事務 a持有users表的意向排他鎖

事務 busers表的加鎖請求被阻塞(排斥)。

最後事務 c也想獲取users表中某一行的排他鎖

select * from

users

where

id = 5

forupdate;

複製**

事務 c申請users表的意向排他鎖

事務 c檢測到事務 a持有users表的意向排他鎖

因為意向鎖之間並不互斥,所以事務 c獲取到了users表的意向排他鎖

因為id 為 5 的資料行上不存在任何排他鎖,最終事務 c成功獲取到了該資料行上的排他鎖

innodb 支援多粒度鎖,特定場景下,行級鎖可以與表級鎖共存。

意向鎖之間互不排斥,但除了 is 與 s 相容外,意向鎖會與 共享鎖 / 排他鎖 互斥

ix,is是表級鎖,不會和行級的x,s鎖發生衝突。只會和表級的x,s發生衝突。

意向鎖在保證併發性的前提下,實現了行鎖和表鎖共存滿足事務隔離性的要求。

詳解 MySql InnoDB 中意向鎖的作用

innodb 支援多粒度鎖 multiple granularity locking 它允許行級鎖與表級鎖共存,而意向鎖就是其中的一種表鎖。需要強調一下,意向鎖是一種不與行級鎖衝突表級鎖,這一點非常重要。意向鎖分為兩種 事務要獲取某些行的 s 鎖,必須先獲得表的 is 鎖。select column...

mysql innodb死鎖問題詳解

1 最近旅遊電商平台對外提供的介面經常有終端使用者反映請求超時異常 2 進過排查伺服器日誌有報錯,錯誤資訊如下 error 1205 hy000 lockwait timeout exceeded try restarting transaction 3 了解平台使用的是mysql 資料庫版本5.6...

MySQL InnoDB索引原理詳解

1 簡介 索引 index 是幫助mysql高效獲取資料的資料結構。我們知道,資料庫查詢是資料庫的最主要功能之一。但每種查詢演算法都只能應用於特定的資料結構之上,例如二分查詢要求被檢索資料有序,而二叉樹查詢只能應用於二叉查詢樹上,但是資料本身的組織結構不可能完全滿足各種資料結構 例如,理論上不可能同...