xtrabackup進行MySQL數據庫備份/還原

http://hongge.blog.51cto.com/

使用xtrabackup進行MySQL數據庫備份

前面介紹mysqldump備份方式是採用邏輯備份,其最大的缺陷就是備份和恢復速度都慢,對於一個小於50G的數據庫而言,這個速度還是能接受的,但如果數據庫非常大,那再使用mysqldump備份就不太適合了。

這時就需要一種好用又高效的工具,xtrabackup就是其中一款,號稱免費版的InnoDB HotBackup。

Xtrabackup實現是物理備份,而且是物理熱備

目前主流的有兩個工具可以實現物理熱備:ibbackup和xtrabackup;ibbackup是商業軟件,需要授權,非常昂貴。而xtrabackup功能比ibbackup還要強大,但卻是開源的。因此我們這裏就來介紹xtrabackup的使用。

Xtrabackup提供了兩種命令行工具:

xtrabackup:專用於備份InnoDB和XtraDB引擎的數據;

innobackupex:這是一個perl腳本,在執行過程中會調用xtrabackup命令,這樣用該命令即可以實現備份InnoDB,也可以備份MyISAM引擎的對象。

Xtrabackup是由percona提供的mysql數據庫備份工具,特點:

(1)備份過程快速、可靠;

(2)備份過程不會打斷正在執行的事務;

(3)能夠基於壓縮等功能節約磁盤空間和流量;

(4)自動實現備份檢驗;

(5)還原速度快。

官方鏈接地址:http://www.percona.com/software/percona-xtrabackup;可以下載源碼編譯安裝,也可以下載適合的RPM包或使用yum進行安裝或者下載二進制源碼包。

安裝xtrabackup

1)下載xtrabackup

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/tarball/percona-xtrabackup-2.4.4-Linux-x86_64.tar.gz

2)解壓

# tar zxf percona-xtrabackup-2.4.4-Linux-x86_64.tar.gz

3)進入解壓目錄

# cd percona-xtrabackup-2.4.4-Linux-x86_64/

4)複製bin下的所有程序到/usr/bin

[root@localhost percona-xtrabackup-2.4.4-Linux-x86_64]# cp bin/* /usr/bin/

Xtrabackup中主要包含兩個工具:

xtrabackup:是用於熱備份innodb, xtradb表中數據的工具,支持在線熱備份,可以在不加鎖的情況下備份Innodb數據表,不過此工具不能操作Myisam引擎表;

innobackupex:是將xtrabackup進行封裝的perl腳本,能同時處理Innodb和Myisam,但在處理Myisam時需要加一個讀鎖。

由於操作Myisam時需要加讀鎖,這會堵塞線上服務的寫操作,而Innodb沒有這樣的限制,所以數據庫中Innodb表類型所佔的比例越大,則越有利。

4)安裝相關插件

#yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-TermReadKey.x86_64 perl-Digest-MD5 –y

5)下載percona-toolkit並安裝

#wget https://www.percona.com/downloads/percona-toolkit/2.2.19/RPM/percona-toolkit-2.2.19-1.noarch.rpm

# rpm -vih percona-toolkit-2.2.19-1.noarch.rpm

下面就可以啓動備份了

方案一:xtrabackup完全備份+binlog增量備份

1、備份

創建備份目錄

# mkdir -p /opt/mysqlbackup/{full,inc}

full:全備存放的目錄;inc:增量備份存放的目錄

1)完全備份

基本語法:# innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/

執行下面的命令進行完全備份:

# innobackupex --user=root --password=123456 /opt/mysqlbackup/full

注: --defaults-file=/etc/my.cnf 指定mysql的配置文件my.cfg,如果指定則必須是第一個參數。

/path/to/BACKUP-DIR/指定備份所存放的目標目錄,備份過程會創建一個以當時備份時間命名的目錄存放備份文件。

出現如下提示。表示成功

image

備份後的文件:

在備份的同時,備份數據會在備份目錄下創建一個以當前日期時間爲名字的目錄存放備份文件:

image

各文件說明:

(1)xtrabackup_checkpoints —— 備份類型(如完全或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息;

每個InnoDB頁(通常爲16k大小)都會包含一個日誌序列號,即LSN。LSN是整個數據庫系統的系統版本號,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。

(2)xtrabackup_binlog_info —— mysql服務器當前正在使用的二進制日誌文件及至備份這一刻爲止二進制日誌事件的位置。

(3)xtrabackup_binlog_pos_innodb —— 二進制日誌文件及用於InnoDB或XtraDB表的二進制日誌文件的當前position。

(4)xtrabackup_binary —— 備份中用到的xtrabackup的可執行文件;

(5)backup-my.cnf —— 備份命令用到的配置選項信息;

在使用innobackupex進行備份時,還可以使用--no-timestamp選項來阻止命令自動創建一個以時間命名的目錄;如此一來,innobackupex命令將會創建一個BACKUP-DIR目錄來存儲備份數據

注意:相關選項說明:

其中,--user指定連接數據庫的用戶名,--password指定連接數據庫的密碼,--defaults-file指定數據庫的配置文件,innobackupex要從其中獲取datadir等信息;--database指定要備份的數據庫,這裏指定的數據庫只對MyISAM表有效,對於InnoDB 數據來說都是全備(所有數據庫中的InnoDB數據都進行了備份,不是隻備份指定的數據庫,恢復時也一樣);/opt/mysqlbackup/full是備份文件的存放位置。

注意:備份數據庫的用戶需要具有相應權限,如果要使用一個最小權限的用戶進行備份,則可基於如下命令創建此類用戶:

mysql> create user 'bkpuser'@'localhost' identified by '123456';

mysql> revoke all privileges,grant option from 'bkpuser'@'localhost';

mysql> grant reload,lock tables,replication client, process on *.* to 'bkpuser'@'localhost';

mysql> flush privileges;

至此全備完全成功,然後向mysql某個庫插入幾條數據,然後進行增量備份

對完全備份的後數據庫更改進行二進制日誌增量備份:

查看完全備份時binlog日誌位置(position):

image

模擬數據庫修改:

image

2)增量備份二進制文件:

#mysqlbinlog --start-position=2378 /usr/local/mysql/data/mysql-bin.000023 > /opt/mysqlbackup/inc/`date +%F`.sql

2、還原數據庫:

模擬數據庫損壞:

我這裏直接使用刪除數據目錄文件來模擬損壞。

# rm -fr /usr/local/mysql/data/*

還原完全備份:

(1)準備(prepare)一個完全備份

一般情況下,在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。

在準備(prepare)過程結束後,InnoDB表數據已經前滾到整個備份結束的點,而不是回滾到xtrabackup剛開始時的點。

innobakupex命令的--apply-log選項可用於實現上述功能。如下面的命令:

--apply-log指明是將日誌應用到數據文件上,完成之後將備份文件中的數據恢復到數據庫中:

# innobackupex --apply-log /opt/mysqlbackup/full/2016-09-12_11-29-55/

注:/opt/mysqlbackup/full/2016-09-12_11-29-55/備份文件所在目錄名稱

如果執行正確,其最後輸出的幾行信息通常如下:

image

在實現“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的內存的大小,默認通常爲100M。如果有足夠的內存可用,可以多劃分一些內存給prepare的過程,以提高其完成速度。

innobackupex命令的--copy-back選項用於執行恢復操作,其通過複製所有數據相關的文件至mysql服務器DATADIR目錄中來執行恢復過程。innobackupex通過backup-my.cnf來獲取DATADIR目錄的相關信息。

(2)還原數據庫語法:

# innobackupex --copy-back /opt/mysqlbackup/full/2016-09-12_11-29-55/

這裏的--copy-back指明是進行數據恢復。數據恢復完成之後,需要修改相關文件的權限mysql數據庫才能正常啓動。

如果執行正確,其輸出信息的最後幾行通常如下:

image

請確保如上信息的最行一行出現“completed OK!”。

修改還原後的數據目錄權限:

image

當數據恢復至DATADIR目錄以後,還需要確保所有數據文件的屬主和屬組均爲正確的用戶,如mysql,否則,在啓動mysqld之前還需要事先修改數據文件的屬主和屬組。如:

# chown -R mysql:mysql /usr/local/mysql/data/

重啓動MySQL:

# systemctl restart mysqld

驗證還原後的數據:

mysql> select * from tb1;

+----+------+

| id | name |

+----+------+

| 1 | tom1 |

| 2 | tom2 |

+----+------+

(3)還原增量備份:

爲了防止還原時產生大量的二進制日誌,在還原時可臨時關閉二進制日誌後再還原:

mysql> set sql_log_bin=0;

mysql> source /opt/mysqlbackup/inc/2016-09-12.sql

重新啓動二進制日誌並驗證還原數據:

mysql> set sql_log_bin=1;

驗證數據是否恢復回來

image

方案二、xtrabackup完全備份+xtrabacup增量備份

前面我們進行增量備份時,使用的還是老方法:備份二進制日誌。其實xtrabackup還支持進行增量備份。

先介紹下xtrabackup的備份原理

在InnoDB內部會維護一個redo日誌文件,我們也可以叫做事務日誌文件(transaction log,事務日誌)。事務日誌會存儲每一個InnoDB表數據的記錄修改。當InnoDB啓動時,InnoDB會檢查數據文件和事務日誌,並執行兩個步驟:它應用已經提交的事務日誌到數據文件,並將修改過但沒有提交的數據進行回滾操作。

xtrabackup在啓動時會記住log sequence number(LSN),並且複製所有的數據文件。複製過程需要一些時間,所以這期間如果數據文件有改動,那麼將會使數據庫處於一個不同的時間點。這時,xtrabackup會運行一個後臺進程,用於監視事務日誌,並從事務日誌複製最新的修改。xtrabackup必須持續的做這個操作,是因爲事務日誌是會輪轉重複的寫入,並且事務日誌可以被重用。所以xtrabackup自啓動開始,就不停的將事務日誌中每個數據文件的修改都記錄下來。這就是xtrabackup的備份過程

所以每個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎。

xtraBackup基於InnoDB的crash-recovery功能。它會複製innodb的data file,由於不鎖表,複製出來的數據是不一致的,在恢復的時候使用crash-recovery,使得數據恢復一致。

當InnoDB啓動的時候,它會先去檢查data file和transaction log,並且會做二步操作:

1.It applies committed transaction logentries to the data files

2.it performs an undo operation on anytransactions that modified data but did not commit.

所以在prepare過程中,XtraBackup使用複製到的transactions log對備份出來的innodb data file進行crash recovery。

測試環境準備

創建一個測試數據庫,並創建一張表輸入幾行數據

mysql> create database test;

mysql> use test;

mysql> create table xx(id int,name varchar(20));

mysql> insert into xx values(1,'tom1');

mysql> insert into xx values(2,'tom2');

1、 xtrabacup進行備份

執行完全備份:

備份命令:

# xtrabackup --defaults-file=/etc/my.cnf --user=root --password="123456" --port=3306 --backup --target-dir=/opt/mysqlbackup/full/full_incre_$(date +%Y%m%d_%H%M%S)

部分顯示信息如下圖所示:

image

其中,--defaults-file指定數據庫的配置文件,如果使用該參數必須做爲第一個參數;--user指定連接數據庫的用戶名;--password指定連接數據庫的密碼;--port指定連接數據庫的端口號;--backup 實施備份到target-dir; --target-dir=name 備份文件的存放目錄路徑。innobackupex要從其中獲取datadir等信息;--database指定要備份的數據庫,這裏指定的數據庫只對MyISAM表和InnoDB表的表結構有效,對於InnoDB 數據來說都是全備(所有數據庫中的InnoDB數據都進行了備份,不是隻備份指定的數據庫,恢復時也一樣);/opt/mysqlbackup/full/是備份文件的存放位置。

查看完全備份文件

[root@localhost ~]# ls /opt/mysqlbackup/full/ -l

drwxr-x---. 8 root root 4096 Sep 12 22:11 full_incre_20160912_221111

xtrabackup進行增量備份

先錄入些數據,實現第一次增量數據:

mysql> use test;

mysql> insert into xx values(3,'tom3');

再進行增量備份1

備份命令:

# xtrabackup --defaults-file=/etc/my.cnf --user=root --password="123456" --port=3306 --backup --target-dir=/opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/full/full_incre_20160912_221111/

部分顯示信息如下圖所示:

image

其中,--incremental-basedir指定上次完整備份或者增量備份文件的位置(即如果是第一次增量備份則指向完全備份所在目錄,在執行過增量備份之後再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄)。

查看增量備份文件:

[root@localhost ~]# ls -l /opt/mysqlbackup/inc/

drwxr-x---. 8 root root 4096 Sep 12 22:15 incre_20160912_221510

注:

這裏的增量備份其實只針對的是InnoDB,對於MyISAM來說,還是完整備份。

向表中再插入幾行數據,繼續第二次增量備份

mysql> use test;

mysql> insert into xx values(4,'tom4');

mysql> commit;

進行第二次增量備份

備份命令:

# xtrabackup --defaults-file=/etc/my.cnf --user=root --password="123456" --port=3306 --backup --target-dir=/opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/inc/incre_20160912_221510/

部分顯示信息如下圖所示:

image

注:第二次增量備份--incremental-basedir指向上一次增量備份文件的位置。

查看增量備份文件

[root@localhost ~]# ls -l /opt/mysqlbackup/inc/

drwxr-x---. 8 root root 4096 Sep 12 22:15 incre_20160912_221510

drwxr-x---. 8 root root 4096 Sep 12 22:19 incre_20160912_221916

2、 xtrabacup進行增量恢復

爲了驗證比對,先刪除兩個增量備份前表裏面的數據

mysql> use test;

mysql> delete from xx where id=3;

完整備份恢復:

在進行恢復前,如果完整備份在遠程主機上,首先將完整備份複製到本地主機上,如果是tar包,則需要先解包,解包命令爲:tar –izxf xxx.tar,這裏必須使用-i參數(忽略存檔中的 0 字節塊(通常意味着文件結束))。

開始全備份恢復

命令如下:

# xtrabackup --defaults-file=/etc/my.cnf --prepare --user=root --password="123456" --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_20160912_221111/

部分顯示信息如下圖所示:

image

恢復到第一次增量的時刻

增量備份恢復的步驟和完整備份恢復的步驟基本一致,只是應用日誌的過程稍有不同。增量備份恢復時,是先將所有的增量備份挨個應用到完整備份的數據文件中,然後再將完整備份中的數據恢復到數據庫中。

恢復命令:

# xtrabackup --defaults-file=/etc/my.cnf --prepare --user=root --password="123456" --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_20160912_221111/ --incremental-dir=/opt/mysqlbackup/inc/incre_20160912_221510/

部分顯示信息如下圖所示:

image

恢復到第二次增量備份前面:

恢復命令:

# xtrabackup --defaults-file=/etc/my.cnf --prepare --user=root --password="123456" --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_20160912_221111/ --incremental-dir=/opt/mysqlbackup/inc/incre_20160912_221916/

部分顯示信息如下圖所示:

image

恢復整個庫

恢復命令:

# xtrabackup --defaults-file=/etc/my.cnf --prepare --user=root --password="123456" --target-dir=/opt/mysqlbackup/full/full_incre_20160912_221111/

部分顯示信息如下圖所示:

image

然後停止mysql數據庫:

[root@localhost ~]# systemctl stop mysqld

開始rsync數據文件:

# cd /opt/mysqlbackup/full/full_incre_20160912_221111/

#rsync -rvt --exclude 'xtrabackup_checkpoints' --exclude 'xtrabackup_logfile' ./ /usr/local/mysql/data/

當數據恢復至DATADIR目錄以後,還需要確保所有數據文件的屬主和屬組均爲正確的用戶,如mysql,否則,在啓動mysqld之前還需要事先修改數據文件的屬主和屬組。

授予mysql訪問權限:

# chown -R mysql:mysql /usr/local/mysql/data/

啓動mysql服務:

# systemctl start mysqld

驗證

登錄mysql,看到以前在備份之後刪除的數據已經通過2次增量備份恢復過來了,如下所示:

[root@localhost ~]# mysql -uroot -p123456 -e "select * from test.xx"

+------+------+

| id | name |

+------+------+

| 1 | tom1 |

| 2 | tom2 |

| 3 | tom3 |

| 4 | tom4 |

+------+------+

方案三:innobackupex全庫備份+innobackupex增量備份

測試環境準備

創建一個測試數據庫,並創建一張表輸入幾行數據

mysql> create database test2;

mysql> use test2;

mysql> create table yy(id int,name varchar(20));

mysql> insert into yy values(1,'kim1');

mysql> insert into yy values(2,'kim2');

1、innobackupex先做完全備份

命令如下:

# innobackupex --defaults-file=/etc/my.cnf --user=root --password="123456" /opt/mysqlbackup/full/full_incre_$(date +%Y%m%d_%H%M%S) --no-timestamp

部分顯示信息如下圖所示:

image

查看完全備份文件

# ll /opt/mysqlbackup/full/

drwxr-x---. 10 root root 4096 Sep 12 23:52 full_incre_20160912_235237

innobackupex做增量備份

做第一次增量備份

先錄入增量數據

mysql> use test2;

mysql> insert into yy values(3,'kim3');

再進行增量備份,命令如下:

# innobackupex --incremental /opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/full/full_incre_20160912_235237/ --user=root --password="123456" --no-timestamp

部分顯示信息如下圖所示:

image

查看增量備份文件

# ll /opt/mysqlbackup/inc/

drwxr-x---. 10 root root 4096 Sep 12 23:56 incre_20160912_235636

基於全備和第一個增量備份來做第二次增量備份

先錄入增量數據錄入

mysql> use test2;

mysql> insert into yy values(4,'kim4');

開始進行第二次增量備份,備份命令:

# innobackupex --incremental /opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/inc/incre_20160912_235636/ --user=root --password="123456" --no-timestamp

部分顯示信息如下圖所示:

image

查看增量備份文件

# ll /opt/mysqlbackup/inc/

drwxr-x---. 10 root root 4096 Sep 12 23:56 incre_20160912_235636

drwxr-x---. 10 root root 4096 Sep 12 23:59 incre_20160912_235942

2、innobackupex做增量恢復

先刪除兩次增量數據,用來查看驗證恢復結果

mysql> use test2;

mysql> delete from yy where id=3;

開始做恢復,恢復全備份

命令如下:

# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_20160912_235237/

部分顯示信息如下圖所示:

image

--redo-only 用於準備增量備份內容把數據合併到全備份目錄,配合incremental-dir 增量備份目錄使用

基於全備份進行第一次增量備份的恢復

命令如下:

# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_20160912_235237/ --incremental-dir=/opt/mysqlbackup/inc/incre_20160912_235636/

基於全備份和第一次增量備份,恢復第二次增量備份

命令如下:

# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_20160912_235237/ --incremental-dir=/opt/mysqlbackup/inc/incre_20160912_235942/

恢復整個數據庫

停止數據庫

# systemctl stop mysqld

清空數據目錄下所有文件

# mkdir -p /tmp/mysqldatabak

# mv /usr/local/mysql/data/* /tmp/mysqldatabak/

將恢復好的數據按照配置文件的需求拷貝到相應目錄

# innobackupex --defaults-file=/etc/my.cnf --user=root --password="123456" --copy-back /opt/mysqlbackup/full/full_incre_20160912_235237/

當數據恢復至DATADIR目錄以後,還需要確保所有數據文件的屬主和屬組均爲正確的用戶,如mysql,否則,在啓動mysqld之前還需要事先修改數據文件的屬主和屬組。

賦予mysql賬號權限

# chown -R mysql:mysql /usr/local/mysql/data/

啓動mysql服務

# systemctl start mysqld

登錄mysql界面,查看數據是否已經恢復,如下所示:

mysql> use test2;

mysql> select * from yy;

+------+------+

| id | name |

+------+------+

| 1 | kim1 |

| 2 | kim2 |

| 3 | kim3 |

| 4 | kim4 |

+------+------+

附:Xtrabackup的“流”及“備份壓縮”功能

Xtrabackup對備份的數據文件支持“流”功能,即可以將備份的數據通過STDOUT傳輸給tar程序進行歸檔,而不是默認的直接保存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。如:

# innobackupex --user=root --password="123456" --stream=tar /opt/mysqlbackup/full/ | gzip >/opt/mysqlbackup/full/full_`date +%F_%H%M%S`.tar.gz

http://hongge.blog.51cto.com/

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