1. 程式人生 > 其它 >MySQL-xtrabackup備份原理

MySQL-xtrabackup備份原理

Percona XtraBackup(簡稱PXB)是 Percona 公司開發的一個用於 MySQL 資料庫物理熱備的備份工具,支援 MySQl(Oracle)、Percona Server 和 MariaDB,並且全部開源,真可謂是業界良心。

工具集

usr
├── bin
│   ├── innobackupex
│   ├── xbcrypt
│   ├── xbstream
│   └── xtrabackup

其中最主要的是 innobackupex 和 xtrabackup,前者是一個 perl 指令碼,後者是 C/C++ 編譯的二進位制。

xtrabackup 是用來備份 InnoDB 表的,不能備份非 InnoDB 表,和 mysqld server 沒有互動。

innobackupex 指令碼用來備份非 InnoDB 表,同時會呼叫 xtrabackup 命令來備份 InnoDB 表,還會和 mysqld server 傳送命令進行互動,如加讀鎖(FTWRL)、獲取位點(SHOW SLAVE STATUS)等。簡單來說,innobackupex 在 xtrabackup 之上做了一層封裝。

一般情況下,我們是希望能備份 MyISAM 表的,雖然我們可能自己不用 MyISAM 表,但是 mysql 庫下的系統表是 MyISAM 的,因此備份基本都通過 innobackupex 命令進行;另外一個原因是我們可能需要儲存位點資訊。

原理
通訊方式
兩個工具之間的互動和協調是通過控制檔案的建立和刪除來實現的,主要檔案有:

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個正在跑的備份控制檔案誤放在同一個目錄下,就等著備份亂掉吧,但是 Percona 就是這麼幹的。

備份過程

1、innobackupex 在啟動後,會先 fork 一個程序,啟動 xtrabackup程序,然後就等待 xtrabackup 備份完 ibd 資料檔案。

2、xtrabackup 在備份 InnoDB 相關資料時,是有2種執行緒的,一種是 redo 拷貝執行緒,負責拷貝 redo 檔案,一種是 ibd 拷貝執行緒,負責拷貝 ibd 檔案。redo 拷貝執行緒只有一個,在 ibd 拷貝執行緒之前啟動,在 ibd 執行緒結束後結束。xtrabackup 程序開始執行後,先啟動 redo 拷貝執行緒,從最新的 checkpoint 點開始順序拷貝 redo 日誌。然後再啟動 ibd 資料拷貝執行緒,在 xtrabackup 拷貝 ibd 過程中,innobackupex 程序一直處於等待狀態( 等待xtrabackup_suspended_2檔案被建立 )。

3、xtrabackup 拷貝完成 ibd 檔案後,通知 innobackupex(通過建立xtrabackup_suspended_2檔案),同時自己進入等待(redo 執行緒仍然繼續拷貝)。

4、innobackupex 收到 xtrabackup 通知後,執行FLUSH TABLES WITH READ LOCK (FTWRL 鎖全例項不可寫),取得一致性位點,然後開始備份非 InnoDB 檔案(包括 frm、MYD、MYI、CSV、opt、par等)。拷貝非 InnoDB 檔案過程中,因為資料庫處於全域性只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。

5、當 innobackupex 拷貝完所有非 InnoDB 表文件後,通知 xtrabackup(通過刪檔案) ,同時自己進入等待(等待 xtrabackup_log_copied 檔案被建立)。

6、xtrabackup 收到 innobackupex 備份完非 InnoDB 通知後,就停止 redo 拷貝執行緒,然後通知 innobackupex redo log 拷貝完成(通過建立檔案)。

7、innobackupex 收到 redo 備份完成通知後,就開始解鎖,執行 UNLOCK TABLES(解鎖)。

8、最後 innobackupex 和 xtrabackup 程序各自完成收尾工作,如資源的釋放、寫備份元資料資訊等,innobackupex 等待 xtrabackup 子程序結束後退出。

注:在上面描述的檔案拷貝,都是備份程序直接通過作業系統讀取資料檔案的,只在執行 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。
1、恢復的目的是把備份集中的資料恢復到一個一致性位點,所謂一致就是指原資料庫某一時間點各引擎資料的狀態,比如 MyISAM 中的資料對應的是 15:00 時間點的,InnoDB 中的資料對應的是 15:20 的,這種狀態的資料就是不一致的。PXB 備份集對應的一致點,就是備份時FTWRL的時間點,恢復出來的資料,就對應原資料庫FTWRL時的狀態。

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

3、所以恢復過程只涉及 InnoDB 檔案的恢復,非 InnoDB 資料是不動的。備份恢復完成後,就可以把資料檔案拷貝到對應的目錄,然後通過mysqld來啟動了。