摘要:此文已由作者王慎為授權(quán)網(wǎng)易云社區(qū)發(fā)布。與之相反,最新支持的壓縮是頁(yè)透明的,當(dāng)然,頁(yè)首尾的元數(shù)據(jù)是不壓縮的,不關(guān)心這個(gè)頁(yè)里面保存的是什么內(nèi)容,可以理解為頁(yè)塊壓縮,本文將塊和頁(yè)混用。
此文已由作者王慎為授權(quán)網(wǎng)易云社區(qū)發(fā)布。
歡迎訪問(wèn)網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運(yùn)營(yíng)經(jīng)驗(yàn)。
MySQL 5.7中包括了很多讓人耳目一新的新特性,其中就包括了InnoDB Transparent Page Compression,姑且稱之為InnoDB透明頁(yè)壓縮。其實(shí)透明頁(yè)壓縮這個(gè)東西,早就關(guān)注過(guò),其用到了sparse file和hole punching技術(shù),但一直沒能將這兩種技術(shù)跟InnoDB壓縮聯(lián)系起來(lái)。最近花了點(diǎn)時(shí)間了解了下。
熟悉InnoDB的同學(xué)都知道,InnoDB從MySQL 5.1版本開始就支持壓縮,提供zlib壓縮算法,是記錄壓縮(record compress),曾大概看過(guò)InnoDB這部分相關(guān)的源碼,邏輯比較復(fù)雜,如果對(duì)InnoDB page的組織結(jié)構(gòu)不了解,相信很難看出個(gè)所以然,該壓縮是頁(yè)感知的(page aware),即需要知道頁(yè)里面記錄是怎么保存的。與之相反,MySQL 5.7最新支持的壓縮是頁(yè)透明的(page transparent),當(dāng)然,頁(yè)首尾的元數(shù)據(jù)是不壓縮的,不關(guān)心這個(gè)頁(yè)里面保存的是什么內(nèi)容,可以理解為頁(yè)/塊壓縮(page/block compress,本文將塊和頁(yè)混用)。
假設(shè)有個(gè)16KB的InnoDB頁(yè)P(yáng)1,通過(guò)塊壓縮為11KB,如果表空間使用的文件系統(tǒng)在mkfs時(shí)指定block size為4KB,那么只需要使用3個(gè)文件塊來(lái)保存11KB的數(shù)據(jù),節(jié)省1個(gè)文件塊即4KB的空間。那么是不是說(shuō)InnoDB下個(gè)頁(yè)P(yáng)2的數(shù)據(jù)直接從所節(jié)省的這4KB開始寫入嗎,答案是否定的。
InnoDB透明頁(yè)壓縮不會(huì)改變表文件的結(jié)構(gòu),我們可以理解為每頁(yè)都占據(jù)了文件中4個(gè)塊的大小,頁(yè)壓縮后的最終大小不會(huì)影響每個(gè)頁(yè)在表文件中的起始偏移位置。即第k個(gè)頁(yè)的數(shù)據(jù),還是從表文件第4k個(gè)塊開始寫入。問(wèn)題來(lái)了,為什么不呢,因?yàn)閴嚎s頁(yè)經(jīng)過(guò)修改后,再次壓縮后的大小是不可知的,可能本來(lái)壓縮后的大小為11KB,再次壓縮就變成15KB了,那么仍需要4K文件塊來(lái)保存,如果文件第4n+3個(gè)塊已經(jīng)被寫入了P2的數(shù)據(jù),P1再次壓縮后多出來(lái)4K數(shù)據(jù)就沒地方放了。
從上段描述來(lái)看,不管P1被壓縮成什么熊樣,P2仍然需要從表文件的第4*n+4個(gè)偏移塊開始寫入數(shù)據(jù),這種壓縮并沒有改變文件邏輯大小。雖然壓縮后,IO是小了,但4KB的IO相比16KB的IO并不能帶來(lái)多大的性能提升。然并卵!
怎樣才能節(jié)省被壓縮后釋放的空間呢,這就需要用到文件系統(tǒng)/操作系統(tǒng)內(nèi)核層面的技術(shù) - sparse file,簡(jiǎn)單來(lái)說(shuō),sparse file是這樣的文件, file 1大小是12KB,但是其實(shí)只占用首尾2個(gè)文件塊共8KB的磁盤空間,中間4KB由于沒有真實(shí)數(shù)據(jù),并未分配磁盤空間,或者本來(lái)已經(jīng)分配了,但又被回收了,像是中間被挖了個(gè)洞(punch hole)。這被挖的4KB,可以被文件系統(tǒng)用來(lái)分配給其他文件保存數(shù)據(jù)。如果中間4KB的數(shù)據(jù)被用戶填上了呢,沒事,文件系統(tǒng)分配一個(gè)新的空閑快給file 1即可。關(guān)于sparse file更詳細(xì)的介紹參見參考文獻(xiàn)。當(dāng)然這可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)IO不連續(xù)。
通過(guò)上面的描述,相信很容易就能夠?qū)parse file技術(shù)應(yīng)用到InnoDB透明頁(yè)壓縮上。不再贅述,只放一張圖。
為什么InnoDB要另辟蹊徑,采用新的壓縮方案,不再原來(lái)的壓縮實(shí)現(xiàn)上進(jìn)行優(yōu)化呢,可能有以下兩點(diǎn)原因:
首先,原有的記錄級(jí)壓縮,代碼實(shí)現(xiàn)復(fù)雜的,需要基于不同的頁(yè)類型采用不同的處理方式,需要熟悉InnoDB的索引和頁(yè)結(jié)構(gòu),代碼封裝性較差,添加新的壓縮算法或進(jìn)行性能優(yōu)化提升較費(fèi)勁,所以一直僅支持zlib。在這個(gè)基礎(chǔ)上進(jìn)行優(yōu)化提高較困難。這個(gè)觀點(diǎn)得到MySQL官方的驗(yàn)證,詳見參考文獻(xiàn)中的官方描述。
其次,相對(duì)于原來(lái)的記錄級(jí)壓縮,新方案更加靈活,因?yàn)閴嚎s算法是保持在InnoDB頁(yè)的元數(shù)據(jù)中,理論上可以做到同個(gè)表中不同頁(yè)采用了不同的壓縮算法,比如根據(jù)不同頁(yè)類型來(lái)決定是否壓縮,采用某種壓縮算法(當(dāng)然目前MySQL官方還沒這么做)?,F(xiàn)實(shí)中,也會(huì)存在同個(gè)表包括多種壓縮算法的場(chǎng)景,因?yàn)橛脩艨梢詣?dòng)態(tài)修改壓縮算法(也可以啟動(dòng)和關(guān)閉壓縮),而動(dòng)態(tài)修改并不是說(shuō)把已經(jīng)壓縮的頁(yè)馬上使用新的壓縮算法重新壓一次,而是對(duì)新產(chǎn)生或更新的頁(yè)起作用,這就會(huì)導(dǎo)致有些頁(yè)是不壓縮的,有些頁(yè)是采用zlib,有些采用lz4。吐槽下,為什么InnoDB還不支持snappy或quicklz呢。
參考文獻(xiàn):
http://dev.mysql.com/worklog/...
http://mysqlserverteam.com/in...
http://mysqlserverteam.com/in...
https://wiki.archlinux.org/in...
網(wǎng)易云免費(fèi)體驗(yàn)館,0成本體驗(yàn)20+款云產(chǎn)品!
更多網(wǎng)易技術(shù)、產(chǎn)品、運(yùn)營(yíng)經(jīng)驗(yàn)分享請(qǐng)點(diǎn)擊。
文章來(lái)源: 網(wǎng)易云社區(qū)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/25252.html
摘要:提供了一套統(tǒng)一的應(yīng)用開發(fā)模型和核心,因此,盡管不同的存儲(chǔ)引擎擁有不同的特性,不過(guò)對(duì)于開發(fā)人員,應(yīng)用操作都是完全透明的。 Mysql 提供了一套統(tǒng)一的應(yīng)用開發(fā)模型和核心 API,因此,盡管不同的存儲(chǔ)引擎擁有不同的特性,不過(guò)對(duì)于開發(fā)人員,應(yīng)用操作都是完全透明的。應(yīng)用層的連接并不直接訪問(wèn)存儲(chǔ)引擎層,而是訪問(wèn) Mysql 提供的 Api,也就是說(shuō)不管所操作的表對(duì)象使用什么存儲(chǔ)引擎,讀寫數(shù)據(jù)時(shí)執(zhí)...
閱讀 3850·2021-09-02 09:53
閱讀 2804·2021-07-30 14:57
閱讀 3558·2019-08-30 13:09
閱讀 1256·2019-08-29 13:25
閱讀 865·2019-08-29 12:28
閱讀 1507·2019-08-29 12:26
閱讀 1186·2019-08-28 17:58
閱讀 3369·2019-08-26 13:28