MySQL各種加鎖案例分析
目錄
InnoDB鎖型別
InnoDB Lock Types
❖Shared and Exclusive Locks
❖Intention Locks
❖Record Locks
❖Gap Locks
❖Next-Key Locks
❖Insert Intention Locks
❖Auto-inc Locks
❖ Predicate Locks for Spatial Index(忽略)
InnoDB - S&X Locks
❖Row-Level Locking
❖S Locks (shared locks)
✓A shared (S) lock permits the transaction that holds the lock to read a row
✓Example: select * from xx where a=1 lock in share mode
❖X Locks ( Exclusive Locks)
✓An exclusive (X) lock permits the transaction that holds the lock to update or delete a row.
✓Example:select * from xx where a=1 for update
❖S 和 S 相容, X 和 S 互斥, X和X互斥
InnoDB - S&X Locks舉例例
❖select * from t where i=1 lock in share mode
❖select * from t where i=1 for update
插⼊入篇:如何檢視SQL加鎖資訊
❖進⾏如下設定可以看到此SQL持有鎖資訊
✓SET GLOBAL innodb_status_output=ON;
✓SET GLOBAL innodb_status_output_locks=ON;
✓5.6.16版本引⼊此引數,影響效能,線上慎開
插⼊入篇:檢視SQL加鎖資訊
InnoDB - Intention Locks
❖InnoDB⽀持多粒度鎖,允許⾏鎖和表鎖並存
❖Table-Level Locks
❖Intention shared Lock(IS) 意味著事務需要在表的⾏上⾯新增S鎖,因此獲取S鎖之前需要獲取IS鎖
❖ Intention exclusive Lock(IX)意味著事務需要在表的⾏上⾯新增X鎖,因此獲取X鎖之前需要獲取IX鎖
InnoDB - 相容性
InnoDB - Record Locks
❖記錄鎖是對索引加鎖,⽽不是具體的資料⾏
❖即使表沒有定義索引,InnoDB產⽣隱藏聚簇索引⽤於加鎖
InnoDB - Gap Locks
❖A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
❖A gap might span a single index value, multiple indexvalues, or even be empty.
❖Gap可能通過設定Read-Commited以及innodb_locks_unsafe_for_binlog進⾏顯⽰關閉
InnoDB - Next-Key Locks
❖A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
❖InnoDB 預設的事務隔離級別是REPEATABLE READ
❖在RR模式下, InnoDB 使⽤ next-key locks 防⽌幻讀
InnoDB - Next-Key Locks舉例例1
InnoDB - Next-Key Locks舉例例2
InnoDB - Insert Intention Locks
❖An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion.
InnoDB - Insert Intention Locks
InnoDB - AUTO-INC Locks
❖特殊的table-level lock
❖持有時間在當前sql執⾏完成就釋放,⽽不是事務結束後才釋放
❖通過引數innodb_autoinc_lock_mode控制,具體有三種模式:
AUTOINC_OLD_STYLE_LOCKING (0)
AUTOINC_NEW_STYLE_LOCKING (1) 保證Id連續,預設
AUTOINC_NO_LOCKING (2)
InnoDB - AUTO-INC Locks
AUTOINC_OLD_STYLE_LOCKING(0)
1)在分⽚片前加上AUTO_INC鎖,並在SQL結束時釋放掉
AUTOINC_NO_LOCKING (2)
1)只在分配時加個mutex即可很快就釋放
2)在statement格式下不不能保證批量量插⼊入的複製安全性
InnoDB MVCC
資料庫併發控制協議
1、基於鎖的協議 (Lock Based Protocol)
2、基於多版本機制 (Multi-version Protocol)
3、基於時間的協議 (Time-Stamp Ordering Protocol)
4、基於圖的協議 (Graph Based Protocol)
5、基於多粒度協議 (Multiple Granularity Protocol)
MVCC
❖多版本控制
❖相對於基於鎖的協議,MVCC最⼤好處:讀不加鎖,讀寫不衝突
❖讀操作
✓快照讀(snapshot read)
✓當前讀(current read)
快照讀和當前讀
❖快照讀:簡單select操作,不加鎖
❖select * from table where ?
❖ 當前讀: 特殊讀操作,插⼊/更新/刪除,需要加鎖
❖select * from table where ? lock in share mode
❖select * from table where ? for update
❖insert into table values (…)
❖delete from table where ?
❖update table set ? where ?
InnoDB MVCC實現關鍵點
❖ROW記錄格式
❖ROW和Undo關係
❖ReadView判斷
InnoDB MVCC實現原理理-Row格式
實際上還有⼀個欄位DB_ROW_ID,只出現在聚簇索引中
InnoDB MVCC實現原理理-Row和Undo
❖通過回滾段實現多個版本的讀取
InnoDB MVCC實現原理理-Read View
InnoDB MVCC實現原理理-可⻅見性判斷
事務隔離級別
讀現象問題
❖丟失更新 (事務ACID保證不會發⽣)
❖髒讀
❖不可重複讀
❖幻讀
事務隔離級別
❖Read Uncommitted
✓可以讀取未提交的事務,此隔離級別不會使⽤。
❖Read committed (RC)
✓針對當前讀,RC隔離級別保證對讀取到的記錄加鎖(⾏鎖),存在幻讀現象。
❖Repeatable Read(RR)
✓針對當前讀,RR保證對讀取到的記錄加鎖(⾏鎖),同時保證對讀取的範圍加鎖,新的滿⾜查詢條件的記錄不能夠插⼊(Next-Key Locks),不存在幻讀現象。
❖Serializable
✓從MVCC併發控制退化為基於鎖的併發控制。所有的讀操作都為當前讀,讀加讀鎖(S鎖),寫加寫鎖(X鎖)。Serializable隔離級別下,讀寫衝突,併發度急劇下降。
讀現象和事務隔離級別舉例例
讀現象舉例例-髒讀
❖髒讀:當⼀個事務允許讀取另⼀個事務修改但未提交的資料時,就可能發⽣髒讀。
讀現象舉例例-不不可重複讀
❖不可重複讀:在⼀次事務中,當⼀⾏資料獲取兩遍得到不同的結果表⽰發⽣了“不可重複讀”
讀現象舉例例-幻讀
❖ 幻讀:不可重複讀的⼀種特殊場景。當事務1兩次執⾏SELECT ... WHERE檢索⼀定範圍內資料的操作中間,事務2在這個表中建立了(如INSERT)⼀⾏新資料,這條新資料正好滿⾜事務1的“WHERE”⼦句。
標準事務隔離級別
❖標準事務隔離級別中RR沒有解決幻讀問題。
InnoDB在RR模式解決幻讀問題舉例例
SQL加鎖分析
❖簡單SQL加鎖分析
❖複雜SQL加鎖分析
❖常見SQL加鎖總結
Update操作加鎖流程
2PL:Two-Phase Locking
一條簡單SQL的加鎖分析-問題
❖SQL1:select * from t1 where id = 10
✓MVCC多版本控制,Select 快照讀,不加鎖
❖SQL2: delete from t1 where id = 10
一條簡單SQL的加鎖分析-前提條件
❖前提⼀:id列是不是主鍵?
❖前提⼆:當前系統的事務隔離級別是什麼?
❖前提三:id列如果不是主鍵,那麼id列上是否有索引嗎?
❖前提四:id列上如果有⼆級索引,那麼這個索引是唯⼀索引嗎?
❖前提五:SQL的執⾏計劃是什麼?索引掃描?全表掃描?
SQL加鎖分析前提場景
❖組合⼀:id列是主鍵,RC事務隔離級別
❖組合⼆:id列是⼆級唯⼀索引,RC事務隔離級別
❖組合三:id列是⼆級⾮唯⼀索引,RC事務隔離級別
❖組合四:id列上沒有索引,RC事務隔離級別
❖組合五:id列是主鍵,RR事務隔離級別
❖組合六:id列是⼆級唯⼀索引,RR事務隔離級別
❖組合七:id列是⼆級⾮唯⼀索引,RR事務隔離級別
❖組合⼋:id列上沒有索引,RR事務隔離級別
❖組合九:Serializable事務隔離級別
組合⼀一:id主鍵+RC
組合⼆二:id唯⼀一索引+RC
複雜SQL加鎖規則