一文搞懂MySQL?數(shù)據(jù)庫意向鎖
在本篇開始閱讀前,建議看下《MySQL數(shù)據(jù)庫 意向鎖(初篇)》章節(jié),對意向所有個(gè)大概了解。
一、用“分層鎖”的圖示理解意向鎖(核心)
InnoDB 使用的是 多粒度鎖(Multi-Granularity Locking):
數(shù)據(jù)庫
└── 表(意向鎖 IS / IX)
└── 行(S / X)規(guī)則一句話版
想鎖行,必須先在表上“打個(gè)招呼”
示例:更新一行數(shù)據(jù)
START TRANSACTION; UPDATE orders SET status = 'paid' WHERE id = 10;
鎖的實(shí)際過程是:
1?? 給 orders 表加 IX(意向排他鎖) 2?? 給 id = 10 這一行加 X(排他鎖)
?? 意向鎖 = “我打算動(dòng)你表里的某些行”
二、為什么沒有意向鎖會很慘?
假設(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(表) | 表 | 全阻塞 | 全阻塞 |
?? 重點(diǎn):
意向鎖幾乎只和“表鎖”打架,不和“行鎖”打架
四、為什么 MyISAM 不需要意向鎖?
MyISAM 的鎖模型
- ? 不支持行鎖
- ? 只有表鎖
要么整張表讀 要么整張表寫
?? 不存在:
- 行鎖
- 表鎖與行鎖并存
- 自然 不需要意向鎖
InnoDB 的優(yōu)勢(但更復(fù)雜)
| 存儲引擎 | 并發(fā) | 鎖模型 |
|---|---|---|
| MyISAM | 低 | 表鎖 |
| InnoDB | 高 | 行鎖 + 意向鎖 |
五、一個(gè)非常經(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;
此時(shí):
- A 等待表鎖釋放
- B 等待 IX 消失
?? 死鎖形成
?? InnoDB 會:
- 自動(dòng)檢測
- 回滾其中一個(gè)事務(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 自動(dòng)維護(hù)的表級鎖,用來聲明事務(wù)將對表中的某些行加行鎖,從而在加表鎖時(shí)避免掃描所有行鎖,是多粒度鎖機(jī)制的關(guān)鍵。
到此這篇關(guān)于一文搞懂MySQL 數(shù)據(jù)庫意向鎖的文章就介紹到這了,更多相關(guān)mysql 數(shù)據(jù)庫意向鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mac安裝mysql數(shù)據(jù)庫及配置環(huán)境變量的圖文教程
本文主要介紹了mac安裝mysql數(shù)據(jù)庫及配置環(huán)境變量,文中通過圖文代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
MySQL重連連接丟失:The last packet successfully 
在開發(fā)和運(yùn)維MySQL數(shù)據(jù)庫應(yīng)用時(shí),經(jīng)常會遇到“連接丟失”或“重連失敗”的問題,這類問題不僅會影響應(yīng)用程序的穩(wěn)定性,還可能導(dǎo)致數(shù)據(jù)不一致等嚴(yán)重后果,本文將探討MySQL連接丟失的原因、如何診斷此類問題以及采取哪些措施來解決或預(yù)防,需要的朋友可以參考下2025-02-02
MySQL安裝報(bào)錯(cuò)找不到MSVCR120.dll文件丟失的解決方案
文章介紹了解決MSVCR120.dll丟失問題的幾種方法,包括重新安裝Microsoft Visual C++ Redistributable、手動(dòng)下載DLL文件、運(yùn)行系統(tǒng)文件檢查工具、檢查系統(tǒng)更新以及卸載并重新安裝相關(guān)軟件2024-12-12
mysql優(yōu)化連接數(shù)防止訪問量過高的方法
這篇文章主要介紹了mysql優(yōu)化連接數(shù)防止訪問量過高的方法,需要的朋友可以參考下2014-06-06

