深入理解mysql各種鎖
鎖的概述
鎖是計算機協調多個進程或線程並訪問某一資源的機制
在數據庫中,除傳統的計算機資源(如cpu、RAM、I/O等)的爭用以外,數據也是一種供許多用戶共享的資源,如果保證數據並發訪問的一致性,有效性是所有數據庫必須解決的一個問題,鎖沖突也是影響數據庫並發訪問性能的一個重要因素,從這個角度來說,鎖對數據庫而言顯得尤其重要,也更加復雜
鎖分類
對數據庫操作的粒度分
表鎖: 操作時,會鎖定整個表 行鎖: 操作時,會鎖定當前操作行
對數據操作的類型分
讀鎖(共享鎖): 針對同一份數據,多個讀操作可以同時進行而不會相互影響 寫鎖(排它鎖): 當操作沒有完成之前,它會阻斷其他寫鎖和讀鎖
mysql鎖
相對其他數據庫而言,Mysql的鎖機制比較簡單,其最顯著的特點是不同的存儲引擎支持不同的鎖機制。
不同存儲引擎支持鎖級別
存儲引擎 | 表級鎖 | 行級鎖 | 頁面鎖 |
---|---|---|---|
MyISAM | 支持 | 不支持 | 不支持 |
InnoDB | 支持 | 支持 | 不支持 |
MEMORY | 支持 | 不支持 | 不支持 |
BDB | 支持 | 不支持 | 支持 |
鎖介紹
很難籠統說哪種鎖更好,需要根據特定的應用場景來分析哪種鎖更合適。
鎖類型 | 特點 |
---|---|
表級鎖 | 偏向MyISAM存儲引擎,開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發送鎖沖突的概率最高,並發度最低。 |
行級鎖 | 偏向InnoDB存儲引擎,開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高。 |
頁面鎖 | 開銷和加鎖時間介於表鎖和行鎖之間;會出現死鎖;鎖定粒度介於表鎖和行鎖之間,並發度一般。 |
MyISAM表鎖
如何添加表鎖
MyISAM在執行查詢語句(select)前,會自動給涉的所有表加鎖,在執行更新操作(update、delete、insert等)前,會自動給涉及的表加寫鎖,這個過程並不需要用戶幹預,因此,用戶一般不需要直接使用LOCK TABLE命令給MyISAM表顯示加鎖
加解鎖
加讀鎖: lock table table_name read; ---解鎖 unlock tables; 加寫鎖: lock table table_name write; 添加寫鎖當前會話可以讀寫操作,別的會話會處於阻塞(等待)狀態 讀鎖限制寫,寫鎖限制讀寫
鎖競爭
1、對MyISAM表的讀操作,不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫請求; 2、對MyISAM的寫操作,則會阻塞其他用戶對表一表的讀和寫操作; 3、MyISAM鎖調度是寫優先。 不適合作為主表,寫鎖後其他線程大量的更新會使查詢很難得到鎖,可能會造成永遠阻塞。
鎖的使用情況
查看鎖的使用情況 show open tables; 查看表的鎖定情況 show status like 'table_locks%'; Table_locks_immediate:可以獲取表級鎖的次數,每立即獲取鎖,值加1 Table_locks_waited:不能立即獲取鎖需要等待的次數,每等待一次,值加1,可以判斷比較嚴重的表級鎖爭用情況
InnoDB鎖
InnoDB與MyISAM的最大不同有亮點:一是支持事務;二是采用行級鎖
行鎖
共享鎖: 又稱讀鎖,多個事務可以共享一把鎖,但是隻能讀,不能寫 排它鎖: 又稱寫鎖,鎖不共用,獲取不到鎖的事務不能進行讀寫操作 如果進行update、delete和insert 語句,innoDB會自動給涉及數據集加排它鎖 對不同的select語句不會添加任何鎖 顯示的給查詢添加鎖 添加共享鎖: select * from table_name where ... Lock IN SHARE MODE 添加排它鎖: select * from table_name where ... FOR UPDATE
鎖升級
索引失效,行鎖升級表鎖 where後面沒索引也升級為表鎖
間隙鎖
InnoDB會對間隙不存在的數據也會加鎖,稱之為間隙鎖
鎖爭用
show status like 'innodb_row_lock%'; Innodb_row_lock_current_waits當前正在等待鎖的數量 Innodb_row_lock_time 鎖定的總時長 Innodb_row_lock_time_avg 鎖定的平均時長 Innodb_row_lock_time_max 鎖定的最大時長 Innodb_row_lock_waits 系統啟動到現在總共等待次數
總結
innoDB存儲引擎實現瞭行鎖,雖然鎖定機制的實現方面帶來瞭性能消耗可能比較表鎖會更高些,但是在整體並發處理能力方面要遠優於MyISAM表鎖,當系統並發比較高的時候,InnoDB的整體性能和MyISAM會有比較明顯的優勢
優化建議
盡可能讓所有數據檢索都能通過索引來完成,避免無索引行鎖升級為表鎖 合理設計索引,盡量縮小鎖的范圍 盡可能減少索引條件,及索引范圍,避免間隙鎖 盡量控制事務大小,減少鎖定資源量和時間的長度 盡可能使用低級別事務隔離(需要業務能滿足需求)
到此這篇關於深入理解mysql各種鎖的文章就介紹到這瞭,更多相關mysql鎖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MySQL InnoDB鎖類型及鎖原理實例解析
- 一篇文章搞懂MySQL加鎖機制
- MySQL臟讀幻讀不可重復讀及事務的隔離級別和MVCC、LBCC實現
- 一文帶你瞭解MySQL中的鎖機制
- 詳解MySQL中事務隔離級別的實現原理