這個問題,涉及MySQL表鎖的一些細節,借著這個問題,系統性說下表鎖的“所以然”。
畫外音:網上不少文章只說結論,不說為什么,容易讓人蒙圈。
MySQL表鎖知識系統性梳理。
哪些存儲引擎使用表鎖?
MySQL,除InnoDB支持行鎖外,MySQL的其他存儲引擎均只使用表鎖,例如:MyISAM, MEMORY, MERGE等。
表鎖有什么好處?
(1)表鎖占用內存少很多,行鎖的數量與行記錄數相關,非常耗內存;
(2)如果業務經常讀寫表中很大一部分數據時,表鎖會更快,因為此時只涉及一個鎖,而不是同時管理N多個鎖;
(3)如果業務經常使用group by,表鎖會更快,原因同(2);
畫外音:這樣的一些場景,使用MyISAM比InnoDB更優。
表鎖是怎么運作的?
和其他臨界資源的讀寫鎖類似。
寫時,要加寫鎖:
(1)如果表沒有鎖,對表加寫鎖;
(2)否則,入寫鎖隊列;
讀時,要加讀鎖:
(1)如果表沒有寫鎖,對表加讀鎖;
(2)否則,入讀鎖隊列;
表鎖釋放時:
如果寫鎖隊列和讀鎖隊列里都有鎖,寫有更高的優先級,即寫鎖隊列先出列。這么做的原因是,如果有“大查詢”,可能會導致寫鎖被批量“餓死”,而寫鎖往往釋放很快。
畫外音:潛臺詞是,如果有大量并發update請求,select會等所有update請求執行完才執行。
如何查看表鎖情況? 如果要分析表鎖沖突情況,可查看:
Table_locks_immediate:立刻獲得表鎖的次數;
Table_locks_waited:需要等待表鎖的次數;
這兩個變量。 使用以下命令查看:
show status like ‘Table%’;
如果等待表鎖的次數占比較大,說明表鎖可能是潛在瓶頸。
說了半天,還是沒有講到點子上,為什么在并發插入量比較大的時候,比較適合使用MyISAM呢?不會因為表鎖頻繁沖突而導致吞吐量降低嗎?
畫外音:知識的系統性,比問題答案更重要。
知識點一:
MyISAM的索引與記錄存儲分離,有單獨的區域存儲行記錄,PK是非聚集索引。
這個知識點就不展開了,以前講過。
知識點二:
MyISAM表,如果數據文件(data file)緊密存儲,中間沒有空閑塊(free blocks),數據總是插入到數據文件的尾部(end),就如同追加日志一樣,性能很高,此時的并發insert與select是不加鎖的(lock free)。
如上圖所示:
(1)數據文件連續且緊密的存儲著; (2)并發insert無表鎖爭搶(只需插入隊列互斥); (3)insert只在數據文件的尾部進行; (4)并發select也能夠同時進行(共享讀鎖); 知識點三:
MyISAM表,如果數據文件(data file)中間有空洞(hole),上述機制會失效,直到空洞被新數據填滿,又會啟用不加鎖機制。 空洞是怎么導致的?
刪除或者修改數據,都可能導致空洞。
如上圖所示:
(1)中間刪除了一些數據,導致中間出現空閑塊(free blocks); (2)此時,select和insert會有表鎖沖突,無法并發;
再如上圖所示:
(1)隨著插入的進行,中間的空閑塊又被填滿了; (2)此時,并發select和insert又恢復了; 結論
雖然MyISAM只支持表鎖,但高并發select與insert的業務場景,上述機制使得MyISAM的表鎖依然有非常強勁的性能。 畫外音:本文基于MySQL5.6。
-
數據
+關注
關注
8文章
7134瀏覽量
89475 -
存儲
+關注
關注
13文章
4353瀏覽量
86114 -
MySQL
+關注
關注
1文章
829瀏覽量
26717
原文標題:頻繁插入,用什么存儲引擎更合適?| 數據庫系列
文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論