使用xtrabackup備份MySQL數據庫

前言

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

  • xtrabackup:專用於備份InnoDB和XtraDB引擎的數據;
  • innobackupex:是一個perl腳本,在執行過程當中會調用xtrabackup命令,這個命令便可以實現備份InnoDB,也能夠備份Myisam引擎的對象。

xtrabackup是由percona提供的MySQL數據庫備份工具,其備份速度快而且可靠;備份過程不會打斷正在執行的事務;可以基於壓縮等功能節約磁盤空間和流量;自動實現備份檢驗;還原速度快。mysql

若須要安裝xtrabackup,能夠移步其官方網站,在其官網上提供了多種安裝方式。sql

博文大綱:shell

  • 1、安裝xtrabackup及其插件
  • 2、xtrabackup徹底備份+binlog增量備份
  • 3、xtrabackup徹底備份+xtrabackup增量備份
  • 4、innobackupex全庫備份+innobackupex增量備份

注:2、3、四是三種不一樣的備份方案,在生產環境中選擇合適的一種便可。數據庫

1、安裝xtrabackup及其插件

一、yum安裝xtrabackup

參考官方文檔,在官方文檔上提供了各個版本的幫助說明。服務器

[root@mysql ~]# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm  
[root@mysql ~]# yum -y install percona-xtrabackup-24

xtrabackup中主要包含兩個工具:app

  • xtrabackup:是用於熱備份innodb,xtradb表中數據的工具,支持在線熱備份,能夠在不加鎖的狀況下備份innodb數據表,不過該工具不能操做myisam引擎表。
  • innobackupex:是將xtrabackup進行封裝的perl腳本,能同時處理innodb和myisam,但在處理myisam時須要加一個讀鎖,因爲操做myisam時須要加讀鎖,因此會堵塞線上服務的寫操做,而Innodb沒有這樣的限制。

二、下載並安裝percona-toolkit工具

[root@mysql test]# yum -y install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-TermReadKey.x86_64 perl-Digest-MD5
[root@mysql test]# wget https://www.percona.com/downloads/percona-toolkit/2.2.19/RPM/percona-toolkit-2.2.19-1.noarch.rpm
[root@mysql test]# rpm -ivh percona-toolkit-2.2.19-1.noarch.rpm

2、xtrabackup徹底備份+binlog增量備份

一、建立備份目錄

[root@mysql test]# mkdir -p /opt/mysqlbackup/{full,inc}
# full:全備存放的目錄
# inc:增量備份存放的目錄

二、建立備份用戶

[root@mysql test]# mysql -uroot -p123.com
mysql> create user bakuser@'localhost' identified by '123.com';
mysql> revoke all privileges,grant option from 'bakuser'@'localhost';
mysql> grant reload,lock tables,replication client,process on *.* to bakuser@'localhost';
mysql> flush privileges;

三、徹底備份

[root@mysql test]# innobackupex --user=bakuser --password=123.com /opt/mysqlbackup/full/
#當備份完成後將出現如下提示信息
.............  #忽略部分信息
200116 13:09:21 completed OK!

上述執行相關解釋以下:ide

  • --user:指定鏈接數據庫的用戶名;
  • --password:指定鏈接數據庫的密碼;
  • --defaults-file:指定數據庫的配置文件my.cnf,innobackupex要從其中獲取datadir等信息,若是不指定,則會默認去搜索my.cnf這個文件,搜索順序和mysql啓動時的搜索順序同樣;
  • --database:指定要備份的數據據庫,這裏指定的數據庫只對myisam表有效,對於innodb數據來講都是全備(全部數據庫中的innodb數據都進行了備份,不是隻備份指定的數據庫,恢復時也同樣);
  • /opt/mysqlbackup/full:是備份文件的存放位置。

四、查看備份後的文件

使用xtrabackup備份MySQL數據庫

各個文件存放的內容以下:工具

  • backup-my.cnf:備份命令用到的配置選項信息;
  • ib_buffer_pool:buffer緩衝區相關的信息;
  • xtrabackup_checkpoints:這個文件很重要,保存的是備份類型(如徹底或增量)、備份狀態(如是否已經爲perpared狀態(備份恢復前須要的狀態)),和LSN(日誌序列號)範圍信息,每一個innodb頁(通常爲16k大小)都會包含一個日誌序列號,LSN時整個數據庫系統同的系統版本號,每一個頁面相關的LSN可以代表此頁面最近是如何發生改變的。
  • xtrabackup_info:備份指令相關的信息。

五、經過二進制日誌進行增量備份

在進行增量備份前,須要先查看到徹底備份時binlog日誌位置(position),以下:測試

[root@mysql 2020-01-17_10-39-52]# pwd
/opt/mysqlbackup/full/2020-01-17_10-39-52
[root@mysql 2020-01-17_10-39-52]# cat xtrabackup_binlog_info 
bin_log.000001  154
# 獲得徹底備份是備份到了bin_log.000001二進制日誌中的154的位置

經過二進制日誌進行增量備份:

在增量備份前,自行向數據庫中進行增刪改等操做,以便產生新的二進制日誌。

[root@mysql ~]# mysqlbinlog --start-position=154 /usr/local/mysql/data/bin_log.000001 > /opt/mysqlbackup/inc/`date +%F`.sql

六、模擬數據丟失,以便還原數據

[root@mysql ~]# rm -rf /usr/local/mysql/data/*      #直接刪除本地全部數據

還原徹底備份的大概流程以下:

  • 準備(prepare)一個徹底備份,通常狀況下,在備份完成後,數據還不能用於恢復操做,由於備份的數據中可能包含還沒有提交的事務或已經提交但還沒有同步至數據文件中的事務。所以,此時數據文件仍處於不一致狀態,「準備」的主要做用就是經過回滾未提交的事務及同步已提交的事務至數據文件也使得數據文件處於一致性狀態。在準備過程結束後,Innodb表數據已經前滾到整個備份結束的點,而不是回滾到xtrabackup剛開始的點。

經過--apply-log選項可用於實現上述功能,命令以下:

[root@mysql ~]# innobackupex --apply-log /opt/mysqlbackup/full/2020-01-17_10-39-52/
[root@mysql 2020-01-17_10-39-52]# cat xtrabackup_checkpoints 
backup_type = full-prepared   #當準備工做完成後,備份目錄下的此文件內容中的備份類型會爲:full-prepared
from_lsn = 0
to_lsn = 2841752
last_lsn = 2841761
compact = 0
recover_binlog_info = 0
flushed_lsn = 2841761

注:/opt/mysqlbackup/full/2020-01-17_10-39-52/是備份文件所在目錄名稱,若是執行正確,最後幾行輸出的信息以下:

使用xtrabackup備份MySQL數據庫

在實現「準備」的過程當中,innobackupex一般還可使用「--user-memory」選項來指定其可使用的內存大小,默認爲100M,若是有足夠的內存,能夠多劃分一些內存給prepare的過程,以提升其完成速度。

在準備工做完成後,便可使用如下命令進行恢復:

[root@mysql ~]# innobackupex --copy-back /opt/mysqlbackup/full/2020-01-17_10-39-52/

確認數據已恢復:

使用xtrabackup備份MySQL數據庫

徹底備份的數據已經恢復,可是須要注意權限的問題,恢復後的數據屬主及屬組都是當前用戶root,因此還須要更改其屬主及屬組,以下:

[root@mysql ~]# cd /usr/local/mysql/data/
[root@mysql data]# chown -R mysql.mysql .
[root@mysql data]# ll        #確認當前屬組與屬主
總用量 122924
drwxr-x--- 2 mysql mysql       90 1月  17 11:15 data1
-rw-r----- 1 mysql mysql      324 1月  17 11:15 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 1月  17 11:15 ibdata1
-rw-r----- 1 mysql mysql 50331648 1月  17 11:15 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 1月  17 11:15 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 1月  17 11:15 ibtmp1
drwxr-x--- 2 mysql mysql     4096 1月  17 11:15 mysql
drwxr-x--- 2 mysql mysql     8192 1月  17 11:15 performance_schema
drwxr-x--- 2 mysql mysql     8192 1月  17 11:15 sys
-rw-r----- 1 mysql mysql       20 1月  17 11:15 xtrabackup_binlog_pos_innodb
-rw-r----- 1 mysql mysql      481 1月  17 11:15 xtrabackup_info
-rw-r----- 1 mysql mysql        1 1月  17 11:15 xtrabackup_master_key_id
[root@mysql ~]# systemctl restart mysqld   #在數據恢復後,須要重啓服務器,不然數據不統一

七、查看數據庫中恢復後的數據

[root@mysql ~]# mysql -uroot -p123.com -e "select * from data1.t1;"

+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
|    3 | tom3 |
+------+------+

八、還原增量備份

爲了防止還原時產生大量的二進制日誌,在還原時最好臨時關閉二進制日誌,以下:

[root@mysql ~]# mysql -uroot -p123.com -e 'set sql_log_bin=0;'    #臨時關閉二進制日誌
[root@mysql ~]# mysql -uroot -p123.com < /opt/mysqlbackup/inc/2020-01-17.sql
#恢復二進制日誌
[root@mysql ~]# mysql -uroot -p123.com -e 'set sql_log_bin=1;'  #開啓二進制日誌
[root@mysql ~]# mysql -uroot -p123.com -e "select * from data1.t1;"
#確認數據恢復正確

+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
|    3 | tom3 |
|    4 | tom4 |
|    5 | tom5 |
+------+------+--+i

3、xtrabackup徹底備份+xtrabackup增量備份

在第一個備份方案中,增量備份使用的是備份二進制日誌,其實xtrabackup還支持進行增量備份,xtrabackup的備份原理以下:

在innodb內部會維護一個redo日誌我呢見,也能夠叫作事務日誌文件(transaction,事務日誌),事務日誌會存儲每一個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,使得數據恢復一致。

一、建立一個測試庫,並準備一張表插入幾行數據

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');
mysql> select * from xx;
+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
+------+------+

二、xtrabackup進行徹底備份

[root@mysql ~]# xtrabackup --defaults-file=/etc/my.cnf --user=bakuser --password="123.com" --port=3306 --backup --target-dir=/opt/mysqlbackup/full/full_incre_$(date '+%F_%T')

上述各個指令解釋以下:

  • --defaults-file:指定數據庫的配置文件,若是使用該參數,必須做爲第一個參數;
  • --user:指定鏈接數據庫的用戶名;
  • --password:指定鏈接數據庫的密碼;
  • --port:指定鏈接數據庫的端口號;
  • --backup:實施備份到target-dir;
  • --target-dir=name:備份文件的存放目錄路徑。innobackupex要從其中獲取datadir等信息;
  • --database:指定要備份的數據庫,這裏指定的數據庫只對myisam和innodb表的表結構有效,對於innodb數據庫來講都是徹底備份(恢復時也同樣)。

三、查看徹底備份文件

使用xtrabackup備份MySQL數據庫

四、進行第一次增量備份

#先插入新的數據
[root@mysql full]# mysql -uroot -p123.com -e "insert into test.xx values(3,'tom3');"
#再進行增量備份
[root@mysql full]# xtrabackup --defaults-file=/etc/my.cnf --user=bakuser --password="123.com" --port=3306 --backup --target-dir=/opt/mysqlbackup/inc/incre_$(date '+%F_%T') --incremental-basedir=/opt/mysqlbackup/full/full_incre_2020-01-17_14\:34\:39/

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

查看增量備份文件:

[root@mysql full]# ll /opt/mysqlbackup/inc/
總用量 0
drwxr-x--- 7 root root 274 1月  17 15:12 incre_2020-01-17_15:12:00
# 注:這裏的增量備份只是針對innodb,對於myisam來講,仍是完整備份。

五、進行第二次增量備份

#再插入新的數據
[root@mysql full]# mysql -uroot -p123.com -e "insert into test.xx values(4,'tom4');"
#進行第二次增量備份
[root@mysql full]# xtrabackup --defaults-file=/etc/my.cnf --user=bakuser --password="123.com" --port=3306 --backup --target-dir=/opt/mysqlbackup/inc/incre_$(date '+%F_%T') --incremental-basedir=/opt/mysqlbackup/inc/incre_2020-01-17_15\:12\:00/

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

六、恢復徹底備份以及增量備份

恢復數據的大概流程以下:

若是備份文件是tar包,解包命令爲:tar -izxf xxx.tar,這裏必須使用-i參數,表示忽略存檔中的0字節。
首先準備恢復徹底備份:

[root@mysql ~]# xtrabackup --defaults-file=/etc/my.cnf --prepare --user=bakuser --password="123.com" --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_2020-01-17_14\:34\:39/

再準備恢復到第一次增量備份的時刻,以下:

[root@mysql ~]# xtrabackup  --defaults-file=/etc/my.cnf --prepare --user=bakuser --password='123.com' --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_2020-01-17_14\:34\:39/ --incremental-dir=/opt/mysqlbackup/inc/incre_2020-01-17_15\:12\:00/

再準備恢復第二次增量備份,以下:

[root@mysql ~]# xtrabackup  --defaults-file=/etc/my.cnf --prepare --user=bakuser --password='123.com' --apply-log-only --target-dir=/opt/mysqlbackup/full/full_incre_2020-01-17_14\:34\:39/ --incremental-dir=/opt/mysqlbackup/inc/incre_2020-01-17_15\:20\:32/

而後中止MySQL數據庫:

[root@mysql ~]# systemctl stop mysqld

開始rsync數據文件:

[root@mysql ~]# cd /opt/mysqlbackup/full/full_incre_2020-01-17_14\:34\:39/
[root@mysql full_incre_2020-01-17_14:34:39]# rsync -rvt --exclude 'xtrabackup_checkpoints' --exclude 'xtrabackup_logfile' ./ /usr/local/mysql/data/

當數據恢復到mysql的data目錄之後,還須要確保全部數據文件的屬主和屬組均爲正確的用戶,如我這裏須要修改成mysql,以下:

[root@mysql full_incre_2020-01-17_14:34:39]# cd /usr/local/mysql/data/
[root@mysql data]# chown -R mysql.mysql .
#更改恢復後的數據屬組和屬主爲mysql

確認數據已恢復:

[root@mysql data]# mysql -uroot -p123.com -e  "select * from test.xx;"
+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
|    3 | tom3 |
|    4 | tom4 |
+------+------+

4、innobackupex全庫備份+innobackupex增量備份

一、全庫備份

#準備測試數據
[root@mysql data]# mysql -uroot -p123.com -e  "select * from test.xx;"
+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
|    3 | tom3 |
+------+------+
#開始徹底備份
[root@mysql ~]# innobackupex --defaults-file=/etc/my.cnf --user=bakuser --password='123.com' /opt/mysqlbackup/full/full_incre_$(date '+%F_%H%M%S') --no-timestamp

注:--no-timestamp選項來阻止命令自動建立一個以時間命名的目錄,而後便可自定義目錄了;

二、作一次增量備份

# 插入測試數據
[root@mysql ~]# mysql -uroot -p123.com -e  "insert into xx values(4,'tom4'),(5,'tom5');" test
#進行增量備份
[root@mysql ~]# innobackupex --incremental /opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/full/full_incre_2020-01-17_165254/ --user=bakuser --password='123.com' --no-timestamp
#  --incremental-basedir:指定的是上次徹底備份或者增量備份的目錄
#因爲這是第一次增量備份,因此就須要指定上次徹底備份的目錄

[root@mysql ~]# ll /opt/mysqlbackup/inc/     #查看增量備份文件
總用量 0
drwxr-x--- 7 root root 274 1月  17 17:04 incre_20200117_170424

三、作第二次增量備份

#插入新的數據
[root@mysql ~]# mysql -uroot -p123.com -e  "insert into test.xx values(6,'tom6')";
#基於第一次增量備份的目錄文件作第二次增量備份
[root@mysql ~]# innobackupex --incremental /opt/mysqlbackup/inc/incre_$(date +%Y%m%d_%H%M%S) --incremental-basedir=/opt/mysqlbackup/inc/incre_20200117_170424/ --user=bakuser --password='123.com' --no-timestamp

四、查看增量備份文件

[root@mysql ~]# ll /opt/mysqlbackup/inc/
總用量 0
drwxr-x--- 7 root root 274 1月  17 17:04 incre_20200117_170424
drwxr-x--- 7 root root 274 1月  17 17:10 incre_20200117_171035

五、刪除數據文件,準備進行恢復

[root@mysql ~]# rm -rf /usr/local/mysql/data/*
#恢復徹底備份目錄文件
[root@mysql ~]# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_2020-01-17_165254/
# 將第一次增量備份合併到全備目錄
[root@mysql ~]# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_2020-01-17_165254/ --incremental-dir=/opt/mysqlbackup/inc/incre_20200117_170424/
# 將第二次增量備份合併到全備目錄
[root@mysql ~]# innobackupex --apply-log --redo-only /opt/mysqlbackup/full/full_incre_2020-01-17_165254/ --incremental-dir=/opt/mysqlbackup/inc/incre_20200117_171035/

六、恢復數據庫

[root@mysql ~]# systemctl stop mysqld    #中止數據庫
#進行恢復
[root@mysql ~]# innobackupex --defaults-file=/etc/my.cnf --user=bakuser --password='123.com' --copy-back  /opt/mysqlbackup/full/full_incre_2020-01-17_165254/

七、修改恢復後的文件屬主及屬組

[root@mysql ~]# cd /usr/local/mysql/data/
[root@mysql data]# chown -R mysql.mysql .

八、啓動MySQL數據庫,確認數據已恢復

[root@mysql data]# systemctl start mysqld
[root@mysql data]# mysql -uroot -p123.com -e "select * from test.xx;"

+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
|    2 | tom2 |
|    3 | tom3 |
|    4 | tom4 |
|    5 | tom5 |
|    6 | tom6 |
+------+------+

數據恢復成功。

5、附加——Xtrabackup的「流」及「備份壓縮」功能

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

#進行完整備份
[root@mysql opt]# innobackupex --user=bakuser --password="123.com" --stream=tar /opt/mysqlbackup/full/ | gzip > /opt/mysqlbackup/full/full_`date +%F_%H%M%S`.tar.gz
#上述命令生成的備份文件以下:
[root@mysql full]# ll /opt/mysqlbackup/full/
總用量 640
-rw-r--r-- 1 root root 652578 1月  17 17:45 full_2020-01-17_174513.tar.gz

———————— 本文至此結束,感謝閱讀 ————————

相關文章
相關標籤/搜索