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