Xtrabackup備份原理

xtrabackup的備份原理

  • 軟件包安裝完成之後一共有4個可執行文件,如下:
usr
├── bin
│   ├── innobackupex
│   ├── xbcrypt
│   ├── xbstream
│   └── xtrabackup

其中最主要的是innobackupexxtrabackup,前者是一個perl腳本,後者是C/C++編譯的二進制。

  • xtrabackup是用來備份InnoDB表的,不能備份非InnoDB表,和mysqld server沒有交互;innobackupex腳本用來備份非InnoDB表,同時會調用xtrabackup命令備份InnoDB表,還會和mysqld server發送命令進行交互,如加讀鎖(FTWRL),獲取位點(SHOW SLAVE STATUS)等。簡單來說,innobackupexxtrabackup之上做了一層封裝。
  • 一般情況下我們是希望備份MyISAM表的,雖然我們可能自己不用MyISAM表,但是mysql庫下面的系統表示MyISAM的,因此備份基本都通過innobackupex命令進行;另外一個原因是我們可能需要保存位點信息。
  • 另外倆個工具比較小衆一些,xbcrypt是加解密用的;`xbstream類似於tar,是Percona自己實現的一種支持併發寫的流文件格式。倆者都在備份和解壓的時候都會用到(如果備份用到了加密和併發)。

原理

通信方式

2個工具之間的交互和協調是通過控制文件的創建和刪除來實現的,主要文件有:

  • xtrabackup_suspended_1
  • xtrabackup_suspended_2
  • xtrabackup_log_copied
  1. innobackupex在啓動xtrabackup進程後,會一直等待xtrabackup備份完InnoDB文件,方式就是等待xtrabackup_suspended_2這個文件被創建出來;
  2. xtrabackup在備份完InnoDB數據後,就在指定的目錄下創建出xtrabackup_suspended_2這個文件,然後等待innobackupex刪除;
  3. innobackupex檢測到文件xtrabackup_suspended_2被創建出來之後,就繼續往下走;
  4. innobackupex備份完非InnoDB表後,刪除xtrabackup_suspended_2這個文件,這樣就通知xtrabackup可以繼續了,然後等xtrabackup_log_copied被創建;
  5. xtrabackup檢測到xtrabackup_suspended_2文件刪除之後,就可以繼續下去了。

通過文件是否存在來控制進程這種方式是非常的不靠譜的,因爲非常容易被外部干擾,比如文件被其他人誤刪除掉,活着2個正在跑的備份控制文件誤放在同一個目錄下面,那麼備份很容易亂掉的。

之所以這麼做的原因是因爲perl和C二進制2個進程,沒有既好用又方便的通信方式,弄個協議的話又太麻煩了,所以纔會出現這種方式進行通信。

但是官方在2.3版本實現了將innobackupex功能全部集成到了xtrabackup,只有一個binary,另外爲了使用上的兼容考慮,innobackupex作爲xtrabackup的一個軟鏈。對於二次開發來說,2.3擺脫了之前2個進程協作的負擔,架構上明顯要好於之前的版本。

2.3之前版本innobackupex備份流程

Xtrabackup備份原理

  1. innobackupex在啓動後,會先fork一個進程,啓動xtrabackup進程,然後等待xtrabackup備份完ibd數據文件;
  2. xtrabackup在備份InnoDB相關數據時候,是有2種線程的,1種是redo拷貝線程,負責拷貝redo文件,1種是ibd拷貝線程,負責拷貝ibd文件;redo拷貝線程只有一個,在ibd拷貝線程之前啓動,在ibd線程結束後結束。xtrabackup進程開始執行後,先啓動redo拷貝線程,從最新的checkpoint點開始順序拷貝redo日誌;然後再啓動ibd數據拷貝線程,在xtrabackup拷貝ibd過程中,innobackupex進程一直處於等待狀態(等待文件被創建);
  3. xtrabackup拷貝完成ibd後,通知innobackupex(通過創建文件),同時自己進入等待(redo拷貝線程任然繼續拷貝);
  4. innobackupex受到xtrabackup通知後,執行FLUSH TABLES WITH READ LOCK(FTWRL),取得一致性位點,然後開始備份非InnoDB文件(包括frm,MYD,CSV,opt,par等)。拷貝非InnoDB文件過程中,因爲數據庫屬於全局只讀狀態,如果在業務的主庫備份的話,需要特別小心,非InnoDB(主要是MyISAM)比較多的話那麼整個只讀的時間就會比較長,這個影響需要評估到;
  5. innobackupex拷貝完所有的非InnoDB表文件之後,通知xtrabackup(通過刪除文件),同時自己進入等待(等待另一個文件被創建)
  6. xtrabackup收到innobackupex備份完非InnoDB通知後,就停止redo拷貝線程,然後通知innobackupexredo log拷貝完成(通過創建文件);
  7. innobackupex收到redo備份完成通知後,就開始解鎖,執行UNLOCK TABLES;
  8. 最後innobackupexxtrabackup進程各自完成收尾工作,如資源的釋放,寫備份元數據信息等,innobackupexxtrabackup子進程結束後退出。

在上面描述的文件拷貝,都是備份進程直接通過操作系統讀取數據文件的,只在執行SQL命令時和數據庫又交互,基本不影響數據庫的運行,在備份非InnoDB時會有一段時間的只讀(如果沒有MyISAM表的話,只讀時間在幾秒左右),在備份InnoDB數據文件時,對數據庫完全沒有影響,是真正的熱備。

InnoDB和非InnoDB文件的備份都是通過拷貝文件來做的,但是實現方式不同,前者是以page爲粒度做的(xtrabackup),後者是cp或者tar命令(innobackupex),xtrabackup在讀取每個page時會校驗checksum值,保證數據塊是一致的,而innobackupex在cp MyISAM文件時已經做了flush(FTWRL),磁盤上的文件也是完整的,所以最終備份集裏的數據文件都是寫入完整的。

增量備份

PXB是支持增量備份的,但是隻能對InnoDB做增量,InnoDB每個page有個LSN號,LSN是全局遞增的,page被更改時會記錄當前的LSN號,page中LSN越大,說明當前的page越新(最近被更新)。每次備份會記錄到當前備份到的LSN(xtrabackup_checkpoints文件中),增量別發就是隻拷貝LSN大於上次備份的page,比上次備份小的跳過,每個ibd文件最終出來的是增量delta文件。

MyISAM是沒有增量機制的,每次增量備份都是全部拷貝的。

增量備份過程和全量備份一樣,只是和ibd文件拷貝不一樣。

恢復過程

如何看恢復備份集的日誌,會發現和mysqld啓動時非常相似,其實備份集的恢復就是類似mysqld crash後,做一次crash recover。

恢復的目的就是把備份集中的數據恢復到一個一致性位點,所謂的一致就是指原數據庫某一時間點各引擎數據的狀態,比如MyISAM中的數據對應的是15:00時間點的,InnoDB中的數據對應的是15:20的,這種狀態的數據就是不一致的。PXB備份集對應的一致點,就是備份FTWRL的時間點,恢復出來的數據,就是對應原數據庫FTWRL時的狀態。

因爲備份時FTWRL後,數據庫時處於只讀的,非InnoDB數據是在持有全局讀鎖情況下拷貝的,所以非InnoDB數據本身就對應FTWRL時間點;InnoDB的ibd文件拷貝時在FTWRL前做的,拷貝出來的不同的ibd文件最後更新點是不一樣的,這種狀態的ibd文件是不能直接用的,但是redo log是從備份開始一直持續拷貝的,最後的redo日誌點事在持有FTWRL後取得的,所以最終通過redo應用後的ibd數據時間點也是和FTWRL一致的。

所以恢復過程只是涉及InnoDB文件的恢復,非InnoDB數據事不動的。備份恢復完成之後,就可以把數據文件拷貝到對應的目錄,然後就可以通過mysqld來啓動了。

轉載

http://mysql.taobao.org/monthly/2016/03/07/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章