InnoDB透明頁壓縮與稀疏檔案

2022-06-07 09:57:10 字數 1793 閱讀 4737

此文已由作者王慎為授權網易雲社群發布。

mysql 5.7中包括了很多讓人耳目一新的新特性,其中就包括了innodb transparent page compression,姑且稱之為innodb透明頁壓縮。其實透明頁壓縮這個東西,早就關注過,其用到了sparse file和hole punching技術,但一直沒能將這兩種技術跟innodb壓縮聯絡起來。最近花了點時間了解了下。

熟悉innodb的同學都知道,innodb從mysql 5.1版本開始就支援壓縮,提供zlib壓縮演算法,是記錄壓縮(record compress),曾大概看過innodb這部分相關的原始碼,邏輯比較複雜,如果對innodb page的組織結構不了解,相信很難看出個所以然,該壓縮是頁感知的(page aware),即需要知道頁裡面記錄是怎麼儲存的。與之相反,mysql 5.7最新支援的壓縮是頁透明的(page transparent),當然,頁首尾的元資料是不壓縮的,不關心這個頁裡面儲存的是什麼內容,可以理解為頁/塊壓縮(page/block compress,本文將塊和頁混用)。

假設有個16kb的innodb頁p1,通過塊壓縮為11kb,如果表空間使用的檔案系統在mkfs時指定block size為4kb,那麼只需要使用3個檔案塊來儲存11kb的資料,節省1個檔案塊即4kb的空間。那麼是不是說innodb下個頁p2的資料直接從所節省的這4kb開始寫入嗎,答案是否定的。

innodb透明頁壓縮不會改變表檔案的結構,我們可以理解為每頁都佔據了檔案中4個塊的大小,頁壓縮後的最終大小不會影響每個頁在表檔案中的起始偏移位置。即第k個頁的資料,還是從表檔案第4*k個塊開始寫入。問題來了,為什麼不呢,因為壓縮頁經過修改後,再次壓縮後的大小是不可知的,可能本來壓縮後的大小為11kb,再次壓縮就變成15kb了,那麼仍需要4k檔案塊來儲存,如果檔案第4*n+3個塊已經被寫入了p2的資料,p1再次壓縮後多出來4k資料就沒地方放了。

從上段描述來看,不管p1被壓縮成什麼熊樣,p2仍然需要從表檔案的第4*n+4個偏移塊開始寫入資料,這種壓縮並沒有改變檔案邏輯大小。雖然壓縮後,io是小了,但4kb的io相比16kb的io並不能帶來多大的效能提公升。然並卵!

怎樣才能節省被壓縮後釋放的空間呢,這就需要用到檔案系統/作業系統核心層面的技術 - sparse file,簡單來說,sparse file是這樣的檔案, file 1大小是12kb,但是其實只占用首尾2個檔案塊共8kb的磁碟空間,中間4kb由於沒有真實資料,並未分配磁碟空間,或者本來已經分配了,但又被**了,像是中間被挖了個洞(punch hole)。這被挖的4kb,可以被檔案系統用來分配給其他檔案儲存資料。如果中間4kb的資料被使用者填上了呢,沒事,檔案系統分配乙個新的空閒快給file 1即可。關於sparse file更詳細的介紹參見參考文獻。當然這可能會導致資料庫io不連續。

通過上面的描述,相信很容易就能夠將sparse file技術應用到innodb透明頁壓縮上。不再贅述,只放一張圖。

為什麼innodb要另闢蹊徑,採用新的壓縮方案,不再原來的壓縮實現上進行優化呢,可能有以下兩點原因:

首先,原有的記錄級壓縮,**實現複雜的,需要基於不同的頁型別採用不同的處理方式,需要熟悉innodb的索引和頁結構,**封裝性較差,新增新的壓縮演算法或進行效能優化提公升較費勁,所以一直僅支援zlib。在這個基礎上進行優化提高較困難。這個觀點得到mysql官方的驗證,詳見參考文獻中的官方描述。

網易雲免費體驗館,0成本體驗20+款雲產品! 

更多網易技術、產品、運營經驗分享請點選。

稀疏表示與壓縮感知

最近在看機器學習時,看到一章關於稀疏學習的,之前有了解過稀疏表示與壓縮感知,但是兩者之間的差異並不是很清楚,今天就總結一下吧 稀疏表示 稀疏域模型 sparse land model 即訊號的稀疏表示,它意欲用盡可能少的非0係數表示訊號的主要資訊,從而簡化訊號處理問題的求解過程。稀疏域模型可如表示式...

稀疏學習與壓縮感知

當樣本資料為稀疏矩陣時,對學習任務有不少好處 稀疏矩陣 矩陣的 每一行 列都包含大量的零元素,且這些零元素沒有出現在同一行 列中。非零元素遠小於零元素 字典學習 側重於為普通稠密表達的樣本找到乙個合適的矩陣 稀疏表示 將樣本轉化為合適的稀釋表示形式,從而使學習任務變得簡單 壓縮感知在前些年也是風風火...

大頁記憶體與透明大頁詳解

大頁記憶體 hugepages 有時也叫 大記憶體頁 記憶體大頁 標準大頁 作業系統以記憶體頁為單位管理記憶體,記憶體頁的大小對系統效能有影響。記憶體頁設得太小,記憶體頁會很多,管理記憶體頁的陣列會比較大,耗記憶體,同時tlb translation lookaside buffer,頁表寄存緩衝器...