tokudb在啟動的時候,會對datadir目錄下的檔案(和檔案夾)進行周遊,根據規則找到所有的redo log檔案,然後進行recover操作。
redo檔案的命名規則是:log[index].toku[version],比如log000000000002.tokulog27。
這個bug說起來有點“謎之”,因為它還跟編譯器的版本有關。
如果使用gcc 4.8.2編譯出一個tokudb(加-o3編譯參數),進行如下操作:
然後重新開機,整個tokudb就可能淩亂了,出現如下crash資訊:
先來看下tokudb判斷一個檔案是否為redo log的代碼:
這段代碼的邏輯很簡單,調用sscanf函數擷取相關參數, 高能區域為:
如果name為log0002,調用完sscanf函數後,n和version的值是不确定的(因為函數内變量未被初始化),就可能導緻函數 <code>is_a_logfile_any_version</code> 把log0002檔案夾誤認為是一個redo log。
當<code>toku_logfilemgr_init</code>函數加載名稱“log0002”時做二次校驗,擷取version值失敗進而觸發assert。
大體思路是:
由于redo log不可能是檔案夾,是以增加隻對檔案進行判斷的邏輯,遇到檔案夾直接跳過;
對<code>is_a_logfile_any_version</code>函數内變量進行初始化。
阿裡雲rds tokudb最新版本已經修複此問題,使用tokudb的使用者可以進行下小版本更新,以避免此問題影響業務。