1. XtraBackup 簡介
XtraBackup(PXB) 工具是 Percona 公司用 perl 語言開發的一個用於 MySQL 數據庫物理熱備的備份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,並且全部開源,真可謂是業界良心。阿里的 RDS MySQL 物理備份就是基於這個工具做的。由於是采取物理拷貝的方式來做的備份,所以速度非常快,幾十G數據幾分鍾就搞定了,而它巧妙的利用了mysql 特性做到了在線熱備份,不用像以前做物理備份那樣必須關閉數據庫才行,直接在線就能完成整庫或者是部分庫的全量備份和增量備份。新版本的xtrabackup改成了cmake安裝,和以前有點不一樣。
版本說明:這里安裝的版本是2.4.6,而2.3.3之后死鎖不再堵塞備份了,如果數據庫是mysql 5.7之后的必須要裝2.4.4才可以用,當然了, 會向下兼容的。
工具集:軟件包安裝后,有以下可執行文件(版本2.4.6)
bin/ ├── innobackupex -> xtrabackup ├── xbcloud ├── xbcloud_osenv ├── xbcrypt ├── xbstream └── xtrabackup
其中最主要的是 innobackupex 和 xtrabackup,前者是一個 perl 腳本,后者是 C/C++ 編譯的二進制。Percona 在2.3 版本用C重寫了 innobackupex ,innobackupex 功能全部集成到 xtrabackup 里面,只有一個 binary,另外為了使用上的兼容考慮,innobackupex 作為 xtrabackup 的一個軟鏈接。對於二次開發來說,2.3 擺脫了之前2個進程協作的負擔,架構上明顯要好於之前版本。(Percona XtraBackup 2.3 發布之后,推薦的備份方法是使用 xtrabackup 腳本。 )
xtrabackup 是用來備份 InnoDB 表的,不能備份非 InnoDB 表,和 mysqld server 沒有交互;innobackupex 腳本用來備份非 InnoDB 表,同時會調用 xtrabackup 命令來備份 InnoDB 表,還會和 mysqld server 發送命令進行交互,如加讀鎖(FTWRL)、獲取位點(SHOW SLAVE STATUS)等。簡單來說,innobackupex 在 xtrabackup 之上做了一層封裝。
一般情況下,我們是希望能備份 MyISAM 表的,雖然我們可能自己不用 MyISAM 表,但是 mysql 庫下的系統表是 MyISAM 的,因此備份基本都通過 innobackupex 命令進行;另外一個原因是我們可能需要保存位點信息。
另外幾個工具相對小眾些,xbcrypt 是加解密備份文件用的;xbstream 類似於tar,是 Percona 自己實現的一種支持並發寫的流文件格式;兩者在備份和解壓時都會用到(如果備份用了加密和並發)。xbcloud 工具的作用是:把全部或部分 xbstream 檔案從雲上下載或上傳到雲。
2. XtraBackup 原理
2.3版本之前 innobackupex 和 xtrabackup 這2個工具之間的交互和協調是通過控制文件的創建和刪除來實現的,2.3版本將 innobackupex 功能全部集成到 xtrabackup 里面,也就不需要他們之間的通信。這里介紹基於老的架構(2.2版本),但是原理和2.3是一樣的,只是實現上的差別。
整個備份過程如下圖:
PXB 備份過程
- innobackupex 在啟動后,會先 fork 一個進程,啟動 xtrabackup進程,然后就等待 xtrabackup 備份完 ibd 數據文件;
- xtrabackup 在備份 InnoDB 相關數據時,是有2種線程的,1種是 redo 拷貝線程,負責拷貝 redo 文件,1種是 ibd 拷貝線程,負責拷貝 ibd 文件;redo 拷貝線程只有一個,在 ibd 拷貝線程之前啟動,在 ibd 線程結束后結束。xtrabackup 進程開始執行后,先啟動 redo 拷貝線程,從最新的 checkpoint 點開始順序拷貝 redo 日志;然后再啟動 ibd 數據拷貝線程,在 xtrabackup 拷貝 ibd 過程中,innobackupex 進程一直處於等待狀態(等待文件被創建)。
- xtrabackup 拷貝完成idb后,通知 innobackupex(通過創建文件),同時自己進入等待(redo 線程仍然繼續拷貝);
- innobackupex 收到 xtrabackup 通知后,執行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,然后開始備份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷貝非 InnoDB 文件過程中,因為數據庫處於全局只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
- 當 innobackupex 拷貝完所有非 InnoDB 表文件后,通知 xtrabackup(通過刪文件) ,同時自己進入等待(等待另一個文件被創建);
- xtrabackup 收到 innobackupex 備份完非 InnoDB 通知后,就停止 redo 拷貝線程,然后通知 innobackupex redo log 拷貝完成(通過創建文件);
- innobackupex 收到 redo 備份完成通知后,就開始解鎖,執行 UNLOCK TABLES;
- 最后 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。
恢復的目的是把備份集中的數據恢復到一個一致性位點,所謂一致就是指原數據庫某一時間點各引擎數據的狀態,比如 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來啟動了。
注:以上原理摘自阿里雲數據庫內核月報。
實現細節 ( Percona官方說明 )
1. 文件權限
因為XtraBackup要從文件系統中復制大量的數據,所以它盡可能地使用 posix_fadvise(),來告訴OS不要緩存讀取到的數據,因為這些數據不會重用到了,從而提升性能。如果一次備份要緩存幾個G的數據,會對OS的虛擬內存造成很大的壓力,其它進程,比如mysqld很有可能被swap出去,這樣系統就會受到很大影響了。xtrabackup 就是通過 posix_fadvise() 來避免這種情況:
posix_fadvise(file,0,0,POSIX_FADV_DONTNEED)
而且, xtrabackup 要求操作系統對源文件進行更多的預讀優化:
posix_fadvise(file,0,0,POSIX_FADV_SEQUENTIAL)
3. 復制數據文件
在備份innodb page的過程中,XtraBackup 每次讀寫1MB的數據,1MB/16KB=64個page。這個不可配置。讀取1MB數據之后,XtraBackup一頁一頁地遍歷這1MB數據,並使用innodb的buf_page_is_corrupted()函數檢查此頁的數據是否正常,如果數據不正常,就重新讀取這一頁,最多重新讀取10次(注意:doublewrite buffer 中的 page 會跳過此檢查)。
在復制 transactions log(redo log) 的時候,每次讀寫512KB的數據。同樣不可以配置。
3. XtraBackup 安裝
系統:CentOS 6.6(Percona 官方建議安裝在 RHEL/CentOS 6.5 及以上的系統)
版本:percona-xtrabackup-24-2.4.6-2.el6.x86_64
- rpm 安裝(下載:https://pan.baidu.com/s/1sl4jByP)
- 二進制安裝/解壓縮安裝(下載:http://pan.baidu.com/s/1c1Vyt3q)
- 編譯安裝
1. rpm 安裝
這種安裝方法比較簡單,只需下載相應的rpm安裝包安裝即可(注意根據提示安裝相應的依賴包)。其中需要的 libev.so.4() 安裝包:https://pan.baidu.com/s/1i4EZfwT
[root@centos6 xtrabackup]# rpm -ivh percona-xtrabackup-24-2.4.6-2.el6.x86_64.rpm warning: percona-xtrabackup-24-2.4.6-2.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY Preparing... ########################################### [100%] 1:percona-xtrabackup-24 ########################################### [100%]
2. 二進制安裝/解壓縮安裝
這種安裝方法也很簡單,不需要安裝依賴,只需解壓安裝文件,為了方便可創建軟連接。
# tar zxvf percona-xtrabackup-2.4.6-Linux-x86_64.tar.gz #解壓目錄下有3個目錄: bin man percona-xtrabackup-2.4-test # mv percona-xtrabackup-2.4.6-Linux-x86_64 /usr/local/xtrabackup # ln -sf /usr/local/xtrabackup/bin/* /usr/bin/ #給命令建個軟連接 [root@centos6 ~]# xtrabackup --version xtrabackup version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
3. 編譯安裝
這種安裝方法比較麻煩,需要安裝很多依賴,也很耗時間,這里就不做介紹了。
4. XtraBackup 備份恢復
待續……