Mysql存儲引擎InnoDB鎖原理詳解

準備

測試環境:測試環境:

Mysql 5.7.20-log

數據庫默認隔離級別:RR(Repeatable Read,可重複讀)

創建一張存儲引擎為InnoDB的表,sql為:

CREATE TABLE innodb (
id int(11) DEFAULT NULL,
num int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

InnoDB鎖與MySIAM鎖的區別

1.InnoDB的實現了行級鎖,粒度更小

2.InnoDB的鎖支持事務

InnoDB鎖分類及概述

Mysql存儲引擎InnoDB鎖原理詳解

InnoDB中鎖分類

1.樂觀鎖(非mysql自帶):樂觀鎖會“樂觀地”假定大概率不會發生併發更新衝突,訪問、處理數據過程中不加鎖,只在更新數據時再根據版本號或時間戳判斷是否有衝突,有則處理,無則提交事務。

2.悲觀鎖:悲觀鎖的特點是先獲取鎖,再進行業務操作,即“悲觀”的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作,即通常所謂的“一鎖二查三更新”。

其又可分為共享鎖和排他鎖,見下文詳解。

3.關於鎖粒度(上一篇有提到)

4.InnoDB有三種鎖算法——記錄鎖、gap間隙鎖、還有結合了記錄鎖與間隙鎖的next-key鎖,InnoDB對於行的查詢加鎖是使用的是next-key locking這種算法,一定程度上解決了幻讀問題;

InnoDB行鎖

1.共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。

2.排他鎖

(X):允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集的共享讀鎖和排他寫鎖。

另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

意向共享鎖(IS):事務打算給數據行加行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。

意向排他鎖(IX):事務打算給數據行加行排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖

以下是4種鎖的兼容性:

Mysql存儲引擎InnoDB鎖原理詳解

InnoDB鎖的兼容性

1.如果一個事務請求的鎖模式與當前的鎖兼容,InnoDB就將請求的鎖授予該事務;否則,該事務就要等待鎖釋放。

2.意向鎖是InnoDB自動加的,不需用戶干預。對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數據集加排他鎖(X);對於普通SELECT語句,InnoDB不會加任何鎖;

3.事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。

共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE。

4.用SELECT ... LOCK IN SHARE MODE獲得共享鎖,主要用在需要數據依存關係時來確認某行記錄是否存在,並確保沒有人對這個記錄進行UPDATE或者DELETE操作。但是如果當前事 務也需要對該記錄進行更新操作,則很有可能造成死鎖,對於鎖定行記錄後需要進行更新操作的應用,應該使用SELECT... FOR UPDATE方式獲得排他鎖。

InnoDB共享鎖測試

Mysql存儲引擎InnoDB鎖原理詳解

共享鎖測試截圖

請按照圖中標識步驟去理解共享鎖(S)

InnoDB排他鎖測試

Mysql存儲引擎InnoDB鎖原理詳解

排他鎖測試截圖

請按照圖中標識步驟去理解排他鎖(X)

總結:

1.InnoDB行鎖是通過給索引上的索引項加鎖來實 現的,這一點MySQL與Oracle不同,後者是通過在數據塊中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特點意味著:只有通過索引條件檢索 數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖! 要特別注意InnoDB行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響併發性能。

2.當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會使用行鎖來對數據加鎖。(本文不再進行演示)。

3.即便在條件中使用了索引字段,但是否使用索引來檢索數據是由MySQL通過判斷不同執行計劃的代價來決定的,如果MySQL認為全表掃描效率更高,比 如對一些很小的表,它就不會使用索引,這種情況下InnoDB將使用表鎖,而不是行鎖。因此,在分析鎖衝突時,別忘了檢查SQL的執行計劃,以確認是否真 正使用了索引。

InnoDB鎖算法

Mysql存儲引擎InnoDB鎖原理詳解

InnoDB鎖算法

InnoDB所有的行鎖算法都是基於索引實現的,鎖定的也都是索引或索引區間;

不同的事務隔離級別、不同的索引類型、是否為等值查詢,使用的行鎖算法也會有所不同;下面僅以InnoDB默認的RR隔離級別、等值查詢為例,介紹幾種行鎖算法:

Mysql存儲引擎InnoDB鎖原理詳解

鎖算法

謝謝瀏覽,下一篇給大家帶來InnoDB中的MVCC(多本版併發控制)詳解。

為什麼要了解MVCC ?

MVCC的最大好處:讀不加任何鎖,讀寫不衝突,對於讀操作多於寫操作的應用,極大的增加了系統的併發性能,更容易瞭解當前讀和快照讀的區別及聯繫。


分享到:


相關文章: