InnoDB鎖的基本概念 文章總共分為五個部分: "InnoDB的鎖機制淺析(一)—基本概念/相容矩陣" "InnoDB的鎖機制淺析(二)—探索InnoDB中的鎖(Record鎖/Gap鎖/Next key鎖/插入意向鎖)" "InnoDB的鎖機制淺析(三)—幻讀" "InnoDB的鎖機制淺析(四) ...
InnoDB鎖的基本概念
文章總共分為五個部分:
- InnoDB的鎖機制淺析(一)—基本概念/相容矩陣
- InnoDB的鎖機制淺析(二)—探索InnoDB中的鎖(Record鎖/Gap鎖/Next-key鎖/插入意向鎖)
- InnoDB的鎖機制淺析(三)—幻讀
- InnoDB的鎖機制淺析(四)—不同SQL的加鎖狀況
- InnoDB的鎖機制淺析(五)—死鎖場景(Insert死鎖)
大而全版(五合一):InnoDB的鎖機制淺析(All in One)
1. 前言
本章的相容矩陣是後面死鎖解決的基礎。
數據事務設計遵循ACID的原則:
原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的資料庫,必須要具有這四種特性,否則在事務過程(Transaction processing)當中無法保證數據的正確性。
MySQL資料庫提供了四種預設的隔離級別,讀未提交(read-uncommitted)、讀已提交(或不可重覆讀)(read-committed)、可重覆讀(repeatable-read)、串列化(serializable)。
MySQL的預設隔離級別是RR。
2. 鎖基本概念
2.1 共用鎖和排它鎖
InnoDB實現了兩種標準行級鎖,一種是共用鎖(shared locks,S鎖),另一種是獨占鎖,或者叫排它鎖(exclusive locks,X鎖)。
S鎖允許當前持有該鎖的事務讀取行。
X鎖允許當前持有該鎖的事務更新或刪除行。
S鎖
如果事務T1持有了行r上的S鎖
,則其他事務可以同時持有行r的S鎖
,但是不能對行r加X鎖
。
X鎖
如果事務T1持有了行r上的X鎖
,則其他任何事務不能持有行r的X鎖
,必須等待T1在行r上的X鎖
釋放。
如果事務T1在行r上保持S鎖
,則另一個事務T2對行r的鎖的請求按如下方式處理:
- T2可以同時持有S鎖
- T2如果想在行r上獲取
X鎖
,必須等待其他事務對該行添加的S鎖
或X鎖
的釋放。
2.2 意向鎖-Intention Locks
InnoDB支持多種粒度的鎖,允許行級鎖和表級鎖的共存。例如LOCK TABLES ... WRITE
等語句可以在指定的表上加上獨占鎖。
InnoBD使用意向鎖來實現多個粒度級別的鎖定。意向鎖是表級鎖,表示table中的row所需要的鎖(S鎖或X鎖)的類型。
意向鎖分為意向共用鎖(IS鎖)和意向排它鎖(IX鎖)。
IS鎖表示當前事務意圖在表中的行上設置共用鎖,下麵語句執行時會首先獲取IS鎖,因為這個操作在獲取S鎖:
SELECT ... LOCK IN SHARE MODE
IX鎖表示當前事務意圖在表中的行上設置排它鎖。下麵語句執行時會首先獲取IX鎖,因為這個操作在獲取X鎖:
SELECT ... FOR UPDATE
事務要獲取某個表上的S鎖和X鎖之前,必須先分別獲取對應的IS鎖和IX鎖。
2.3 鎖的相容性
鎖的相容矩陣如下:
--- | 排它鎖(X) | 意向排它鎖(IX) | 共用鎖(S) | 意向共用鎖(IS) |
---|---|---|---|---|
排它鎖(X) | N | N | N | N |
意向排它鎖(IX) | N | OK | N | OK |
共用鎖(S) | N | N | OK | OK |
意向共用鎖(IS) | N | OK | OK | OK |
按照上面的相容性,如果不同事務之間的鎖相容,則當前加鎖事務可以持有鎖,如果有衝突則會等待其他事務的鎖釋放。
如果一個事務請求鎖時,請求的鎖與已經持有的鎖衝突而無法獲取時,互相等待就可能會產生死鎖。
意向鎖不會阻止除了全表鎖定請求之外的任何鎖請求。
意向鎖的主要目的是顯示事務正在鎖定某行或者正意圖鎖定某行。