天天看點

資料庫核心月報 - 2015 / 07-MySQL · TokuDB · TokuDB Checkpoint機制

為了降低使用者資料存儲成本,2015年4月份,雲資料庫(aliyun rds)增加了tokudb引擎支援(mysql5.6版本),也是第一家支援tokudb的rds。

我們知道,當一個執行個體的資料空間超過tb級别時,空間存儲和運維成本都是非常高的,尤其是做執行個體遷移和備份,整個過程耗時會非常長。

我們對線上一些大的innodb執行個體(tb級)平滑遷移到tokudb後,資料空間從 2tb+ 直接降到 400gb ,空間成本僅為原來的五分之一,而且讀寫性能沒有任何降低(寫性能反而提升不少)。通過線上幾個大執行個體(tb級)的使用,tokudb的壓縮比均在5倍以上,同樣的空間大小,使用tokudb後可以存5倍的容量!

tokudb的另外一個特點就是低io消耗,相同資料量下,io花銷基本是innodb的1/8,io成本也降低了不少,同樣的iops限制下,tokudb寫性能會更高。因為iops消耗較少,rds已經線上上部署tokudb+廉價sata盤叢集,配合“方寸山”(分庫分表proxy)來提供低成本高性能的pb級日志存儲能力。

這個叢集使用廉價的sata盤(iops能力~120),單台實體機基本可提供30,000 tps的寫能力(tokudb_fsync_log_period=0和sync_binlog=1,針對類如日志型應用,對資料安全性要求不是很高的話,調整tokudb_fsync_log_period=1000,sync_binlog=1000,性能會更高),利用tokudb的大頁(page size 4mb)壓縮優勢,尤其是對日志内容,壓縮比基本在1/8以上,單機可提供160tb+的的存儲能力,整個叢集可輕松支援pb級。

使用tokudb,讓你随便任性!

本篇來探讨下tokudb内部的一個重要機制: checkpoint。

tokudb的checkpoint隻有一種方式:sharp checkpoint,即做checkpoint的時候,需要把記憶體中所有的”髒頁”都刷回磁盤。本篇就來介紹下tokudb的sharp checkpoint的一些具體細節,使看官們對tokudb的checkpoint有個大概了解。

tokudb引擎裡,資料存在于3個地方:

redo log (disk)

buffer pool (memory)

data file (disk)

為了性能,對“頁”級的操作會先被cache到buffer pool裡,當觸發某些條件後,才會把這些“髒頁”刷到磁盤進行持久化,這樣就帶來一個問題:

對于tokudb來說,整個fractal-tree元素有兩部分的“頁”組成:(buffer pool裡的“頁” ) + (data file裡已持久化的”頁”),如果tokudb crash後,buffer pool裡的“頁”丢失,隻剩data file的“頁”,此時的fractal-tree處于“混沌“狀态(不一緻狀态)。

為了避免出現這種“混沌“狀态,tokudb需要定期(預設60s)做checkpoint操作,把buffer pool裡的“髒頁”刷到磁盤的data file裡。

當tokudb crash後,隻需從上次的一緻性狀态點開始“回放” redo log裡的日志即可,恢複的資料量大概就是60s内的資料,快吧?嗯。

tokudb checkpoint分2個階段:begin_checkpoint 和 end_checkpoint

大體邏輯如下:

begin_checkpoint:

end_checkpoint:

以上就是整個checkpoint大概的邏輯,整個過程中,隻有c6的任務最“繁重”,在這裡面有幾個“大活”:

clone的時候如果是leaf“頁”,會對原“頁”重做資料均分(leaf裡包含多個大小均勻的子分區) –cpu消耗

刷盤前做大量壓縮 –cpu消耗

多線程并發的把page刷到磁盤 –io操作

以上3點會導緻checkpoint的時候出現一點點的性能抖動,下面看組資料:

以上為sysbench測試資料(讀寫混合),僅供參考,可以看到在[255s]和[315s]checkpoint的時候,性能有個抖動。

喵,另外一個問題來了:如果tokudb在end_checkpoint c6的時候crash了呢,隻有部分“髒頁”被寫到磁盤?此時的資料庫(fractal-tree)狀态豈不是不一緻了?

tokudb在這裡使用了copy-on-write模型,本次checkpoint的“髒頁”在刷到磁盤的時候,不會覆寫上次checkpoint的檔案區間,保證在整個checkpoint過程中出現crash,不會影響整個資料庫的狀态。