今天我們就來學習一下加鎖規則吧。
在學習前要說明一點,以下的規則只限於版本範圍:5.x系列<=5.7.24,8.0系列<=8.0.13。
這個加鎖規則包含兩個「原則」、兩個「優化」和乙個「bug」。
原則1:加鎖的基本單位是next-key lock。希望你還記得,next-key lock是前開後閉區間。
原則2:查詢過程中訪問到的物件才會加鎖。
優化1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock退化為行鎖。
優化2:索引上的等值查詢,向右遍歷時且最後乙個值不滿足等值條件的時候,next-key lock退化為間隙鎖。
乙個bug:唯一索引上的範圍查詢會訪問到不滿足條件的第乙個值為止。
下面以表t為例來介紹一下這些規則。表t的建表語句和初始化語句如下。
圖1 等值查詢間隙鎖
分析:
結論:
圖2 非唯一索引等值鎖
分析:
結論:
圖3 主鍵索引範圍鎖
分析:
因此加鎖id=15的行鎖和id的next-key lock(10, 15]
結論:
圖4 非唯一索引範圍鎖
分析:
因此加鎖索引c (5, 10]和(10, 15]
結論:
圖5 唯一索引範圍鎖bug
分析:
因此加鎖為(10, 15]和(15, 20]
結論:
圖6 非唯一索引上存在"等值"的例子
分析:
因此加鎖(c=5,id=5)到(c=10,id=10)這個next-key lock和(c=10,id=10)到(c=15,id=15)這個間隙鎖
結論:
先插入一條記錄。
圖7 limit 語句加鎖
分析:
因此加鎖c (5, 10)和兩個行鎖(id=10和id=30)
結論:
說明:這個例子對我們實踐的指導意義就是,在刪除資料的時候盡量加limit。
這個案例的目的是說明:next-key lock實際上是間隙鎖和行鎖加起來的結果。
圖8 乙個死鎖的例子
分析:
結論:
說明:next-key lock具體執行的時候,是要分成間隙鎖和行鎖兩段來執行的。
圖9 非唯一索引排序範圍鎖
分析:
在掃瞄過程中,c=20、c=15、c=10這三行都存在值,由於是select *,所以會在主鍵id上加三個行鎖。
因此要加鎖索引c (5, 25)和三個行鎖(id=10,id=15,id=20)。
結論:
begin;
select * from t where id>9 and id<12 order by id desc for update;
在執行過程中,通過樹搜尋的方式定位記錄的時候,用的是「等值查詢」的方法。
分析:
begin;
select id from t where c in(5,20,10) lock in share mode;
分析:說明:鎖是逐個逐個加的。
間隙鎖是不互斥的,因為加鎖範圍是(0, 25),除c=15外。
mysql行鎖表鎖區別 mysql表鎖和行鎖區別
一 表鎖 特點 偏向myisam儲存引擎,開銷小,加鎖快 無死鎖 鎖定粒度大,發生鎖衝突的概率最高,併發度最低。我們在編輯表,或者執行修改表的事情了語句的時候,一般都會給表加上表鎖,可以避免一些不同步的事情出現,表鎖分為兩種,一種是讀鎖,一種是寫鎖。我們可以手動給表加上這兩種鎖,語句是 lock t...
mysql行鎖和表鎖
在呼叫儲存過程中,就會涉及到表鎖,行鎖這一概念 所謂區別 有索引的時候就是行鎖,沒有索引的時候就是表索。innodb 的行鎖是在有索引的情況下,沒有索引的表是鎖定全表的.表鎖演示 無索引 session1 mysql set autocommit 0 mysql select from innodb...
mysql行鎖和表鎖
在呼叫儲存過程中,就會涉及到表鎖,行鎖這一概念 所謂區別 有索引的時候就是行鎖,沒有索引的時候就是表索。innodb 的行鎖是在有索引的情況下,沒有索引的表是鎖定全表的.表鎖演示 無索引 session1 mysql set autocommit 0 mysql select from innodb...