一文搞懂MySQL?數(shù)據(jù)庫意向鎖
在本篇開始閱讀前,建議看下《MySQL數(shù)據(jù)庫 意向鎖(初篇)》章節(jié),對意向所有個大概了解。
一、用“分層鎖”的圖示理解意向鎖(核心)
InnoDB 使用的是 多粒度鎖(Multi-Granularity Locking):
數(shù)據(jù)庫
└── 表(意向鎖 IS / IX)
└── 行(S / X)規(guī)則一句話版
想鎖行,必須先在表上“打個招呼”
示例:更新一行數(shù)據(jù)
START TRANSACTION; UPDATE orders SET status = 'paid' WHERE id = 10;
鎖的實際過程是:
1?? 給 orders 表加 IX(意向排他鎖) 2?? 給 id = 10 這一行加 X(排他鎖)
?? 意向鎖 = “我打算動你表里的某些行”
二、為什么沒有意向鎖會很慘?
假設(shè):沒有意向鎖
- 表
orders有 1000 萬行 - 事務(wù) A:更新其中 1 行
- 事務(wù) B:想加表鎖
LOCK TABLE orders WRITE;
?? MySQL 只能:
- 掃描 1000 萬行
- 看看有沒有行鎖
為此,就會引發(fā):?? 性能災(zāi)難
有了意向鎖之后
| 操作 | 檢查內(nèi)容 |
|---|---|
| 行鎖 | 不管表鎖 |
| 表鎖 | 只看 IS / IX |
?? O(1) 判斷是否沖突
三、意向鎖 vs 表鎖 vs 行鎖(對比表)
| 鎖類型 | 級別 | 是否阻塞行鎖 | 是否阻塞表鎖 |
|---|---|---|---|
| IS | 表 | ? | 阻塞表 X |
| IX | 表 | ? | 阻塞表 S / X |
| S | 行 | 行級互斥 | — |
| X | 行 | 行級互斥 | — |
| S(表) | 表 | 阻塞 IX | 阻塞 X |
| X(表) | 表 | 全阻塞 | 全阻塞 |
?? 重點:
意向鎖幾乎只和“表鎖”打架,不和“行鎖”打架
四、為什么 MyISAM 不需要意向鎖?
MyISAM 的鎖模型
- ? 不支持行鎖
- ? 只有表鎖
要么整張表讀 要么整張表寫
?? 不存在:
- 行鎖
- 表鎖與行鎖并存
- 自然 不需要意向鎖
InnoDB 的優(yōu)勢(但更復(fù)雜)
| 存儲引擎 | 并發(fā) | 鎖模型 |
|---|---|---|
| MyISAM | 低 | 表鎖 |
| InnoDB | 高 | 行鎖 + 意向鎖 |
五、一個非常經(jīng)典的死鎖場景(面試??迹?/h2>
場景描述
表 user:
| id | name |
|---|---|
| 1 | A |
| 2 | B |
事務(wù) A
START TRANSACTION; SELECT * FROM user WHERE id = 1 FOR UPDATE;
鎖狀態(tài):
user 表:IX id=1 行:X
事務(wù) B
START TRANSACTION; LOCK TABLE user WRITE;
B 想要:
user 表:X
? 但被 A 的 IX 阻塞
接著事務(wù) A 再做:
SELECT * FROM user WHERE id = 2 FOR UPDATE;
此時:
- A 等待表鎖釋放
- B 等待 IX 消失
?? 死鎖形成
?? InnoDB 會:
- 自動檢測
- 回滾其中一個事務(wù)
六、如何在生產(chǎn)中“看到”意向鎖?
1?? 查看當(dāng)前鎖(MySQL 8.0)
SELECT * FROM performance_schema.data_locks;
你會看到類似:
OBJECT_NAME = orders LOCK_TYPE = TABLE LOCK_MODE = IX
2?? 常見 LOCK_MODE 含義
| LOCK_MODE | 含義 |
|---|---|
| IS | 意向共享 |
| IX | 意向排他 |
| S | 共享 |
| X | 排他 |
七、一句話總結(jié)
意向鎖是 InnoDB 自動維護(hù)的表級鎖,用來聲明事務(wù)將對表中的某些行加行鎖,從而在加表鎖時避免掃描所有行鎖,是多粒度鎖機(jī)制的關(guān)鍵。
到此這篇關(guān)于一文搞懂MySQL 數(shù)據(jù)庫意向鎖的文章就介紹到這了,更多相關(guān)mysql 數(shù)據(jù)庫意向鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql安裝與配置調(diào)優(yōu)及修改root密碼的方法
這篇文章給大家介紹了Mysql安裝與配置調(diào)優(yōu),然后在文中給大家提到了mysql修改root密碼的多種方法,需要的的朋友參考下吧2017-07-07
探討:sql插入空,默認(rèn)1900-01-01 00:00:00.000的解決方法詳解
本篇文章是對sql插入空,默認(rèn)1900-01-01 00:00:00.000的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
MySQL DATE_SUB()函數(shù)的實現(xiàn)示例
本文主要介紹了MySQL DATE_SUB() 函數(shù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03

