網易視訊雲是網易傾力打造的一款基於雲端計算的分散式多媒體處理叢集和專業音視訊技術,為客戶提供穩定流暢、低時延、高併發的視訊直播、錄製、儲存、轉碼及點播等音視訊的PaaS服務。線上教育、遠端醫療、娛樂秀場、線上金融等各行業及企業使用者只需經過簡單的開發即可打造線上音視訊平臺。現在,網易視訊雲與大家分享一下MySQL 5.6對於Xtrabackup的影響。
組提交優化
最近QA在對InnoSQL-5.5.30-v5版本做迴歸測試時發現數據不一致的問題,簡單來說這個測試用例為在主機上進行全備後恢復,會發現資料不一致的情形。因為我們使用全INSERT操作來進行測試,所以可以非常簡單的發現不一致的情形。但是這些測試在我們之前的v2版本中都是沒有問題的。由於InnoSQL非常強調資料的一致性,因此這個問題在組內得到了極大的關注。小夥伴們測試了多個版本,發現官方MySQL 5.5、InnoSQL 5.5.20-v2版本都沒有問題,但是官方MySQL 5.6和InnoSQL 5.5.30-v5版本都有這個問題。經過多方面的定位,最終確定了這個問題的源頭——MySQL組提交的優化。
大家或許已經知道MySQL5.6中修復了組提交的bug,這個修復最早是由MariaDB開發團隊的大牛Kristian完成的,MySQL 5.6也借鑑了這樣的實現,即一次fsync可以重新整理多個事務的提交。在MySQL資料庫中,組提交存在於上層binlog也存在於下層的InnoDB引擎層。
在InnoDB儲存引擎層每次每個事務進行prepare操作,都需要觸發一次fsync操作,以此確保事務的prepare日誌一定寫入到redo日誌(當然,InnoDB引擎本身支援組提交,可能一次fsync重新整理多個事務的prepare日誌,但是這個完全是無法控制的行為)。然後,一個組提交中的事務依次向MySQL的二進位制日誌寫日誌,這個寫操作是快取寫,最後寫完進行一次fsync操作。即一個fsync將多個事務的日誌寫入到了二進位制日誌,也就是通常所說的組提交。最後完成InnoDB引擎層面的提交操作,這個操作主要是將undo日誌放入到History連結串列,釋放鎖等相關資源。但是與MySQL 5.5不同是,最後InnoDB引擎層提交操作不再需要fsync。
最後這樣優化的優化也是Kristian提出並實現的,原因很簡單,因為即使InnoDB引擎層的redo日誌丟失,但是由於binlog日誌已經寫入(fsync確保),恢復時只要確定寫入binlog的日誌在InnoDB引擎層全部提交即可。可以看出,這個優化進一步減少了資料庫的fsync次數,從而整體上提升了資料庫的效能。InnoSQL 5.5修復了組提交的bug,同時也引入了這個優化。
對Xtrabackup的影響
但是,任何優化可能都會存在一些潛在的影響。這就是為什麼MySQL 5.6和InnoSQL 5.5備份會導致資料不一致的問題。我們來看Xtrabackup的內部過程,這裡進考慮InnoDB表的備份:
1.記錄redo日誌的LSN,記為lsn1
2.拷貝ibdata,*.ibd表空間檔案
3.flush tables with read lock
4.記錄binlog位置,記錄當前redo日誌為lsn2
5.unlock tables
6.拷貝lsn1至lsn2的redo日誌
但是在MySQL 5.6中xtrackup會遇到問題,因為事務最後提交不再需要fsync操作,這意味這第6步驟拷貝的日誌可能會不包括那些已經在步驟4中寫入binlog的那些事務,而Xtrabackup對InnoDB的恢復僅通過redo日誌回放。雖然,Xtrabackup備份出來的InnoDB資料檔案還是一致的,但是這些資料與binlog的位置是不一致的。那麼當通過備份重新建立一個slave伺服器時,就可能會導致出錯。Xtrackup 2.2.3版本解決了這個問題,即在執行步驟6時,先執行一步FLUSH ENGINE LOGS操作,確保重做日誌通過fsync重新整理到磁碟,從而避免binlog與備份檔案的不一致。
總結
各位在使用MySQL5.6、MariaDB 10.0、InnoSQL版本時,務必確保Xtrabackup已經升級到了2.2.3版本。最後,感謝QA組的同事們,每次在InnoSQL新版本釋出前後,總能幫助我們發現很多“奇奇怪怪”的問題。