閱讀430 返回首頁    go 阿裏雲 go 技術社區[雲棲]


TokuDB · 讓Hot Backup更完美

很久很久以前,內核君發表了一篇HA方案·TokuDB熱備的文章,方法很簡單:

 1) SET TOKUDB_CHECKPOINT_LOCK=ON;
 2) 開始拷貝TokuDB的數據文件(不包含日誌文件)
 3) FLUSH TABLES WITH READ LOCK;
 4) 記錄binlog位置,拷貝最新的binlog和TokuDB的日誌文件(*.tokulog)
 5) UNLOCK TABLES;
 6) SET TOKUDB_CHECKPOINT_LOCK=OFF;

這些步驟可以很方便的嵌入到Percona XtraBackup中,與InnoDB一起工作,目前看是一個比較簡單可行的方案。

問題來了。
當某個實例的數據量達到TB級,你會發現備庫(基於備份)重搭後,啟動會灰常灰常慢,因為他們都在recover redo-log,為什麼呢?

 1) SET TOKUDB_CHECKPOINT_LOCK=ON;
 2) 開始拷貝TokuDB的數據文件(不包含日誌文件)
     -- 由於拷貝TB級的數據非常耗時,redo log持續增加甚至上萬個

當TokuDB啟動後,掃描和recover這幾萬個redo log將是災難性的。

解決這個問題比較簡單,我們稍微調整下熱備的順序即可:

 1) SET TOKUDB_CHECKPOINT_LOCK=ON;
 2) FLUSH TABLES WITH READ LOCK;
 3) 記錄binlog位置,拷貝最新的binlog和TokuDB的日誌文件(*.tokulog)
 4) UNLOCK TABLES;
 5) 開始拷貝TokuDB的數據文件(不包含日誌文件)  --移動到這裏
 6) SET TOKUDB_CHECKPOINT_LOCK=OFF;

這樣在拷貝TokuDB數據文件的時候,就跟redo-log沒半毛錢關係了,而且拷貝的redo-log數也大大減少!

本以為這樣就可以早點下班回家,但問題還是來。

某實例有幾十萬個TokuDB文件(分區表文件),使用熱備的數據備庫重搭後,複製過程中偶爾會出現"Duplicate entry ... for key 'PRIMARY'"錯誤。

引起這個錯誤的原因比較深,觸發自TokuDB內部機製。

TokuDB每個分區表有數個文件組成(想了解TokuDB數據庫文件的請輕戳這裏),當分區表非常多的時候,打開的文件句柄數會非常多,受限於open_files_limit配置,TokuDB底層會觸發句柄關閉機製,對當前文件進行checkpoint操作(新數據被刷到磁盤且生效)再做close,這樣即使拿到checkpoint鎖後,還是有數據被寫入,就引發了以上問題。

為了解決這個問題,我們在熱備的過程中引入一個狀態:in_backup = true,防止文件關閉做checkpoint操作,具體的patch見這裏:
https://github.com/percona/PerconaFT/pull/331/files

這樣TokuDB的熱備就比較完美了,整個熱備過程中,所有的數據文件均處於一個“一致性”狀態,所有的操作都在redo-log裏,不再汙染數據文件。

最後更新:2017-04-01 13:44:35

  上一篇:go 攔截規則
  下一篇:go Greenplum 激活standby master