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