摘要:此文已由作者王慎為授權網易云社區發布。與之相反,最新支持的壓縮是頁透明的,當然,頁首尾的元數據是不壓縮的,不關心這個頁里面保存的是什么內容,可以理解為頁塊壓縮,本文將塊和頁混用。
此文已由作者王慎為授權網易云社區發布。
歡迎訪問網易云社區,了解更多網易技術產品運營經驗。
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個頁的數據,還是從表文件第4k個塊開始寫入。問題來了,為什么不呢,因為壓縮頁經過修改后,再次壓縮后的大小是不可知的,可能本來壓縮后的大小為11KB,再次壓縮就變成15KB了,那么仍需要4K文件塊來保存,如果文件第4n+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官方的驗證,詳見參考文獻中的官方描述。
其次,相對于原來的記錄級壓縮,新方案更加靈活,因為壓縮算法是保持在InnoDB頁的元數據中,理論上可以做到同個表中不同頁采用了不同的壓縮算法,比如根據不同頁類型來決定是否壓縮,采用某種壓縮算法(當然目前MySQL官方還沒這么做)?,F實中,也會存在同個表包括多種壓縮算法的場景,因為用戶可以動態修改壓縮算法(也可以啟動和關閉壓縮),而動態修改并不是說把已經壓縮的頁馬上使用新的壓縮算法重新壓一次,而是對新產生或更新的頁起作用,這就會導致有些頁是不壓縮的,有些頁是采用zlib,有些采用lz4。吐槽下,為什么InnoDB還不支持snappy或quicklz呢。
參考文獻:
http://dev.mysql.com/worklog/...
http://mysqlserverteam.com/in...
http://mysqlserverteam.com/in...
https://wiki.archlinux.org/in...
網易云免費體驗館,0成本體驗20+款云產品!
更多網易技術、產品、運營經驗分享請點擊。
文章來源: 網易云社區
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25252.html
摘要:提供了一套統一的應用開發模型和核心,因此,盡管不同的存儲引擎擁有不同的特性,不過對于開發人員,應用操作都是完全透明的。 Mysql 提供了一套統一的應用開發模型和核心 API,因此,盡管不同的存儲引擎擁有不同的特性,不過對于開發人員,應用操作都是完全透明的。應用層的連接并不直接訪問存儲引擎層,而是訪問 Mysql 提供的 Api,也就是說不管所操作的表對象使用什么存儲引擎,讀寫數據時執...
閱讀 3775·2021-09-02 09:53
閱讀 2753·2021-07-30 14:57
閱讀 3495·2019-08-30 13:09
閱讀 1200·2019-08-29 13:25
閱讀 813·2019-08-29 12:28
閱讀 1458·2019-08-29 12:26
閱讀 1133·2019-08-28 17:58
閱讀 3308·2019-08-26 13:28