mysql數(shù)據(jù)庫中各種鎖歸納總結(jié)
一、引言
在現(xiàn)代應(yīng)用程序中,數(shù)據(jù)庫是不可或缺的組成部分之一。而MySQL作為一款開源的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),廣泛應(yīng)用于各種規(guī)模的應(yīng)用中。然而,在高并發(fā)的情況下,數(shù)據(jù)庫的性能往往成為瓶頸,因此數(shù)據(jù)庫鎖機制成為了至關(guān)重要的技術(shù)。本文將深入探討MySQL中的各種鎖,包括行鎖、表鎖、頁鎖等,以及如何使用它們來提高數(shù)據(jù)庫的性能。
二、鎖分類
從對數(shù)據(jù)操作的粒度來分:
表鎖:操作時會鎖定整個表
行鎖:操作時會鎖定當(dāng)前操作行
從對數(shù)據(jù)操作的類型分:
讀鎖(共享鎖):針對同一個份數(shù)據(jù),多個讀操作可以同時進行而不會互相影響
寫鎖(排它鎖):當(dāng)前操作沒有完成之前,它會阻斷其他寫鎖和讀鎖
三、Mysql鎖
mysql鎖的特性:
表級鎖
偏向MyISAM存儲引擎,開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低
行級鎖
偏向InnoDB存儲引擎,開銷小,加鎖慢;會出現(xiàn)死鎖;鎖定粒度小,發(fā)生鎖沖突的概率最低,并發(fā)度最高
頁面鎖
開鎖和加鎖時間介于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度介于表鎖和行鎖之間,并發(fā)度一般
四、MyISAM表鎖
MyISAM在執(zhí)行查詢語句(SELECT)前會自動給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT)前,會自動給涉及的表加寫鎖,這個過程并不需要用戶干預(yù),因此,用戶一般不需要直接用 LOCK TABLE 命令給MyISAM表顯式加鎖。
顯式加鎖語法:
lock table table_name read; lock table table_name write; unlock tables;
MyISAM表的讀操作不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫操作 MyISAM表的寫操作會阻塞其他用戶對同一表的讀和寫操作 MyISAM的讀寫鎖調(diào)度是優(yōu)先寫,這也是MyISAM不適合作寫為主的表的存儲引擎原因。因為寫鎖后,其他線程不能做任何操作,大量的更新會使查詢很難得到鎖,從而造成永遠阻塞
查看鎖爭用情況:
show open tables; show status like 'Table_locks%';
五、InnoDB鎖
兩種類型的行鎖共享鎖(S)
又稱讀鎖,簡稱S鎖,共享鎖就是多個事務(wù)對于同一數(shù)據(jù)可以共享一把鎖,都能訪問到數(shù)據(jù),但是只能讀不能修改
排它鎖(X)
又稱寫鎖,簡稱X鎖,排他鎖就是不能與其他鎖并存,如一個事務(wù)獲取了一個數(shù)據(jù)行的排它鎖,其他事務(wù)就不能再獲取改行的其他鎖,包括共享鎖和排它鎖,但是獲取排它鎖的事務(wù)是可以對數(shù)據(jù)行讀取和修改
加鎖語句:
select * from table_name where … LOCK IN SHARE MODE select * from table_name where… FOR UPDATE
TIPS:
對于UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數(shù)據(jù)集加排它鎖
對于普通SELECT語句,InnnoDB不會加任何鎖
無索引行鎖升級為表鎖執(zhí)行更新時,如果where條件沒有索引 或 寫法不當(dāng)導(dǎo)致索引失效(例如:隱式轉(zhuǎn)換),最終行鎖變?yōu)楸礞i
-- name 類型為varchar(16) update test_innodb_lock set sex='2' where name = 400;
六、間隙鎖
當(dāng)我們用范圍條件而不是使用相等條件檢索數(shù)據(jù),并請求共享或排它鎖時,InnoDB會給符合條件的已有數(shù)據(jù)進行加鎖;對于鍵值在條件范圍內(nèi)但不存在的記錄,叫做“間隙(GAP)",InnoDB也會對這個”間隙“加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)
update test_innodb_lock set sex = '0' where id < 4;
另一個事務(wù)如果執(zhí)行下面語句時,會被阻塞
insert into test_innodb_lock values(2, '200', '1');
行鎖爭用情況
show status like 'innodb_row_lock%';
- Innodb_row_lock_current_waits:當(dāng)前正在等待鎖定的數(shù)量
- Innodb_row_lock_time:從系統(tǒng)啟動到現(xiàn)在鎖定總時間長度
- Innodb_row_lock_time_avg:每次等待所花平均時長
- Innodb_row_lock_time_max:從系統(tǒng)啟動到現(xiàn)在等待最長的一次所花的時間
- Innodb_row_lock_waits:系統(tǒng)啟動后到現(xiàn)在總共等待的次數(shù)
七、總結(jié)
InnoDB存儲引擎由于實現(xiàn)了行級鎖定,雖然在鎖定機制的實現(xiàn)方面帶來了性能損耗可能比表鎖會更高一些,但是在整體并發(fā)處理能力方面要遠遠優(yōu)于MyISAM的表鎖的。當(dāng)系統(tǒng)并發(fā)量較高的時候,InnoDB的整體性能和MyISAM相比就會有比較明顯的優(yōu)勢
但是,InnoDB的行級鎖同樣也有其脆弱的一面,當(dāng)我們使用不當(dāng)?shù)臅r候,可能會讓InnoDB的整體性能表現(xiàn)不僅不能比MyISAM高,甚至可能會更差
優(yōu)化建議:
盡可能讓所有數(shù)據(jù)檢索都能通過索引來完成,避免無索引行鎖升級為表鎖
合理設(shè)計索引,盡量縮小鎖的范圍
盡可能減少索引條件及索引范圍,避免間隙鎖
盡量控制事務(wù)大小,減少鎖定資源量和時間長度
盡可使用低級別事務(wù)隔離(需要業(yè)務(wù)層面滿足需求)
到此這篇關(guān)于mysql數(shù)據(jù)庫中各種鎖歸納的文章就介紹到這了,更多相關(guān)mysql各種鎖總結(jié)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL中TIMESTAMP類型返回日期時間數(shù)據(jù)中帶有T的解決
這篇文章主要介紹了MySQL中TIMESTAMP類型返回日期時間數(shù)據(jù)中帶有T的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12基于mysql事務(wù)、視圖、存儲過程、觸發(fā)器的應(yīng)用分析
本篇文章是對mysql事務(wù)、視圖、存儲過程、觸發(fā)器的應(yīng)用進行了詳細的分析介紹,需要的朋友參考下2013-05-05Navicat連接遠程服務(wù)器里docker中mysql的方法(已解決)
相信大家都有在遠程服務(wù)器上進行開發(fā)吧,其中MySQL的使用率應(yīng)該也會挺高,這篇文章主要給大家介紹了關(guān)于Navicat連接遠程服務(wù)器里docker中mysql的相關(guān)資料,需要的朋友可以參考下2024-04-04MySQL InnoDB架構(gòu)的相關(guān)總結(jié)
InnoDB存儲引擎架構(gòu)作為MySQL最常用的存儲引擎,每個后端程序員都應(yīng)有所了解,本文將具體講述MySQL InnoDB架構(gòu)的相關(guān)知識,感興趣的朋友可以參考下2021-05-05mysql8.0數(shù)據(jù)庫無法被遠程連接問題排查小結(jié)
本文主要介紹了mysql8.0數(shù)據(jù)庫無法被遠程連接問題排查小結(jié)2024-07-07