深入理解mysql各種鎖
鎖的概述
鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并訪問(wèn)某一資源的機(jī)制
在數(shù)據(jù)庫(kù)中,除傳統(tǒng)的計(jì)算機(jī)資源(如cpu、RAM、I/O等)的爭(zhēng)用以外,數(shù)據(jù)也是一種供許多用戶(hù)共享的資源,如果保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性,有效性是所有數(shù)據(jù)庫(kù)必須解決的一個(gè)問(wèn)題,鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)性能的一個(gè)重要因素,從這個(gè)角度來(lái)說(shuō),鎖對(duì)數(shù)據(jù)庫(kù)而言顯得尤其重要,也更加復(fù)雜
鎖分類(lèi)
對(duì)數(shù)據(jù)庫(kù)操作的粒度分
表鎖: 操作時(shí),會(huì)鎖定整個(gè)表 行鎖: 操作時(shí),會(huì)鎖定當(dāng)前操作行
對(duì)數(shù)據(jù)操作的類(lèi)型分
讀鎖(共享鎖): 針對(duì)同一份數(shù)據(jù),多個(gè)讀操作可以同時(shí)進(jìn)行而不會(huì)相互影響 寫(xiě)鎖(排它鎖): 當(dāng)操作沒(méi)有完成之前,它會(huì)阻斷其他寫(xiě)鎖和讀鎖
mysql鎖
相對(duì)其他數(shù)據(jù)庫(kù)而言,Mysql的鎖機(jī)制比較簡(jiǎn)單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制。
不同存儲(chǔ)引擎支持鎖級(jí)別
存儲(chǔ)引擎 | 表級(jí)鎖 | 行級(jí)鎖 | 頁(yè)面鎖 |
---|---|---|---|
MyISAM | 支持 | 不支持 | 不支持 |
InnoDB | 支持 | 支持 | 不支持 |
MEMORY | 支持 | 不支持 | 不支持 |
BDB | 支持 | 不支持 | 支持 |
鎖介紹
很難籠統(tǒng)說(shuō)哪種鎖更好,需要根據(jù)特定的應(yīng)用場(chǎng)景來(lái)分析哪種鎖更合適。
鎖類(lèi)型 | 特點(diǎn) |
---|---|
表級(jí)鎖 | 偏向MyISAM存儲(chǔ)引擎,開(kāi)銷(xiāo)小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)送鎖沖突的概率最高,并發(fā)度最低。 |
行級(jí)鎖 | 偏向InnoDB存儲(chǔ)引擎,開(kāi)銷(xiāo)大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。 |
頁(yè)面鎖 | 開(kāi)銷(xiāo)和加鎖時(shí)間介于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度介于表鎖和行鎖之間,并發(fā)度一般。 |
MyISAM表鎖
如何添加表鎖
MyISAM在執(zhí)行查詢(xún)語(yǔ)句(select)前,會(huì)自動(dòng)給涉的所有表加鎖,在執(zhí)行更新操作(update、delete、insert等)前,會(huì)自動(dòng)給涉及的表加寫(xiě)鎖,這個(gè)過(guò)程并不需要用戶(hù)干預(yù),因此,用戶(hù)一般不需要直接使用LOCK TABLE命令給MyISAM表顯示加鎖
加解鎖
加讀鎖: lock table table_name read; ---解鎖 unlock tables; 加寫(xiě)鎖: lock table table_name write; 添加寫(xiě)鎖當(dāng)前會(huì)話可以讀寫(xiě)操作,別的會(huì)話會(huì)處于阻塞(等待)狀態(tài) 讀鎖限制寫(xiě),寫(xiě)鎖限制讀寫(xiě)
鎖競(jìng)爭(zhēng)
1、對(duì)MyISAM表的讀操作,不會(huì)阻塞其他用戶(hù)對(duì)同一表的讀請(qǐng)求,但會(huì)阻塞對(duì)同一表的寫(xiě)請(qǐng)求; 2、對(duì)MyISAM的寫(xiě)操作,則會(huì)阻塞其他用戶(hù)對(duì)表一表的讀和寫(xiě)操作; 3、MyISAM鎖調(diào)度是寫(xiě)優(yōu)先。 不適合作為主表,寫(xiě)鎖后其他線程大量的更新會(huì)使查詢(xún)很難得到鎖,可能會(huì)造成永遠(yuǎn)阻塞。
鎖的使用情況
查看鎖的使用情況 show open tables; 查看表的鎖定情況 show status like 'table_locks%'; Table_locks_immediate:可以獲取表級(jí)鎖的次數(shù),每立即獲取鎖,值加1 Table_locks_waited:不能立即獲取鎖需要等待的次數(shù),每等待一次,值加1,可以判斷比較嚴(yán)重的表級(jí)鎖爭(zhēng)用情況
InnoDB鎖
InnoDB與MyISAM的最大不同有亮點(diǎn):一是支持事務(wù);二是采用行級(jí)鎖
行鎖
共享鎖: 又稱(chēng)讀鎖,多個(gè)事務(wù)可以共享一把鎖,但是只能讀,不能寫(xiě) 排它鎖: 又稱(chēng)寫(xiě)鎖,鎖不共用,獲取不到鎖的事務(wù)不能進(jìn)行讀寫(xiě)操作 如果進(jìn)行update、delete和insert 語(yǔ)句,innoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排它鎖 對(duì)不同的select語(yǔ)句不會(huì)添加任何鎖 顯示的給查詢(xún)添加鎖 添加共享鎖: select * from table_name where ... Lock IN SHARE MODE 添加排它鎖: select * from table_name where ... FOR UPDATE
鎖升級(jí)
索引失效,行鎖升級(jí)表鎖 where后面沒(méi)索引也升級(jí)為表鎖
間隙鎖
InnoDB會(huì)對(duì)間隙不存在的數(shù)據(jù)也會(huì)加鎖,稱(chēng)之為間隙鎖
鎖爭(zhēng)用
show status like 'innodb_row_lock%'; Innodb_row_lock_current_waits當(dāng)前正在等待鎖的數(shù)量 Innodb_row_lock_time 鎖定的總時(shí)長(zhǎng) Innodb_row_lock_time_avg 鎖定的平均時(shí)長(zhǎng) Innodb_row_lock_time_max 鎖定的最大時(shí)長(zhǎng) Innodb_row_lock_waits 系統(tǒng)啟動(dòng)到現(xiàn)在總共等待次數(shù)
總結(jié)
innoDB存儲(chǔ)引擎實(shí)現(xiàn)了行鎖,雖然鎖定機(jī)制的實(shí)現(xiàn)方面帶來(lái)了性能消耗可能比較表鎖會(huì)更高些,但是在整體并發(fā)處理能力方面要遠(yuǎn)優(yōu)于MyISAM表鎖,當(dāng)系統(tǒng)并發(fā)比較高的時(shí)候,InnoDB的整體性能和MyISAM會(huì)有比較明顯的優(yōu)勢(shì)
優(yōu)化建議
盡可能讓所有數(shù)據(jù)檢索都能通過(guò)索引來(lái)完成,避免無(wú)索引行鎖升級(jí)為表鎖 合理設(shè)計(jì)索引,盡量縮小鎖的范圍 盡可能減少索引條件,及索引范圍,避免間隙鎖 盡量控制事務(wù)大小,減少鎖定資源量和時(shí)間的長(zhǎng)度 盡可能使用低級(jí)別事務(wù)隔離(需要業(yè)務(wù)能滿(mǎn)足需求)
到此這篇關(guān)于深入理解mysql各種鎖的文章就介紹到這了,更多相關(guān)mysql鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
windows下mysql 8.0.15 詳細(xì)安裝使用教程
這篇文章主要為大家詳細(xì)介紹了windows下mysql 8.0.15 詳細(xì)安裝使用教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08mysql性能監(jiān)控工具Innotop簡(jiǎn)介及配置
INNOTOP是一個(gè)通過(guò)文本模式顯示MySQL和InnoDB的監(jiān)測(cè)工具。INNOTOP是用PERL語(yǔ)言寫(xiě)成的,這使它能更加靈活的使用在各種操作平臺(tái)之上,它能詳細(xì)的的監(jiān)控出當(dāng)前MYSQL和INNODB運(yùn)行的狀態(tài),以DBA根據(jù)結(jié)果,可以合理的優(yōu)化MYSQL,讓MYSQL更穩(wěn)定更高效的運(yùn)行。2014-08-08解析SQL Server 視圖、數(shù)據(jù)庫(kù)快照
在程序開(kāi)發(fā)過(guò)程中,任何一個(gè)項(xiàng)目都離不開(kāi)數(shù)據(jù)庫(kù),這篇文章給大家詳細(xì)介紹SQL Server 視圖、數(shù)據(jù)庫(kù)快照相關(guān)內(nèi)容,需要的朋友可以參考下2015-08-08千萬(wàn)級(jí)用戶(hù)系統(tǒng)SQL調(diào)優(yōu)實(shí)戰(zhàn)分享
這篇文章主要介紹了千萬(wàn)級(jí)用戶(hù)系統(tǒng)SQL調(diào)優(yōu)實(shí)戰(zhàn)分享,用戶(hù)日活百萬(wàn)級(jí),注冊(cè)用戶(hù)千萬(wàn)級(jí),而且若還沒(méi)有進(jìn)行分庫(kù)分表,則該DB里的用戶(hù)表可能就一張,單表上千萬(wàn)的用戶(hù)數(shù)據(jù),下面我們就來(lái)學(xué)習(xí)如何讓優(yōu)化,需要的朋友可以參考一下2022-03-03MYSQL數(shù)據(jù)庫(kù)表結(jié)構(gòu)優(yōu)化方法詳解
這篇文章主要介紹了MYSQL數(shù)據(jù)庫(kù)表結(jié)構(gòu)優(yōu)化方法,總結(jié)分析了mysql針對(duì)表結(jié)構(gòu)優(yōu)化的數(shù)據(jù)類(lèi)型選擇、范式化操作、表的拆分等相關(guān)使用技巧,需要的朋友可以參考下2019-08-08mysql 如何使用JSON_EXTRACT() 取json值
這篇文章主要介紹了mysql如何使用JSON_EXTRACT() 取json值的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07