想了解Xtrabackup備份原理和常見問題分析,看這篇就夠了

華為雲開發者社群 發表於 2021-10-16
摘要:本文來自華為雲MySQL研發團隊,主要分享了MySQL備份工具Xtrabackup的備份過程、華為雲資料庫團隊對其做的優化改進,以及在使用中可能遇到的問題與解決方法。

本文分享自華為雲社群《華為雲帶你探祕Xtrabackup備份原理和常見問題分析》,作者:GaussDB 資料庫 。

本文來自華為雲MySQL研發團隊,主要分享了MySQL備份工具Xtrabackup的備份過程、華為雲資料庫團隊對其做的優化改進,以及在使用中可能遇到的問題與解決方法。文章討論的內容主要是針對華為雲RDS for MySQL, 以及使用者自建的社群版MySQL資料庫,希望有助於大家理解和使用Xtrabackup,以後面對Xtrabackup問題也更加從容。

一、Xtrabackup簡介

Xtrabackup是Percona團隊開發的用於MySQL資料庫物理熱備份的開源備份工具,具有備份速度快、支援備份資料壓縮、自動校驗備份資料、支援流式輸出、備份過程中幾乎不影響業務等特點,是目前各個雲廠商普遍使用的MySQL備份工具。

當前Xtrabackup存在兩個版本:Xtrabackup 2.4.x與8.0.x,分別用於備份MySQL 5.x與MySQL 8.0.x 版本。下面我們分別介紹 Xtrabackup如何備份MySQL社群版以及華為雲上的Xtrabackup的備份原理

二、社群版MySQL的Xtrabackup備份

Xtrabackup是為Percona MySQL設計的,同時也支援對官方社群版本MySQL進行備份,過程如下圖所示:
image.png

圖1:Xtrabackup備份官方MySQL流程示意

  1. 相容性檢查:Xtrabackup社群版本只支援 MyISAM , InnoDB , CSV , MRG_MYISAM 四種儲存引擎的表,其他儲存引擎的表不會備份;在這一步中,通過查詢tables,若發現存在表的儲存引擎不是上述四種引擎之一,會列印warning, 表明Xtrabackup不會備份該表。
  2. 啟動redo後臺備份執行緒:啟動redo後臺備份執行緒,從備份例項的最近一次checkpoint LSN的位置開始備份所有增量的redo log,一直持續到備份任務結束。
  3. 載入所有的innodb表空間:開啟並掃描所有innodb表的資料檔案,檢查所有表空間的第一個頁面,初始化所有表的記憶體結構。
  4. 備份innodb表:遍歷步驟3所構建的表的記憶體結構,備份每一個innodb表的資料檔案,備份的過程中會檢查每個頁面的資料是否正確。
  5. 加備份鎖 FLUSH TABLES WITH READ LOCK (FTWRL):FTWRL鎖是MySQL例項級的讀鎖,加鎖過程複雜,且加鎖之後,所有表的所有更新操作以及DDL都會堵塞。
  6. 備份非innodb表:因為在步驟5我們已經對例項加了讀鎖,因此,此時備份非innodb表是安全的,此時一定沒有寫業務。
  7. 記錄binlog當前的GTID資訊:請注意,此時我們仍持有全域性讀鎖。這一步主要是方便我們使用該備份集快速地建立出備機。
  8. 停止redo備份執行緒。
  9. 釋放鎖資源,備份結束。

需要注意的是,Xtrabackup 2.4.x與8.0.x在第7、8這兩個步驟存在差異,這個差異有MySQL 8.0.x的原因,詳情我們在下文介紹。

三、華為雲RDS for MySQL備份

在備份社群版MySQL例項時,Xtrabackup會對例項加全域性讀鎖(FTWRL),該鎖對資料庫的業務影響很大,嚴重時甚至會導致資料庫“掛起”,這對客戶來說是不可接受的。因此華為雲MySQL團隊對這個過程進行了優化,主要有兩點:

  1. 對MySQL 5.x以及0.x增加了備份鎖:LOCK TABLES FOR BACKUP
  2. 對MySQL 5.x新增了binlog鎖:LOCK BINLOG FOR BACKUP

優化之後,華為雲Xtrabackup對MySQL的備份過程如下:
image.png

圖2 Xtrabackup備份華為雲MySQL流程示意

與FTWRL鎖相比,備份鎖 LOCK TABLES FOR BACKUP對客戶例項影響很小,其加鎖過程簡單,加鎖期間innodb表的DML操作不受影響,但是非innodb表的所有的更新操作以及DDL操作仍然是不允許的。

備份完所有的表檔案後,Xtrabackup需要獲取binlog GTID資訊。

• 對於MySQL 5.x版本,Xtrabackup 2.4.x會執行 LOCK BINLOG FOR BACKUP 操作,對binlog加鎖,然後獲取GTID資訊。
• 對於MySQL 8.0.x版本,華為雲Xtrabackup 8.0.x沿用官方的一致性備份點查詢方法。Xtrabackup查詢log_status 時,MySQL伺服器會分別對redo log, binlog等加輕量級鎖,獲取一致性備份點,這個過程是非常短暫的,對例項的執行幾乎沒有影響。MySQL 8.0.x的備份一致性點,會告訴我們一致性的redo log LSN以及binlog的GTID;查詢完備份一致點後,Xtrabackup會備份最後一個binlog檔案,用於恢復時仲裁事務是否需要回滾;最後,redo log備份執行緒任務會在其讀取到的redo log的LSN大於查詢到的備份一致性點的redo log LSN處停止。

由於Xtrabackup 2.4.x與8.0.x在處理binlog時存在差異,恢復過程也存在差異,我們會在後續文章中詳細闡述。

四、常見問題與解決方法

華為雲已經使用Xtrabackup為公司幾乎所有的MySQL例項提供備份服務,在使用過程中,我們積極與社群保持聯絡,向Percona社群報告使用過程中的一些問題,幫助Xtrabackup向更好的方向演進。此外,對於發現的一些致命問題,若社群未能及時修復,華為雲資料庫團隊會進行及時修復以保證備份資料的正確性。

下面是我們總結在使用Xtrabackup備份過程各個階段可能遇到的問題,分析其原因以及對應的解決方法,

1. 相容性檢查階段

  • 問題現象:Xtrabackup啟動後,立即長時間“掛起”,檢視日誌發現redo log備份執行緒也沒有啟動。

原因:Xtrabackup相容性檢查時無法獲取MDL鎖。Xtrabackup相容性檢查是通過查詢 imformation_schema.tables這個外掛表實現:

“SELECT CONCAT(table_schema, '/', table_name), engine FROM information_schema.tables WHERE engine NOT IN ('MyISAM', 'InnoDB', 'CSV', 'MRG_MYISAM') AND table_schema NOT IN ('performance_schema', 'information_schema', 'mysql')”

在查詢每張表時,需要獲取對應表的MDL鎖,如果此時MySQL例項中存在長時間的DML或者DDL 語句,或者更嚴重者出現了MDL死鎖,上面的查詢會一直堵塞在等待MDL鎖階段,此時 Xtrabackup會長時間“掛起”。

解決辦法:若等待鎖的原因只是因為其他SQL語句的堵塞,等待其他SQL執行完成即可;若是發生了死鎖,此時需要分析出死鎖原因,將死鎖解除;華為雲RDS for MySQL提供了MDL鎖檢視功能,可以很好地幫助使用者分析業務的MDL死鎖。

2.redo log備份階段

  • 問題現象1:redo log回捲,備份失敗,Xtrabackup報如下錯誤資訊:
    “xtrabackup: error:it looks like InnoDB log has wrapped around before xtrabackup could process all records due to either log copying being too slow, or log files being too small.\n");”

原因:在備份的過程中,如果主機業務負載很高,導致redo log寫入的速度很快,會發生Xtrabackup的redo log備份執行緒的備份速度小於redo log的寫入速度,因為MySQL redo log檔案寫入使用了 round-robin的方式,使得新寫入的日誌覆蓋了之前寫入卻還未備份的日誌,因此備份失敗。

解決辦法:推薦在業務低峰期進行備份,或者增大redo log的檔案大小。

  • 問題現象2:備份因DDL操作失敗,錯誤資訊如下:

“An optimized (without redo logging) DDLoperation has been performed. All modified pages may not have been flushed to the disk yet.

PXB will not be able take a consistent backup. Retry the backup operation”

原因: 備份過程中MySQL例項發生了建立索引的DDL操作,因為建立索引不會寫redo,若繼續備份會引起資料不一致問題,所以Xtrabackup在這種場景中備份失敗是預期行為。

解決辦法:不要在備份過程中建立索引,如果確實需要,建議在建表語句中直接帶上索引,或者使用 lock-ddl 引數進行備份(阻塞例項上新的DDL操作)。

  • 問題現象3:undo truncate導致備份失敗,Xtrabackup錯誤資訊如下:

“An undo ddl truncation (could be automatic) operation has been performed.”

原因:在Xtrabackup備份期間,如果MySQL例項發生undo truncate時,有可能會出現寫入新 undo檔案(space id不同)的undo日誌丟失導致恢復出來的資料存在問題。官方在Xtrabackup 8.0.14版本(基於MySQL 8.0.21)對該問題進行了修復,修復方法是redo備份執行緒,解析redo log時若發現該操作是undo log的truncate操作,則會備份失敗。遺憾的是,該修復並沒有完全解決問題,在以下兩種場景中,社群版本的Xtrabackup仍可能會發生恢復出來的資料存在不一致的現象:

  1. MySQL版本低於MySQL 8.0.21;
  2. 使用者在備份過程中,自己建立了新的undo tablespace。

解決辦法:在備份期間關閉undo tablespace的truncate操作,並禁止使用者建立undo tablespace, 能夠有效地防止備份資料恢復出來不一致的問題;另外華為雲Xtrabackup對這個問題進行了進一步的修復,可以有效地防止此類現象發生。

3.載入表空間階段

  • 問題現象1:Xtrabackup報錯:Too many open files

原因:作業系統允許同時開啟的檔案數量是有限的,Xtrabackup在load tablespace階段會同時開啟所有的表檔案,如果Xtrabackup開啟的表的個數超過了該限制,則會備份失敗。

解決辦法:調大作業系統,允許同時開啟最大檔案數的配置,或者使用 lock-ddl 引數(阻塞例項上新的DDL操作)。

  • 問題現象2:rename table導致備份失敗,錯誤資訊如下:

“Trying to add tablespace 'xxxx' with id xxx to the tablespace memory cache, but tablespace xxxx already exists in the cache!;”

原因:在Xtrabackup開啟表空間的全過程是沒有加鎖的,如果發生了rename table有概率會發生重複載入相同的表空間,此時Xtrabackup會檢測到重複的tablespace id,因此備份失敗。

解決辦法:一般來說,載入表空間是一個很快的操作,rename table並不是一個很頻繁的操作,這種情況重試即可(Percona Xtrabackup 2.4.x僅支援單執行緒載入表空間,華為雲Xtrabackup支援多執行緒載入表空間)。

4.備份innodb表階段

  • 問題現象:innodb表資料檔案損壞,備份失敗,錯誤資訊如下:

“xtrabackup: Database page corruption detected at page xxxx, retrying.”

原因:Xtrabackup在備份innodb表資料檔案時,會檢查每個頁面的checksum,如果發現checksum不對,則備份失敗,這時說明MySQL例項的資料已經發生了損壞(例如磁碟靜默錯誤)。

解決辦法:需要通過恢復前一次的備份資料或者其他的辦法將資料進行修復之後,備份才能成功,在後續的文章中,我們也會詳細介紹資料修復辦法。

五、結語

本文主要對比介紹了Xtrabackup備份原理,備份社群版MySQL以及華為雲對其的改進,並分享了Xtrabackup常見問題的排查與解決,後續我們也會為大家帶來更深入的分析,更實用的使用技巧,希望對大家理解和使用Xtrabackup有幫助。我們也將持續為客戶提供更好的資料庫服務,並時刻守護客戶的資料安全。

最後,告訴大家一個好訊息,雲資料庫MySQL包年19.9元起,助力企業無憂上雲,歡迎大家前來體驗

點選關注,第一時間瞭解華為雲新鮮技術~