MariaDB/MySQL備份和恢復(三):xtrabackup用法和原理詳述


MariaDB/MySQL備份恢復系列:
備份和恢復(一):mysqldump工具用法詳述
備份和恢復(二):導入、導出表數據
備份和恢復(三):xtrabackup用法和原理詳述


xtrabackup是percona團隊研發的備份工具,比MySQL官方的ibbackup的功能還要多。支持myisam溫全備、innodb熱全備和溫增備,還可以實現innodb的定時點恢復,而且備份和恢復的速度都較快。在目前MySQL的備份實現上,考慮價格、速度、安全、一致性等角度,xtrabackup是非常合適的工具。

MariaDB也可以使用percona xtrabackup進行備份,不過MariaDB基於percona xtrabackup開發了它自己的備份工具:MariaDB Backup。它基於xtrabackup開發,所以所用方法基本和xtrabackup相同,只是有些自己的特性。詳細內容見MariaDB Backup官方手冊:https://mariadb.com/kb/en/library/mariadb-backup/

xtrabackup官方手冊:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html

1.安裝xtrabackup

下載地址:https://www.percona.com/downloads/XtraBackup/LATEST/

rpm倉庫(實際上是percona的倉庫):http://repo.percona.com/release/

清華大學percona源:https://mirrors.tuna.tsinghua.edu.cn/percona/

因為只是一個備份工具,所以沒必要編譯安裝,直接下載它的rpm包即可。但是該rpm包依賴於libev.so.4,該依賴包可以在epel源中找到。

這里安裝的是目前最新版的xtrabackup-24-2.4.11。

cat <<eof>>/etc/yum.repos.d/percona.repo
[percona]
name = Percona
baseurl = https://mirrors.tuna.tsinghua.edu.cn/percona/release/\$releasever/RPMS/\$basearch
enabled = 1
gpgcheck = 0

[epel]
name=epelrepo
baseurl=https://mirrors.aliyun.com/epel/\$releasever/\$basearch
gpgcheck=0
enable=1
eof
[root@node1 ~]# yum list all| grep xtraback -i
Repository epel is listed more than once in the configuration
holland-xtrabackup.noarch                      1.0.14-3.el6                 epel
percona-xtrabackup.x86_64                      2.3.10-1.el6                 percona
percona-xtrabackup-20.x86_64                   2.0.8-587.rhel6              percona
percona-xtrabackup-20-debuginfo.x86_64         2.0.8-587.rhel6              percona
percona-xtrabackup-20-test.x86_64              2.0.8-587.rhel6              percona
percona-xtrabackup-21.x86_64                   2.1.9-746.rhel6              percona
percona-xtrabackup-21-debuginfo.x86_64         2.1.9-746.rhel6              percona
percona-xtrabackup-22.x86_64                   2.2.13-1.el6                 percona
percona-xtrabackup-22-debuginfo.x86_64         2.2.13-1.el6                 percona
percona-xtrabackup-24.x86_64                   2.4.11-1.el6                 percona
percona-xtrabackup-24-debuginfo.x86_64         2.4.11-1.el6                 percona
percona-xtrabackup-debuginfo.x86_64            2.3.10-1.el6                 percona
percona-xtrabackup-test.x86_64                 2.3.10-1.el6                 percona
percona-xtrabackup-test-21.x86_64              2.1.9-746.rhel6              percona
percona-xtrabackup-test-22.x86_64              2.2.13-1.el6                 percona
percona-xtrabackup-test-24.x86_64              2.4.11-1.el6                 percona

[root@node1 ~]# yum -y install percona-xtrabackup-24

裝完xtrabackup后,生成以下幾個工具。

[root@node1 ~]# rpm -ql percona-xtrabackup-24 | grep bin | xargs ls -hl
lrwxrwxrwx 1 root root   10 May  8 19:19 /usr/bin/innobackupex -> xtrabackup
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcloud
-rwxr-xr-x 1 root root 3.0K Apr 19 01:04 /usr/bin/xbcloud_osenv
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcrypt
-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbstream
-rwxr-xr-x 1 root root  21M Apr 19 01:11 /usr/bin/xtrabackup
  • xbcloud和xbcloud_osenv是xtrabackup新的高級特性:雲備份;
  • xbcrypt也是新的特性,加密備份集;
  • xbstream是xtrabackup的流數據功能,通過流數據功能,可將備份內容打包並傳給管道后的壓縮工具進行壓縮;
  • xtrabackup是主程序;
  • innobackupex在以前是一個perl腳本,會調用xtrabackup這個二進制工具,從xtrabackup 2.3開始,該工具使用C語言進行了重寫,當前它是xtabackup二進制工具的一個軟連接,但是實際的使用方法卻不同,並且在以后的版本中會刪除該工具。

在本文中,會分別對兩個主程序innobackupex和xtrabackup的備份恢復方法進行詳細的說明,還會在說明過程中盡可能的解釋它們是如何工作的,另外還會介紹它們的一些特殊功能的選項,如流備份選項。

2.備份鎖

一篇不錯的介紹xtrabackup鎖的文章:https://www.percona.com/blog/2014/03/11/introducing-backup-locks-percona-server-2/

percona Server 5.6+ 支持一種新鎖——backup lock(備份鎖),這種鎖是percona對MySQL的補充,專門為備份而設計。這種鎖在percona Server 5.6+ 有,MariaDB中也有,但是Oracle的MySQL中沒有,至少MySQL 5.7中沒有。

這種鎖用在備份的時候替代 flush tables with read lock 獲取全局鎖,是一種輕量級的全局鎖。它有兩種類型的鎖:備份表鎖和二進制日志鎖。為此新增了3種語法:

lock tables for backup   # 申請備份表鎖
lock binlog for backup   # 申請二進制日志鎖
unlock binlog            # 釋放二進制日志鎖

備份表鎖在全局范圍內只對非innodb表加鎖,所以持有該鎖后無法修改非innodb表,但卻不影響innodb表的DML。當然,因為是全局鎖,所以也會阻塞DDL操作。

二進制日志鎖在全局范圍內鎖定二進制日志,所以會阻塞其他會話修改二進制日志。這樣可以保證能夠獲取到二進制日志中一致性的位置坐標。 

3.xtrabackup備份原理說明

不管是使用innobackupex還是xtrabackup工具進行備份和恢復,都有3個步驟:備份(backup)、准備(prepare)、恢復(copy back)。

注意,xtrabackup備份過程中,先備份innodb表,再備份非innodb表。

3.1 備份過程(backup階段)

(1).在啟動xtrabackup時記下LSN並將redo log拷貝到備份目標目錄下的xtrabackup_logfile文件中。由於拷貝需要一定時間,如果在拷貝時間段內有日志寫入,將導致拷貝的日志和MySQL的redo log不一致,所以xtrabackup還有一個后台進程監控着mysql的redo log,每秒監控一次,當MySQL的redo log有變化,該監控進程會立即將變化的內容寫入到xtrabackup_logfile文件,這樣就能保證拷貝走的redo log中記錄了一切變化。但是這也是有風險的,因為redo是輪訓式循環寫入的,如果某一時刻有非常大量的日志寫到redo log中,使得還沒開始復制的日志就被新日志覆蓋了,這樣會日志丟失,並報錯。

(2).拷貝完初始版的redo log后,xtrabackup開始拷貝innodb表的數據文件(即表空間文件.ibd文件和ibdata1)。注意,此時不拷貝innodb的frm文件。

(3).當innodb相關表的數據文件拷貝完成后,xtrabackup開始准備拷貝非innodb的文件。但在拷貝它們之前,要先對非innodb表進行加鎖防止拷貝時有語句修改這些類型的表數據。

對於不支持backup lock的版本,只能通過flush tables with read lock來獲取全局讀鎖,但這樣也同樣會鎖住innodb表,殺傷力太大。所以使用xtrabackup備份Oracle的MySQL,實質上只能實現innodb表的部分時間熱備、部分時間溫備。

對於支持backup lock的版本,xtrabackup通過lock tables for backup獲取輕量級的backup locks來替代flush tables with read lock,因為它只鎖定非innodb表,所以由此實現了innodb表的真正熱備。

(4).當獲取到非innodb表的鎖以后,開始拷貝非innodb表的數據和.frm文件。當這些拷貝完成之后,繼續拷貝其他存儲引擎類型的文件。(實際上,拷貝非innodb表的數據是在獲取backup locks(如果支持)后自動進行的,它們屬於同一個過程)

(5).當拷貝階段完成后,就到了備份的收尾階段。包括獲取二進制日志中一致性位置的坐標點、結束redo log的監控和拷貝、釋放鎖等。

對於不支持backup lock的版本,收尾階段的過程是這樣的:獲取二進制日志的一致性坐標點、結束redo log的監控和拷貝、釋放鎖。

對於支持backup lock的版本,收尾階段的過程是這樣的:先通過lock binlog for bakcup來獲取二進制日志鎖,然后結束redo log的監控和拷貝,再unlock tables釋放表鎖,隨后獲取二進制日志的一致性位置坐標點,最后unlock binlog釋放二進制日志鎖。

(6).如果一切都OK,xtrabackup將以狀態碼0退出。

所以,對是否支持backup lock的版本,xtrabackup備份的時的行為是不一樣的。

backup階段的過程具體如下圖所示:

FTWRL:flush table with read lock;

3.2 准備過程(prepare階段)

由於備份的時候拷貝走的數據文件可能是不一致的,比如監控着MySQL的redo log中在拷貝過程完成后又新的事務提交了,而拷貝走的數據是未提交狀態的,那么就需要對該事務前滾;如果監控到的日志中有事務未提交,那么該事務就需要回滾。

但是如果只備份了myisam表或其他非事務表數據,因為備份階段直接鎖定了這些表,所以不會有不一致的狀態。

xtrabackup有一個"准備"的階段。這個階段的實質就是對備份的innodb數據應用redo log,該回滾的回滾,該前滾的前滾,最終保證xtrabackup_logfile中記錄的redo log已經全部應用到備份數據頁上,並且實現了一致性。當應用結束后,會重寫"xtrabackup_logfile"再次保證該redo log和備份的數據是對應的。

准備過程不需要連接數據庫,該過程可以在任意裝了xtrabackup軟件的機器上進行,之所能實現是因為xtrabackup軟件的內部嵌入了一個簡化的innodb存儲引擎,可以通過它完成日志的應用。

3.3 恢復過程(copy back階段)

xtrabackup的恢復過程實質是將備份的數據文件和結構定義等文件拷貝回MySQL的datadir。同樣可以拷貝到任意機器上。

要求恢復之前MySQL必須是停止運行狀態,且datadir是空目錄,除非恢復的操作是導入表的操作。具體見后文對應的內容。

4.准備實驗環境

創建測試數據庫backuptest,並創建myisam表和innodb表,此處簡單的使用數值輔助表並分別插入1億條數據。

DROP DATABASE IF EXISTS backuptest;
CREATE DATABASE backuptest;
USE backuptest;

# 創建myisam類型的數值輔助表和對應插入數據的存儲過程
CREATE TABLE num_isam(n INT NOT NULL PRIMARY KEY)ENGINE=MYISAM;
DELIMITER $$
DROP PROCEDURE IF EXISTS proc_num1$$
CREATE PROCEDURE proc_num1(num INT) 
BEGIN
    DECLARE rn INT DEFAULT 1;
    TRUNCATE TABLE backuptest.num_isam;
    INSERT INTO backuptest.num_isam VALUES(1);
    dd: WHILE rn*2 < num DO
        BEGIN
            INSERT INTO backuptest.num_isam SELECT rn+n FROM backuptest.num_isam;
            SET rn = rn*2;
        END;
    END WHILE dd;
    INSERT INTO backuptest.num_isam SELECT n+rn FROM num_isam WHERE n+rn <=num;
END;$$
DELIMITER ;

# 創建innodb類型的數值輔助表和對應插入數據的存儲過程
CREATE TABLE num_innodb(n INT NOT NULL PRIMARY KEY)ENGINE=INNODB;
DELIMITER $$
DROP PROCEDURE IF EXISTS proc_num2$$
CREATE PROCEDURE proc_num2(num INT) 
BEGIN
    DECLARE rn INT DEFAULT 1;
    TRUNCATE TABLE backuptest.num_innodb;
    INSERT INTO backuptest.num_innodb VALUES(1);
    dd: WHILE rn*2 < num DO
        BEGIN
            INSERT INTO backuptest.num_innodb SELECT rn+n FROM backuptest.num_innodb;
            SET rn = rn*2;
        END;
    END WHILE dd;
    INSERT INTO backuptest.num_innodb SELECT n+rn FROM backuptest.num_innodb WHERE n+rn <=num;
END;$$
DELIMITER ;

# 分別向兩個數值輔助表中插入1億條數據,
CALL proc_num1(100000000);
CALL proc_num2(100000000);

5.innobackupex工具

5.1 innobackupex實現全備份和恢復的過程

(1). 全備

除了給定連接MySQL服務器的連接參數,只需再給定一個目錄即可,該目錄是備份的目標位置。默認xtrabackup連接數據庫的時候從配置文件中去讀取和備份相關的配置,可以使用選項--defaluts-file指定連接時的參數配置文件,但如果指定該選項,該選項只能放在第一個選項位置。

innobackupex --user=root --password=123456 /bakdir/

默認備份的路徑是指定路徑/bakdir下的一個以時間為時間戳的目錄。

[root@xuexi bakdir]# du -sh /bakdir/2017-04-02_07-09-47/*
4.0K    /bakdir/2017-04-02_07-09-47/backup-my.cnf
4.0G    /bakdir/2017-04-02_07-09-47/backuptest
589M    /bakdir/2017-04-02_07-09-47/ibdata1
1.8M    /bakdir/2017-04-02_07-09-47/mysql
8.0K    /bakdir/2017-04-02_07-09-47/Performance
636K    /bakdir/2017-04-02_07-09-47/performance_schema
1008K   /bakdir/2017-04-02_07-09-47/world
4.0K    /bakdir/2017-04-02_07-09-47/xtrabackup_binlog_info
4.0K    /bakdir/2017-04-02_07-09-47/xtrabackup_checkpoints
4.0K    /bakdir/2017-04-02_07-09-47/xtrabackup_info
4.0K    /bakdir/2017-04-02_07-09-47/xtrabackup_logfile

查看該文件目錄中文件和大小,可以看出xtrabackup的行為就是復制了目標數據庫的相關文件,並新建了幾個文件。

其中:

  • backup-my.cnf是拷貝過來的配置文件。里面只包含[mysqld]配置片段和備份有關的選項。
  • xtrabackup_binlog_info中記錄的是當前使用的二進制日志文件。

    [root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_binlog_info 
    mysql-bin.000001        120
    
  • xtrabackup_checkpoints中記錄了備份的類型是全備還是增備,還有備份的起始、終止LSN號。

    [root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_checkpoints 
    backup_type = full-backuped
    from_lsn = 0
    to_lsn = 7533359841
    last_lsn = 7533359841
    compact = 0
    recover_binlog_info = 0
    
  • xtrabackup_info中記錄的是備份過程中的一些信息。

    [root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_info 
    uuid = 66f34974-1730-11e7-9d09-000c299af3f3
    name = 
    tool_name = innobackupex
    tool_command = --user=root --password=...  /bakdir/
    tool_version = 2.4.6
    ibbackup_version = 2.4.6
    server_version = 5.6.35-log
    start_time = 2017-04-02 07:09:47
    end_time = 2017-04-02 07:10:31
    lock_time = 0
    binlog_pos = filename 'mysql-bin.000001', position '120'
    innodb_from_lsn = 0
    innodb_to_lsn = 7533359841
    partial = N          # N表示未啟用該方面的功能,如此處表示不是備份部分數據庫或表
    incremental = N
    format = file
    compact = N
    compressed = N
    encrypted = N
    
  • xtrabackup_logfile是復制和監控后寫的redo日志。該日志是備份后下一個操作"准備"的關鍵。只有通過它才能實現數據一致性。

(2). 全備的准備過程

在全備份完成之后,備份的數據中如果有innodb數據,則還不能用來恢復。因為從xtrabackup開始備份的時候就監控着MySQL的redo log,在拷貝的innodb數據文件中很可能還有未提交的事務,並且拷貝完innodb數據之后還可能提交了事務或者開啟了新的事務等等。總之,全備之后的狀態不一定是一致的。但是如果只備份了myisam表或其他非事務表數據,因為備份階段直接鎖定了這些表,所以不會有不一致的狀態。

xtrabackup有一個"准備"的階段。這個階段的實質就是對備份的innodb數據應用redo log,該回滾的回滾,該前滾的前滾,最終保證xtrabackup_logfile中記錄的redo log已經全部應用到備份數據頁上,並且實現了一致性。當應用結束后,會重寫"xtrabackup_logfile"再次保證該redo log和備份的數據是對應的。

例如,備份的innodb數據文件中存在未提交的事務,但是在監控到的日志中進行了提交,那么就需要對該事務前滾;如果監控到的日志中有事務未提交,那么該事務就需要回滾。

准備階段使用的模式選項是"--apply-log"。准備階段不會連接MySQL,所以不用指定連接選項如--user等。

[root@xuexi bakdir]# innobackupex --apply-log /bakdir/2017-04-02_07-09-47/

在准備成功時,會在頻幕上輸出如下提示內容:

InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 7533367063
170402 12:11:23 completed OK!

在准備階段,有一個內存使用量選項"--use-memory",該選項默認值為100M,值越大准備的過程越快。當然,將該值加大的前提是服務器內存夠用。

(3). 全備份的恢復過程

恢復的階段就是向MySQL的datadir拷貝。全備份的恢復要求MySQL必須處於stop狀態,並且datadir必須為空哪怕是和MySQL無關的文件也不能存在,它不會去覆蓋datadir中已存在的內容。否則會提示如下錯誤:

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)
Original data directory /mydata/data is not empty!

停止mysql並清空datadir。

service mysqld stop
rm -rf /mydata/data/*

恢復時使用的模式是"--copy-back",選項后指定要恢復的源備份目錄。恢復時因為不需要連接數據庫,所以不用指定連接選項,如--user等。

[root@xuexi bakdir]# innobackupex --copy-back /bakdir/2017-04-02_07-09-47/
170402 12:36:09 completed OK!

拷貝完成后,MySQL的datadir的文件的所有者和屬組是innobackupex的調用者,所以需要改回mysql.mysql。

[root@xuexi bakdir]# ll /mydata/data/
total 712736
drwxr-x--- 2 root root      4096 Apr  2 12:36 backuptest
-rw-r----- 1 root root 616562688 Apr  2 12:35 ibdata1
-rw-r----- 1 root root  50331648 Apr  2 12:35 ib_logfile0
-rw-r----- 1 root root  50331648 Apr  2 12:35 ib_logfile1
-rw-r----- 1 root root  12582912 Apr  2 12:36 ibtmp1
drwxr-x--- 2 root root      4096 Apr  2 12:36 mysql
drwxr-x--- 2 root root      4096 Apr  2 12:35 Performance
drwxr-x--- 2 root root      4096 Apr  2 12:36 performance_schema
drwxr-x--- 2 root root      4096 Apr  2 12:35 world
-rw-r----- 1 root root        23 Apr  2 12:35 xtrabackup_binlog_pos_innodb
-rw-r----- 1 root root       494 Apr  2 12:35 xtrabackup_info

[root@xuexi bakdir]# chown -R mysql.mysql /mydata/data/*

完成這些之后,就可以啟動MySQL服務器了。可以進入mysql測試backuptest數據庫中的數據是否完整。

5.2 innobackupex實現增量備份和恢復的過程

增量備份依賴於全備份。xtrabackup實現增量備份的原理是通過比較全備份的終點LSN和當前的LSN,增備時將從終點LSN開始一直備份到當前的LSN。在備份時也有redo log的監控線程,對於增備過程中導致LSN增長的操作也會寫入到日志中。

增備的實現依賴於LSN,所以只對innodb有效,對myisam表使用增備時,背后進行的是全備。

(1). 要進行增備,首先要有全備文件。這里重新進行一次全備。

innobackupex --user=root --password=123456 /bakdir/

全備完成后,在/bakdir目錄下生成的全備目錄是2017-04-02_13-26-35。

[root@xuexi ~]# ls /bakdir/2017-04-02_13-26-35/
backup-my.cnf  ibdata1  Performance         secure_dir  xtrabackup_binlog_info  xtrabackup_info
backuptest     mysql    performance_schema  world       xtrabackup_checkpoints  xtrabackup_logfile

查看xtrabackup_checkpoints可以得知相關的LSN。

[root@xuexi ~]# cat /bakdir/2017-04-02_13-26-35/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 7533367093
last_lsn = 7533367093
compact = 0
recover_binlog_info = 0

注意:要實現增備,這一次的全備一定不能進行"准備"操作,原因稍后給出。

(2). 進行第一次增備。

假設對示例數據可backuptest中的num_innodb表進行了truncate操作。

mysql> truncate backuptest.num_innodb;

然后再增備。增備時使用"--incremental"選項表示增量備份,增量備份時需要通過"--incremental-basedir=fullback_PATH"指定基於哪個備份集備份,因為是第一次增備,所以要基於完全備份增量集。

[root@xuexi ~]# innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-basedir=/bakdir/2017-04-02_13-26-35/

增備完成后,生成的增備集為/bakdir/2017-04-02_13-39-05/,查看其中的xtrabackup_checkpoints,可以看到備份的起始LSN是上次全備完成后的LSN。

[root@xuexi ~]# cat /bakdir/2017-04-02_13-39-05/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 7533367093
to_lsn = 7533372535
last_lsn = 7533372535
compact = 0
recover_binlog_info = 0

默認情況下,增備的起始LSN是自動獲取的,但是在某些情況下無法獲取,還有些情況下無法獲取到將要增備的basedir。xtrabackup提供的選項"--incremental-lsn=N"可以顯式指定增備的起始LSN,顯式指定LSN時,可以無需提供增備的basedir。

例如,如果獲取到了上次全備的終止LSN為7533367093,可以如下方式增備:

innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-lsn=7533367093

這樣增備后也在/bakdir中生成一個時間戳目錄/bakdir/2017-04-02_13-50-33。查看LSN信息:

[root@xuexi ~]# cat /bakdir/2017-04-02_13-50-33/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 7533367093
to_lsn = 7533372535
last_lsn = 7533372535
compact = 0
recover_binlog_info = 0

由此可知和指定--incremental-basedir進行增備是一樣的。

(3). 進行第二次增備。

假設在第一次增備后,向上次truncate的表backuptest.num_innodb表中插入的100W條記錄。

mysql> call backuptest.proc_num2(1000000);      
mysql> select count(*) from backuptest.num_innodb;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+

然后進行增備。這次增備是基於第一次增備的(當然也可以基於全備進行備份,這樣實現的是差異備份)。

[root@xuexi ~]# innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-basedir=/bakdir/2017-04-02_13-39-05/

這次增備完成后生成的備份集為/bakdir/2017-04-02_14-03-51/。查看LSN信息:

[root@xuexi ~]# cat /bakdir/2017-04-02_14-03-51/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 7533372535
to_lsn = 7585150275
last_lsn = 7585150275
compact = 0
recover_binlog_info = 0

(4). 增備的准備過程

增備的准備過程和全備的准備過程有點不一樣,不到最后恢復的時候不能進行任何"准備"過程。

增備過程中的每一次備份行為都會監控MySQL的redo log,寫入到xtrabackup_logfile的日志中可能會有未提交的事務,但是到后面增備的時候進行了提交,也就是說提交過程記錄到了增備時監控的日志xtrabackup_logfile中。如果在增備前進行了"准備",那么該事務就會被回滾,后面增備中的提交就丟失了,由此會造成數據丟失。

要保證將所有的備份集進行整合,需要使用在每個備份集的"准備"過程中使用"--redo-only"選項,這樣應用日志時會"直線向前"直到最后一個備份集。它的本質是向全備集中不斷的追加應用增備中的日志。但是,最后一個增備集需要作為備份集整合的終點,所以它不能使用"--redo-only"選項。整合完成之后,原來的全備就已經完整了,這時再對追加完成的全備集進行一次"准備"即可用於后面的恢復。

所以,如果全備為A,3次增備分別為B/C/D,如果只想恢復到C,那么從A開始整合到C結束即可。

因為在每一個增備的"准備"過程中都需要向整合的開始備份集中追加應用日志,所以每一次增備的"准備"都需要指定整合的開始備份集目錄作為basedir。例如指定全備份作為整合的初始備份集。

從以上實驗過程中,得到的全備集是2017-04-02_13-26-35,第一次和第二次增備集分別是2017-04-02_13-26-35、2017-04-02_14-03-51。下面是它們的"准備"過程。

# 對整合的開始備份集——全備集應用日志,並指定"--redo-only"表示開始進入日志追加
innobackupex --apply-log --redo-only /bakdir/2017-04-02_13-26-35

# 對第一個增備集進行"准備",將其追加到全備集中
innobackupex --apply-log --redo-only /bakdir/2017-04-02_13-26-35 --incremental-dir=/bakdir/2017-04-02_13-39-05

# 對第二個增備集進行"准備",將其追加到全備集中,但是不再應用"--redo-only",表示整合的結束點
innobackupex --apply-log /bakdir/2017-04-02_13-26-35 --incremental-dir=/bakdir/2017-04-02_14-03-51

# 對整合完成的全備集進行一次整體的"准備"
innobackupex --apply-log /bakdir/2017-04-02_13-26-35

當所有的備份集整合完畢后,就像是一個完整的全備集,全備中的LSN會更新到整合的結束點。如下:

[root@xuexi data]# cat /bakdir/2017-04-02_13-26-35/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 7585150275  #整合完成后全備中的LSN
last_lsn = 7585150275
compact = 0
recover_binlog_info = 0

[root@xuexi data]# cat /bakdir/2017-04-02_14-03-51/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 7533372535
to_lsn = 7585150275       #整合的結束備份集中的LSN
last_lsn = 7585150275
compact = 0
recover_binlog_info = 0

如果不小心整合的順序錯誤了,那么整合的備份集將是無效的,需要重新整合。

(5). 增備的恢復過程

因為整合結束后就等價於一個全備集,所以可以直接進行恢復。

恢復過程同樣需要保證MySQL的datadir是空的,且MySQL服務器是stop的。

service mysqld stop
rm -rf /mydata/data/*
innobackupex --copy-back /bakdir/2017-04-02_13-26-35
chown -R mysql.mysql /mydata/data/*

然后重啟MySQL,進入查看可知num_innodb的數據為100W行記錄,即恢復成功。

mysql> select count(*) from backuptest.num_innodb;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+

5.3 innobackupex實現導出和導入單張表的過程

默認情況下,InnoDB表不能通過直接復制表文件的方式在mysql服務器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實現此種功能,不過只能"導出"具有.ibd文件的表,也就是說導出表的mysql服務器啟用了innodb_file_per_table選項,而且要導出的表還是在啟用該選項之后才創建的。

導入表的是,要求導入表的服務器版本是MySQL 5.6+,且啟用了innodb_file_per_table選項。

(1). 導出表

導出表是在"准備"的過程中進行的,不是在備份的時候導出。對於一個已經備份好的備份集,使用"--apply-log"和"--export"選項即可導出備份集中的表。

假如以全備份集/bakdir/2017-04-02_17-41-38為例,要導出其中的表。

innobackupex --apply-log --export /bakdir/2017-04-02_17-41-38

在導出過程中,會看到如下信息:

xtrabackup: export metadata of table 'backuptest/num_innodb' to file `./backuptest/num_innodb.exp` (1 indexes)
xtrabackup:     name=PRIMARY, id.low=144, page=3

它說明了創建了一個.exp文件。

查看備份集目錄下的backuptest目錄,會發現多出了2個文件:.cfg和.exp,再加上.ibd文件,這3個文件是后續導入表時所需的文件。

-rw-r--r-- 1 root root  349 Apr  2 18:15 num_innodb.cfg
-rw-r----- 1 root root  16K Apr  2 18:15 num_innodb.exp
-rw-r----- 1 root root 8.4K Apr  2 17:41 num_innodb.frm
-rw-r----- 1 root root  31M Apr  2 17:41 num_innodb.ibd

其中.cfg文件是一種特殊的innodb數據字典文件,它和exp文件的作用是差不多的,只不過后者還支持在xtradb中導入,嚴格地講,要將導出的表導入到MySQL5.6或者percona server 5.6中,".cfg"文件完全可以不需要,但是如果有該文件的話,會進行架構驗證。

(2). 導入表

要在mysql服務器上導入來自於其它服務器的某innodb表,需要先在當前服務器上創建一個跟原表表結構一致的表,而后才能實現將表導入:

mysql> CREATE TABLE tabletest (...)  ENGINE=InnoDB;

然后將此表的表空間:

mysql> ALTER TABLE mydatabase.tabletest  DISCARD TABLESPACE;

接下來,將來自於"導出"表的的.ibd和.exp文件復制到當前服務器的數據目錄,如果導入目標服務器是MySQL 5.6+,也可以復制.cfg文件。然后使用如下命令將其“導入”:

mysql> ALTER TABLE mydatabase.tabletest IMPORT TABLESPACE;

5.4 innobackupex實現部分備份和恢復的過程

xtrabackup支持部分備份,意味着可以指定備份哪個數據庫或者哪個表。

部分備份只有一點需要注意:在恢復的時候不要通過"--copy-back"的方式拷貝回datadir,而是應該使用導入表的方式。盡管使用拷貝的方式有時候是可行的,但是很多情況下會出現數據庫不一致的狀態。

(1). 備份

創建部分備份有三種方式:

  1.  通過"--include"選項可以指定正則來匹配要備份的表,這種方式要使用完整對象引用格式,即db_name.tab_name的方式。
  2. 將要備份的表分行枚舉到一個文件中,通過"--tables-file"指定該文件。
  3. 或者使用"--databases"指定要備份的數據庫或表,指定備份的表時要使用完整對象引用格式,多個元素使用空格分開。

使用前兩種部分備份方式,只能備份innodb表,不會備份任何myisam,即使指定了也不會備份。而且要備份的表必須有獨立的表空間文件,也就是說必須開啟了innodb_file_per_table,更精確的說,要備份的表是在開啟了innodb_file_per_table選項之后才創建的。第三種備份方式可以備份myisam表。

例如 --include='^back.*[.]num_*' ,將備份back字母開頭的數據庫中num開頭的表,其中"[.]"的中括號不能少,因為正則中"."有特殊意義,所以使用中括號來枚舉以實現對象的完整引用。

innobackupex --user=root --password=123456 --include='^back*[.]num_*' /bakdir/

使用"--include"和"--tables-file"備份后,會生成一個時間戳目錄,目錄中只有和要備份的表有關的文件。

[root@xuexi data]# ls /bakdir/2017-04-02_17-35-46/
backup-my.cnf  ibdata1  xtrabackup_binlog_info  xtrabackup_checkpoints  xtrabackup_info  xtrabackup_logfile

如果使用的是--databases選項,則會生成一個時間戳目錄,里面有備份的數據庫代表的目錄,如果只備份了某個表,則該數據庫目錄中只有該表相關的文件。

innobackupex --user=root --password=123456 --databases='mysql.user backuptest' /bakdir/

上面只備份mysql.user表和backuptest數據庫,在生成的時間戳目錄中將有兩個mysql目錄和backuptest目錄。

[root@xuexi data]# ls /bakdir/2017-04-02_17-41-38/
backup-my.cnf  backuptest  ibdata1  mysql  xtrabackup_binlog_info  xtrabackup_checkpoints  xtrabackup_info  xtrabackup_logfile

[root@xuexi data]# ls /bakdir/2017-04-02_17-41-38/backuptest/
db.opt  num_innodb.frm  num_innodb.ibd  num_isam.frm  num_isam.MYD  num_isam.MYI

[root@xuexi data]# ls /bakdir/2017-04-02_17-41-38/mysql/
user.frm  user.MYD  user.MYI

(2). 部分備份的准備和恢復過程

部分備份的准備和恢復過程分別是導出表和導入表的過程。見上文。 

5.5 innobackupex實現定時點恢復

xtrabackup本身無法實現定時點恢復,只能通過恢復備份后通過二進制日志實現。實現方法和一般定時點恢復是一樣的。見:二進制日志定點還原數據庫

5.6 流備份和遠程備份

xtrabackup支持備份流,當前可用的流類型只有tar和xtrabackup自帶的xbstream,通過流可以將它們傳遞給其他程序進行相關的操作,如壓縮。但是不建議在備份的同時進行壓縮,因為壓縮會占用極大的cpu資源,使得備份時間延長很多,溫備的過程也就延長了。

另外,MySQL的數據文件壓縮比非常大,所以建議備份后在空閑的時候進行壓縮。

xtrabackup還支持遠程備份,只需使用"--remote-host"指定遠程的主機名即可,指定方式和ssh指定的方式一樣。如--remote-host=root@192.168.100.18。

使用流備份的方法如下:

# 使用tar流
innobackupex --user=root --password=123456 --stream=tar /bakdir/ >/tmp/a.tar
# 使用tar流的同時交給gzip壓縮
innobackupex --user=root --password=123456 --stream=tar /bakdir/ | gzip >/tmp/a.tar.gz
# 使用tar流備份到遠程主機中並歸檔
innobackupex --user=root --password=123456 --stream=tar /bakdir/ | ssh root@192.168.100.10  "cat -  > /tmp/`date +%F_%H-%M-%S`.tar"
# 使用tar流備份到原遠程主機中並解包
innobackupex --user=root --password=123456 --stream=tar /bakdir/ | ssh root@192.168.100.10  "cat -  | tar -x -C /tmp/"

# 使用xtrabackup自帶的xbstream流
innobackupex --user=root --password=123456 --stream=xbstream /bakdir/ >/tmp/b.xbs
# 解壓xbstream流
innobackupex --user=root --password=123456 --stream=xbstream /bakdir/ | ssh root@192.168.100.10  "cat -  | xbstream -x -C /tmp/"
# 使用xbstream流的同時進行壓縮,使用"--compress"選項
innobackupex --user=root --password=123456 --stream=xbstream --compress /bakdir/ > /bakdir/backup.xbs

注意,如果在解壓備份的.tar.gz時出錯,可能在解壓的時候需要使用-i選項。如tar -xif /tmp/b.tar/gz。

5.7 加速備份

當備份到本地的時候,可以使用"--rsync"選項,該選項用於在flush tables with read lock后調用rsync替代cp進程復制非Innodb數據和.frm文件,加快復制速度。

但要注意,因為支持備份鎖的版本在獲取到backup locks的時候會自動復制非Innodb數據和.frm文件,所以"--rsync"選項是無效的。

另外,該選項不能和"--stream"選項和"--remote-host"選項同時使用。 

6.xtrabackup工具

xtrabackup工具是C語言編寫的工具,在innobackupex使用C重寫之后,innobackupex是該工具的一個軟鏈接。但是它不能實現innobackupex的所有功能,例如xtrabackup工具沒有恢復功能,而innobackupex有"--copy-back"選項來恢復。

xtrabackup工具有兩種常用運行模式:"--backup"和"--prepare"。還有兩個比較少用的模式:"--stats"和"--print-param"。

由於前文對innobackupex的介紹非常詳細,xtrabackup在功能實現上和它是一樣的。所以下面將簡單介紹。

6.1 xtrabackup實現全備 

(1).備份過程

和innobackupex備份過程不同的是,xtrabackup的備份路徑是由"--target-dir"選項嚴格指定的,如果指定的目錄不存在,它備份的時候不會在target-dir目錄中再創建時間戳子目錄。

[root@xuexi data]# xtrabackup --backup --user=root --password=123456 --datadir=/mydata/data --target-dir=/bakdir/fullback

[root@xuexi data]# ls /bakdir/fullback
backup-my.cnf  ibdata1  Performance         secure_dir  xtrabackup_binlog_info  xtrabackup_info
backuptest     mysql    performance_schema  world       xtrabackup_checkpoints  xtrabackup_logfile

(2).准備過程

xtrabackup --prepare --target-dir=/bakdir/fullback

(3).恢復過程

xtrabackup自身不能恢復,只能通過拷貝備份集的方式來恢復。例如使用rsync或者cp等。

另外,恢復時也一樣要求MySQL是stop狀態,datadir是空目錄。並且拷貝完成后要修改datadir中文件的所有者和屬組為mysql用戶和組。

service mysqld stop
rm -rf /mydata/data/*
rsync -azP /bakdir/fullback/* /mydata/data
chown -R mysql.mysql /mydata/data/*

6.2 xtrabackup實現增備

(1).首先進行全備

xtrabackup --backup --user=root --password=123456 --datadir=/mydata/data --target-dir=/bakdir/base_full

(2).進行第一次增備

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/incr_bak1 --incremental-basedir=/bakdir/base_full --datadir=/mydata/data/

同樣也可以在增備時使用"--incremental-lsn"來指定從哪個lsn開始增量備份,這和innobackupex是一樣的。

(3).進行第二次增備

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/incr_bak2 --incremental-basedir=/bakdir/incr_bak1 --datadir=/mydata/data/

(4).准備過程

准備過程和innobackupex是一樣的,使用"--apply-log-only"來直線向前地應用redo log,同樣,在最后一個增備集的准備過程中不能使用"--apply-log-only"選項。

xtrabackup --prepare --apply-log-only --target-dir=/bakdir/base_full
xtrabackup --prepare --apply-log-only --target-dir=/bakdir/base_full --incremental-dir=/bakdir/incr_bak1
xtrabackup --prepare --target-dir=/bakdir/base_full --incremental-dir=/bakdir/incr_bak2

(5).恢復階段

恢復階段即拷貝階段,和前面全備的恢復階段是一樣的,要求MySQL停止運行,datadir是空目錄,拷貝全備目錄到datadir,修改datadir的所有者和屬組。

6.3 xtrabackup實現部分備份

xtrabackup部分備份和innobackupex不太一樣,innobackupex的部分備份實質上是在已經備份好的備份集上導出導入表,而xtrabackup直接在備份過程中篩選要備份的目標,它不建立在已有的備份集上。

(1).備份過程

  • Ÿxtrabackup使用"--tables"選項對應innobackupex的"--include"選項,它們是一樣的,都是正則匹配完整對象引用名稱。
  • 使用"--tables-file"選項指定枚舉要備份表的列表,每行一個表,表名需要使用完整對象引用名稱。和innobackupex一樣的。
  • Ÿ使用"--databases"和"--databases-file"指定要單獨備份的數據庫或表,后者可以枚舉出要備份的列表。這兩個選項不能使用通配符和正則匹配。

例如:

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/part_bak1 --datadir=/mydata/data/ --tables="^back*[.]num_*"

(2).准備過程

xtrabackup的部分備份的准備要比innobackupex方便的多,直接對備份集進行"--prepare"即可。

xtrabackup --prepare --target-dir=/bakdir/part_bak1


免責聲明!

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



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