某tokudb執行個體備庫發生複制中斷,報錯資訊甚是詭異:
經過gdb core後,大體知道了發生錯誤的原因:
tokudb在建立子事務的時候,由于嵌套事務過多,ft-index直接傳回了錯誤(tokudb的嵌套事務最多允許256個,嵌套事務數目的類型為uint8_t)導緻。
比較詭異的是主庫一切正常,無任何錯誤。
經過溝通,發現使用者使用了大量的savepoint,這是一個突破點。
在tokudb裡savepoint的機制是個啥樣子呢?
這裡我們分兩種情況來處理,先來看第一種,sql1:
tokudb将會這樣處理:
savepoint 間的事務并非嵌套,而是用完就釋放,然後再重新建立,這樣不會導緻事務棧溢出。
再來看另外一種情況,sql2:
這種sql tokudb的處理方式是:
針對開始時的問題,tokudb核心君進行了大膽猜測:
通過翻看 binlog 代碼印證了我們的猜測,在 sql/binlog.cc 裡隻實作了 <code>binlog_savepoint_set</code> 方法,隻記錄savepoint event到binlog,而未記錄release savepoint event!
由于savepoint實作機制不同,對innodb引擎來說是沒有問題的,但對 tokudb 來說就是災難了。解決辦法就是實作<code>binlog_savepoint_release</code>方法,記錄release savepoint event到binlog。
apsaradb mysql 5.6 最新版已修複這個問題,對savepoint有需求的tokudb使用者(innodb不受影響)做下更新即可。
本篇小文從一個使用者引發的問題出發,讨論了tokudb的savepoint機制,當然tokudb核心組的同學每天都會處理很多類似的問題,從發現問題到解決問題,以及持續的優化,為的就是給大家提供一種“飛”的感覺。有大資料量存儲的同學不妨試試我們的 tokudb 引擎,存儲成本大大降低,順便體驗一把下一代存儲引擎帶來的“優越感”(注意,這不是廣告)。
最後廣告還是來了: