Percona-xtrabackup 使用詳解與原理


現在有個需求需要對使用 innodb 的數據庫進行熱備。網上查了很多工具皆推薦 Percona-xtrabackup 於是就仔細了解調研一番。

我們可以前往 https://www.percona.com/downloads/XtraBackup/LATEST/  下載我們需要的 linux 發行版的對應版本。 這里我下載了最近的穩定版本 2.4.12 rpm 包。

使用 tar -zvf 解壓后 得到了好幾個 rpm 文件。 安裝了 percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm 並且提示需要下載 libev-4.24-7.fc29.x86_64.rpm 。

可能還需要安裝 perl dbd:mysql 和 perl(Digest::MD5) 看自己機器缺什么組件。(PS: 千萬別亂刪 centos 下的 perl。可能關聯非常多的組件!

yum install perl-DBD-mysql
yum install perl-Digest-MD5

rpm -ivh libev-4.24-7.fc29.x86_64.rpm
rpm -ivh percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm
 
        

https://fedora.pkgs.org/rawhide/fedora-x86_64/libev-4.24-7.fc29.x86_64.rpm.html 下載對應包。

安裝了通用版本的 libev-4.24-7.fc29.x86_64.rpm 包之后就算成功安裝完成啦!

 

當我們安裝完成之后運行目錄如下:

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

有四個工具可以給我們直接調用。其中最主要的是 innobackupex 和 xtrabackup,前者是一個 perl 腳本,后者是 C/C++ 編譯的二進制。

下面內容來引用於 rds 內核組文章,由於寫得很好原理也很清晰所以直接貼過來做 backup 了。

其中最主要的是 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 命令進行;另外一個原因是我們可能需要保存位點信息。

另外2個工具相對小眾些,xbcrypt 是加解密用的;xbstream 類似於tar,是 Percona 自己實現的一種支持並發寫的流文件格式。兩都在備份和解壓時都會用到(如果備份用了加密和並發)。

本文的介紹的主角是 innobackupex 和 xtrabackup

 

原理

通信方式

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

  • xtrabackup_suspended_1
  • xtrabackup_suspended_2
  • xtrabackup_log_copied

舉個栗子,我們來看備份時 xtrabackup_suspended_2 是怎么來協調2個工具進程的

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

是不是感覺有點不可思議,通過文件是否存在來控制進程,這種方式非常的不靠譜,因為非常容易被外部干擾,比如文件被別人誤刪掉,或者2個正在跑的備份控制文件誤放在同一個目錄下,就等着備份亂掉吧,但是 Percona 就是這么干的。

之所以這么搞,估計主要是因為 perl 和 C 二進制2個進程,沒有既好用又方便的通信方式,搞個協議啥的太麻煩了。但是官方也覺得這種方式不靠譜,11年就搞了個 blueprint 要用C重寫 innobackupex,終於在2.3 版本實現了,innobackupex 功能全部集成到 xtrabackup 里面,只有一個 binary,另外為了使用上的兼容考慮,innobackupex作為 xtrabackup 的一個軟鏈。對於二次開發來說,2.3 擺脫了之前2個進程協作的負擔,架構上明顯要好於之前版本。考慮到 perl + C 這種架構的長期存在,大多數讀者朋友也基本用的2.3之前版本,本文的介紹也是基於老的架構(2.2版本),但是原理和2.3是一樣的,只是實現上的差別。

可以看到在 2.3 之前的版本,都是通過對文件的生成的監控來控制整個備份流程的。

  

 

  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 拷貝完成idb后,通知 innobackupex(通過創建文件),同時自己進入等待(redo 線程仍然繼續拷貝);
  4. innobackupex 收到 xtrabackup 通知后,執行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,然后開始備份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷貝非 InnoDB 文件過程中,因為數據庫處於全局只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
  5. 當 innobackupex 拷貝完所有非 InnoDB 表文件后,通知 xtrabackup(通過刪文件) ,同時自己進入等待(等待另一個文件被創建);
  6. xtrabackup 收到 innobackupex 備份完非 InnoDB 通知后,就停止 redo 拷貝線程,然后通知 innobackupexredo 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),磁盤上的文件也是完整的,所以最終備份集里的數據文件都是寫入完整的。

以上就是 xtrabakcup 工具工作的原理。

下面我們來實際操作一把:

1. 首先去想要存放備份的地方建個文件夾

2. 進行一次全備

innobackupex -uxbackup -pbackup123 /data/backup/backup  # 最好不要加 --no-timestamp 否則不會創建文件夾打包,會直接放在這個目錄下面。不太適合定期全備。

當備份完成之后,我們不能直接使用這些備份進行恢復,我們還需要進行一步 preparing 操作以對其時間點

在使用xtrabackup——backup選項進行備份之后,首先需要准備它以便恢復。數據文件在准備好之前不是時間點一致的,因為它們是在程序運行的不同時間復制的,並且在這一過程中它們可能已經被更改了。如果您試圖用這些數據文件啟動InnoDB,它會檢測到損壞並崩潰,以防止您在損壞的數據上運行。xtrabackup—prepare步驟使文件在某個時刻內完全一致,因此您可以在這些文件上運行InnoDB。

xtrabackup --prepare --target-dir=/data/backups/

使用上面命令對備份完成的副本進行立即 prepare 即可,prepare 之后就可以用這個副本進行恢復了。

如此簡單 一次全備就完成了

 

之后我們執行

移除datadir:
$ mv /data/mysql_data /data/mysql_data.bk
 
恢復數據
$ innobackupex --copy-back /data/backup/backup/
 
修改新datadir的權限
$ chown mysql:mysql -R /data/mysql_data

就可以將我們備份的數據恢復了。

 

我們再來看看局部備份:

增量備份我們需要數據庫設置了 innodb_file_per_table 開啟,讓 pxb 能拿到對應庫的結構才可以。

這里直接貼一個我平時備份用的腳本

#!/usr/bin/env bash
# 備份 mysql
targetDir=/data1/mysql_backup/
innobackupex --lock-wait-timeout=10  --include='^cms_db' -uxxx -pxxx $targetDir
filename=`ls -ltr $targetDir | tail -n 1 | awk '{print $9}'`
innobackupex --apply-log --export $targetDir$filename

這里會把工作做到 preparing 結束

之后恢復需要參考

https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/restoring_individual_tables_ibk.html

按照單個表的規則來進行恢復

Importing tables

To import a table to other server, first create a new table with the same structure as the one that will be imported at that server:

OTHERSERVER|mysql> CREATE TABLE mytable (...) ENGINE=InnoDB; 

then discard its tablespace:

OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE; 

Next, copy mytable.ibd and mytable.exp ( or mytable.cfg if importing to MySQL 5.6) files to database’s home, and import its tablespace:

OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE; 

Set the owner and group of the files:

$ chown -R mysql:mysql /datadir/db_name/table_name.*

After running this command, data in the imported table will be available.

即可。

 

 

Reference:

http://mysql.taobao.org/monthly/2016/03/07/  阿里雲 rds 內核組 Percona-xtrabackup 文章

https://www.percona.com/doc/percona-xtrabackup/2.4/backup_scenarios/full_backup.html  full backup 官方文檔

https://www.aliyun.com/jiaocheng/1106116.html  Percona XtraBackup 備份和還原數據庫

http://www.ttlsa.com/mysql/the-database-part-of-backup-using-percona-xtrabackup/  使用Percona Xtrabackup對數據庫進行部分備份

https://www.linuxidc.com/Linux/2017-03/142380.htm  Percona XtraBackup 實現全備&增量備份與恢復

https://www.cnblogs.com/xinysu/p/6555082.html  說說 redo undo 都在干啥

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM