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