MySQL 鎖全解:從行鎖到死鎖,一文講透所有面試考點(diǎn)
在MySQL中,鎖是實(shí)現(xiàn)并發(fā)控制的一種機(jī)制,用于管理對數(shù)據(jù)庫中數(shù)據(jù)的訪問。MySQL支持多種類型的鎖,包括表鎖和行鎖。行鎖是較為先進(jìn)的鎖機(jī)制,因?yàn)樗试S多個(gè)事務(wù)同時(shí)對數(shù)據(jù)庫中的不同行進(jìn)行操作,從而提高并發(fā)性能。然而,如果不正確管理,即使是行鎖也可能導(dǎo)致死鎖。
行鎖
行鎖是MySQL中較為常見的一種鎖機(jī)制,它允許多個(gè)事務(wù)對不同的行進(jìn)行操作,而不會互相干擾。InnoDB存儲引擎使用行鎖來實(shí)現(xiàn)其多版本并發(fā)控制(MVCC)。
死鎖
死鎖是指兩個(gè)或多個(gè)事務(wù)在執(zhí)行過程中,因互相等待對方釋放資源而無法繼續(xù)執(zhí)行的情況。例如,事務(wù)A持有資源B并請求資源C,同時(shí)事務(wù)B持有資源C并請求資源A。
避免死鎖的策略
- 使用索引:確保涉及的所有表都有適當(dāng)?shù)乃饕?,特別是那些在WHERE子句中使用的列。
- 鎖定順序:在應(yīng)用中強(qiáng)制一致的鎖定順序。所有事務(wù)都應(yīng)該以相同的順序請求資源。例如,始終先鎖定表A再鎖定表B。
- 超時(shí)設(shè)置:設(shè)置InnoDB的
innodb_lock_wait_timeout參數(shù),該參數(shù)定義了事務(wù)等待鎖的最長時(shí)間。超過這個(gè)時(shí)間后,事務(wù)會自動回滾以避免死鎖。
- 超時(shí)設(shè)置:設(shè)置InnoDB的
- 使用樂觀鎖或悲觀鎖:
- 悲觀鎖:在事務(wù)開始時(shí)立即獲取所有需要的鎖。適用于寫操作較多的場景。
- 樂觀鎖:不使用鎖,而是在更新數(shù)據(jù)前檢查版本號或時(shí)間戳。適用于讀多寫少的場景。
- 檢測和解決死鎖:
- 使用
SHOW ENGINE INNODB STATUS命令查看死鎖日志,分析死鎖原因。 - 使用
INNODB_TRX,INNODB_LOCKS,INNODB_LOCK_WAITS表查詢當(dāng)前的事務(wù)和鎖情況。
- 使用
mysql里有哪些鎖?
在MYSQL里把鎖分為三類:全局鎖、表鎖、行級鎖
全局鎖:在使用了flush tables with read lock語句之后,全庫都會進(jìn)入只讀狀態(tài),數(shù)據(jù)庫執(zhí)行增刪改和修改表結(jié)構(gòu)的操作時(shí),都會被阻塞;主要用于在全表進(jìn)行備份時(shí),防止其他事務(wù)修改表的數(shù)據(jù)
表級鎖:
表鎖:使用lock tables語句就會給表上鎖,限制其他線程訪問這張表,這里對線程有兩種限制方式:
1.讀鎖 lock tables 表名 read
本線程:可讀,不能寫
其他線程:可讀,不能寫
2.寫鎖 lock tables 表名 write
本線程:可讀可寫
其他線程:讀寫全都阻塞
元數(shù)據(jù)鎖:對表上一個(gè)MDL鎖,如果是對表進(jìn)行CRUD操作,會對表上MDL讀鎖,如果是修改表的結(jié)構(gòu),就會對表上一個(gè)MDL寫鎖,MDL鎖的作用是防止線程在操作表時(shí),其他線程影響表的結(jié)構(gòu)和數(shù)據(jù)
意向鎖:當(dāng)執(zhí)行插入、更新、刪除操作,需要先對表加上「意向獨(dú)占鎖」,然后對該記錄加獨(dú)占鎖。意向鎖用于確定這個(gè)表是否有行級鎖
兩類意向鎖:
- 意向共享 IS:后續(xù)要加共享行鎖(S鎖)
- 意向獨(dú)占 IX:后續(xù)要加獨(dú)占行鎖(增刪改都會觸發(fā)、X鎖)
行級鎖:InnoDB 引擎是支持行級鎖的,而 MyISAM 引擎并不支持行級鎖。
記錄鎖(Record Lock):分為S讀鎖和X寫鎖,滿足讀寫互斥和寫寫互斥
| 已有鎖 | 加 S 鎖 | 加 X 鎖 |
|---|---|---|
| S 鎖 | 允許 | 阻塞 |
| X 鎖 | 阻塞 | 阻塞 |
間隙鎖(Gap Lock):只存在于可重復(fù)讀隔離級別,是為了解決可重復(fù)讀(RR)隔離級別下的幻讀現(xiàn)象。
臨鍵鎖(Next-key Lock):記錄鎖 + 間隙鎖合體,會鎖定一個(gè)范圍,并鎖定這個(gè)范圍的數(shù)據(jù)
InnoDB有哪些鎖呢:行級鎖、表鎖、意向鎖
行鎖什么時(shí)候變表鎖?
這里不是有一個(gè)升級閾值一樣的規(guī)定,所謂 “行鎖變表鎖”,是看起來像鎖表,本質(zhì)是鎖了全表所有行 / 大范圍間隙,效果等價(jià)于表鎖。
InnoDB 行鎖依托索引生效,無索引 / 索引失效時(shí)會全表掃描,行操作就會查詢?nèi)恚缓蠼o所有行加鎖效果等價(jià)于表鎖
臨鍵鎖怎么解決幻讀?
因?yàn)榕R建鎖 = 間隙鎖 + 記錄鎖,利用這兩個(gè)鎖的機(jī)制就可以大幅度的減少幻讀的發(fā)生
- 鎖住查到的真實(shí)數(shù)據(jù)行(記錄鎖) 不讓別人修改已有數(shù)據(jù)
- 鎖住數(shù)據(jù)前后的空白間隙(間隙鎖) 區(qū)間內(nèi)無法插入新記錄
- 范圍查詢會鎖定一整個(gè)左開右閉區(qū)間 別的事務(wù)插不進(jìn)區(qū)間空位,自然不會憑空多出數(shù)據(jù),大幅規(guī)避幻讀
什么是死鎖?產(chǎn)生條件、怎么排查和避免死鎖?
死鎖定義:
兩個(gè)事務(wù)互相持有對方的鎖,并且自身不會主動釋放鎖,互相陷入等待的循環(huán)就是鎖
產(chǎn)生條件:
- 互斥性:一把鎖只有一個(gè)事務(wù)可以拿到
- 請求并保持:持有鎖的同時(shí)去請求另一把鎖
- 不可剝奪:鎖不能被搶走,只能主動釋放
- 循環(huán)等待:A等B的鎖,B等A的鎖
MySQL 排查死鎖
查看最近死鎖日志
show engine innodb status;
日志里看:阻塞 SQL、持有鎖、等待鎖、事務(wù)執(zhí)行順序,定位沖突語句
避免死鎖:
- 統(tǒng)一訪問順序 :所有事務(wù)按相同順序操作表、操作行,杜絕循環(huán)等待。
- 縮小事務(wù)范圍 :事務(wù)盡量短小,盡早提交,減少鎖持有時(shí)間。
- 合理使用索引 :保證更新語句走索引,鎖定行數(shù)越少,鎖沖突越少。
- 避免事務(wù)內(nèi)等待交互 :不要事務(wù)中途等待用戶操作、接口調(diào)用,防止長時(shí)間占鎖。
總結(jié):
主要是了解了mysql里面所有的鎖的定義,行鎖與表鎖并不是字面意思上的轉(zhuǎn)換,而是效果上在全盤掃描時(shí)實(shí)現(xiàn)了鎖全表的現(xiàn)象,臨鍵鎖解決幻讀,從臨鍵鎖的組成來分為鎖數(shù)據(jù)(記錄鎖)和鎖數(shù)據(jù)前后的空白間隙(間隙鎖),以及死鎖的相關(guān)知識。
到此這篇關(guān)于MySQL 鎖全解:從行鎖到死鎖,一文講透所有面試考點(diǎn)的文章就介紹到這了,更多相關(guān)mysql行鎖到死鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL UPDATE 語句一個(gè)“經(jīng)典”的坑
這篇文章主要介紹了MySQL UPDATE 語句一個(gè)“經(jīng)典”的坑,一個(gè)非常有意思的話題,感興趣的小伙伴可以參考下面文章的具體內(nèi)容哦2021-10-10
MySQL不可忽視的數(shù)據(jù)庫約束(維護(hù)數(shù)據(jù)秩序)
數(shù)據(jù)庫約束是數(shù)據(jù)庫管理中不可或缺的一部分,它們在維護(hù)數(shù)據(jù)秩序、保證數(shù)據(jù)完整性和一致性方面發(fā)揮著重要作用,本文給大家介紹MySQL不可忽視的數(shù)據(jù)庫約束,感興趣的朋友一起看看吧2025-05-05
MySQL不使用order by實(shí)現(xiàn)排名的三種思路總結(jié)
ORDER BY語句用于根據(jù)指定的列對結(jié)果集進(jìn)行排序,在日常開發(fā)中也經(jīng)常會用到,但下面這篇文章主要給大家介紹了關(guān)于MySQL不使用order by實(shí)現(xiàn)排名的三種思路,需要的朋友可以參考下2021-06-06
MySQL中使用auto_increment修改初始值和步長
本文主要介紹了MySQL中使用auto_increment修改初始值和步長,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
MySQL 格式化時(shí)間的實(shí)現(xiàn)示例
MySQL提供了多種日期和時(shí)間類型,在處理時(shí)間時(shí)需要根據(jù)不同類型選擇不同的格式化方法,常用的日期類型有DATE、YEAR、TIME;常用的日期時(shí)間類型有DATETIME和TIMESTAMP,本文就來介紹一下MySQL 格式化時(shí)間,感興趣的可以了解一下2023-10-10
Mysql服務(wù)器的安裝配置與啟動關(guān)閉方法詳解
MySQL 是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在 WEB 應(yīng)用方面 MySQL 是最好的 RDBMS(Relational Database Management System:關(guān)系數(shù)據(jù)庫管理系統(tǒng))應(yīng)用軟件之一2021-10-10

