MySQL InnoDB鎖問題(四)

2021-07-25 19:33:08 字數 1908 閱讀 4449

一、innodb行鎖實現方式。

innodb行鎖是通過給索引上的索引項來加鎖實現的,如果沒有索引,innodb將通過隱藏的聚簇索引來對記錄加鎖。innodb行鎖分三種情形。

(1)record lock :對索引項加鎖。

(2)grap lock:對索引項之間的」間隙」、第一條記錄前的「間隙」,或者最後一條記錄後的「間隙」加鎖。

(3)next-key lock:前兩種的組合,對記錄及其前面的間隙加鎖。

innodb這樣行鎖實現的特點意味著:如果不通過索引條件檢索資料,那麼innodb將對錶中的所有記錄加鎖,實際效果和表鎖一樣。

在實際的應用中,需要特別注意行鎖的這一特性,否則導致大量的鎖衝突,從而影響併發效能。

下面通過例子說明情況。

a、不通過索引條件查詢時,innodb會鎖定表中所有記錄。

如果開始tab_no_index沒有索引。

從上面**中可以看出,session1只給一行新增排他鎖,但session2在請求其他排他鎖的時,卻出現了鎖等待!原因就是在沒有鎖等待的情況下,innodb會給所有記錄新增排他鎖。如果表有索引時,innodb就只鎖定了符合條件的行,如下圖所示:

建立tab_with_index表,id欄位為普通的索引。

(b)、由於mysql的行鎖是爭對索引新增的鎖,不是爭對記錄新增的鎖,所以雖然是訪問不同的行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的。設計的使用應該特別注意這一點。

(c)、當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,無論是使用主鍵索引,唯一索引或者普通索引,innodb都會使用行鎖來加鎖。

(d)、即使在條件中使用了索引字段,但是否使用索引來檢索資料是由mysql通過判斷不同執行計畫的代價來決定的,如果mysql認為全表掃瞄效率更高,比如一些很小的表,他就不會使用索引,這種情況innodb會對所有的記錄新增行鎖。

因此在分析鎖衝突時,別忘記檢查sql的執行計畫,以確認是否真正使用索引。下面的例子中,檢索值得資料型別和索引字段不同,雖然mysql可以進行資料型別轉換,但卻不會使用索引,從而導致innodb給索引記錄新增行鎖。通過explain檢查兩條sql的執行計畫,可以清楚看到這一點。

栗子中,tab_with_index表的name欄位有索引,但是name欄位是varchar型別,如果where條件中,不是和varchar型別進行比較,則會對那麼進行隱式的資料型別轉換,導致索引無法使用,走了全表掃瞄。

MySQL InnoDB鎖問題(五)

一 next key鎖。當我們使用範圍條件而不是相等條件去檢索資料,並請求共享鎖和排他鎖時,innodb會給符合條件的已有的資料新增上鎖 對於鍵值在條件範圍內,但不存在的記錄,叫間隙。innodb此時會給這個部分新增上鎖,這種鎖機制就是next key鎖。假如 員工表emp中只有101條資料,其em...

MySQL InnoDB鎖問題(六)

一 在innodb情況下什麼時候使用表鎖。對於innodb表,大多數情況都應該使用行鎖,因為事務和行鎖往往是我們選擇innodb表的重要原因。但在特殊的情況下,也可以使用表級鎖。1 事務需要更新大部分資料或者全部資料,表又比較大,如果使用預設的行級鎖,不僅使得事務執行比較慢效率低,而且可能造成其他事...

Mysql innodb引擎(二)鎖

專案 isixsx is相容 相容相容 不相容ix 相容相容 不相容不相容s相容 不相容相容 不相容x 不相容不相容 不相容不相容 是指 innodb 通過多版本控制的方式來讀取當前執行時間資料庫中的資料。如果,讀取的時候行正好在執行 delete 或 update 的排他操作,那讀取操作不會等待,...