mysql 熱備 之 Xtrabackup備份與恢復

一、Xtrabackup介紹

      MySQL冷備、mysqldump、MySQL熱拷貝都無法實現對數據庫進行增量備份。在實際生產環境中增量備份是非常實用的,如果數據大於50G或100G,存儲空間足夠的情況下,可以每天進行完整備份,如果每天產生的數據量較大,需要定製數據備份策略。例如每週實用完整備份,週一到週六實用增量備份。而Percona-Xtrabackup就是爲了實現增量備份而出現的一款主流備份工具,xtrabakackup有2個工具,分別是xtrabakup、innobakupe。

  Percona-xtrabackup是 Percona公司開發的一個用於MySQL數據庫物理熱備的備份工具,支持MySQL、Percona server和MariaDB,開源免費,是目前較爲受歡迎的主流備份工具。xtrabackup只能備份innoDB和xtraDB兩種數據引擎的表,而不能備份MyISAM數據表。

二、Xtrabackup優點

(1)備份速度快,物理備份可靠

(2)備份過程不會打斷正在執行的事務(無需鎖表)

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

(4)自動備份校驗

(5)還原速度快

(6)可以流傳將備份傳輸到另外一臺機器上

(7)在不增加服務器負載的情況備份數據

三、Xtrabackup備份原理

(1)innobackupex啓動後,會先fork一個進程,用於啓動xtrabackup,然後等待xtrabackup備份ibd數據文件;

(2)xtrabackup在備份innoDB數據是,有2種線程:redo拷貝線程和ibd數據拷貝線程。xtrabackup進程開始執行後,會啓動一個redo拷貝的線程,用於從最新的checkpoint點開始順序拷貝redo.log;再啓動ibd數據拷貝線程,進行拷貝ibd數據。這裏是先啓動redo拷貝線程的。在此階段,innobackupex進行處於等待狀態(等待文件被創建)

(4)xtrabackup拷貝完成ibd數據文件後,會通知innobackupex(通過創建文件),同時xtrabackup進入等待狀態(redo線程依舊在拷貝redo.log)

(5)innobackupex收到xtrabackup通知後哦,執行FLUSH TABLES WITH READ LOCK(FTWRL),取得一致性位點,然後開始備份非InnoDB文件(如frm、MYD、MYI、CSV、opt、par等格式的文件),在拷貝非InnoDB文件的過程當中,數據庫處於全局只讀狀態。

(6)當innobackup拷貝完所有的非InnoDB文件後,會通知xtrabackup,通知完成後,進入等待狀態;

(7)xtrabackup收到innobackupex備份完成的通知後,會停止redo拷貝線程,然後通知innobackupex,redo.log文件拷貝完成;

(8)innobackupex收到redo.log備份完成後,就進行解鎖操作,執行:UNLOCK TABLES;

(9)最後innbackupex和xtrabackup進程各自釋放資源,寫備份元數據信息等,innobackupex等xtrabackup子進程結束後退出。

四、xtrabackup的安裝部署以及備份恢復實現

1、xtrabackup的安裝

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

[root@gitlab opt]# wget https://www.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.9/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.9-1.el7.x86_64.rpm
[root@gitlab opt]# yum install -y percona-xtrabackup-80-8.0.9-1.el7.x86_64.rpm
[root@gitlab opt]# rpm -qa |grep xtrabackup
percona-xtrabackup-80-8.0.9-1.el7.x86_64
[root@gitlab opt]# xtrabackup -v
xtrabackup: recognized server arguments: --datadir=/var/lib/mysql 
xtrabackup version 8.0.9 based on MySQL server 8.0.18 Linux (x86_64) (revision id: c5cbbe4)
Xtrabackup中主要包含兩個工具:
xtrabackup:是用於熱備innodb,xtradb表中數據的工具,不能備份其他類型的表,也不能備份數據表結構;
innobackupex:是將xtrabackup進行封裝的perl腳本,提供了備份myisam表的能力。
常用選項:  
   --host     指定主機
   --user     指定用戶名
   --password    指定密碼
   --port     指定端口
   --databases     指定數據庫
   --incremental    創建增量備份
   --incremental-basedir   指定包含完全備份的目錄
   --incremental-dir      指定包含增量備份的目錄   
   --apply-log        對備份進行預處理操作             
     一般情況下,在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。
   --redo-only      不回滾未提交事務
   --copy-back     恢復備份目錄

使用innobackupex備份時,其會調用xtrabackup備份所有的InnoDB表,複製所有關於表結構定義的相關文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關文件,同時還會備份觸發器和數據庫配置信息相關的文件,這些文件會被保存到一個以時間命名的目錄當中。在備份的同時,innobackupex還會在備份目錄中創建如下文件:

(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目錄來存儲備份數據。

如果要使用一個最小權限的用戶進行備份,則可基於如下命令創建此類用戶:如果要使用一個最小權限的用戶進行備份,則可基於如下命令創建此類用戶:

mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY '123456';  #創建用戶
mysql> REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'bkpuser';  #回收此用戶所有權限
mysql> GRANT RELOAD,LOCK TABLES,RELICATION CLIENT ON *.* TO 'bkpuser'@'localhost';  #授權刷新、鎖定表、用戶查看服務器狀態
mysql> FLUSH PRIVILEGES;  #刷新授權表

注意:備份時需啓動MySQL,恢復時需關閉MySQL,清空mysql數據目錄且不能重新初始化,恢復數據後應該立即進行一次完全備份

2、xtrabackup全量備份與恢復

備份:
innobackupex --user=DBUSER --password=DBUSERPASS --defaults-file=/etc/my.cnf /path/to/BACKUP-DIR/

恢復:
innobackupex --apply-log /backups/2018-07-30_11-04-55/
innobackupex --copy-back --defaults-file=/etc/my.cnf  /backups/2018-07-30_11-04-55/

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

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

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

# innobackupex --apply-log /path/to/BACKUP-DIR
如果執行正確,其最後輸出的幾行信息通常如下:

120407 09:01:04 innobackupex: completed OK!

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

(2)從一個完全備份中恢復數據

注意:恢復不用啓動MySQL

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

# innobackupex --copy-back /path/to/BACKUP-DIR

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

# chown -R mysql.mysql /mydata/data/

(3)實戰練習

(1)全量備份
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/  #在master上進行全庫備份#語法解釋說明:
#--user=root 指定備份用戶
#--password=123456  指定備份用戶密碼
#--host  指定主機
#/backups  指定備份目錄
[root@master backups]# ll
total 0
drwxr-x--- 7 root root 232 Jul 30 11:01 2018-07-30_11-01-37
[root@master backups]# ll 2018-07-30_11-01-37/  #查看備份數據
total 77856
-rw-r----- 1 root root      418 Jul 30 11:01 backup-my.cnf  #備份用到的配置選項信息文件
-rw-r----- 1 root root 79691776 Jul 30 11:01 ibdata1  #數據文件
drwxr-x--- 2 root root       20 Jul 30 11:01 kim
drwxr-x--- 2 root root     4096 Jul 30 11:01 mysql
drwxr-x--- 2 root root     4096 Jul 30 11:01 performance_schema
drwxr-x--- 2 root root       20 Jul 30 11:01 repppp
drwxr-x--- 2 root root     4096 Jul 30 11:01 wordpress
-rw-r----- 1 root root       21 Jul 30 11:01 xtrabackup_binlog_info  #mysql服務器當前正在使用的二進制日誌文件和此時二進制日誌時間的位置信息文件
-rw-r----- 1 root root      113 Jul 30 11:01 xtrabackup_checkpoints  #備份的類型、狀態和LSN狀態信息文件
-rw-r----- 1 root root      482 Jul 30 11:01 xtrabackup_info
-rw-r----- 1 root root     2560 Jul 30 11:01 xtrabackup_logfile    #備份的日誌文件

(2)恢復
[root@slave ~]# /etc/init.d/mysqld stop  #停止slave上的mysql
Shutting down MySQL.. SUCCESS! 

[root@slave tools]# yum install -y percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm   #安裝xtrabackup
[root@master backups]# scp -r 2018-07-30_11-01-37/ [email protected]:/backups/   #從master上拷貝備份數據
[root@slave tools]# innobackupex --apply-log /backups/2018-07-30_11-01-37/      #合併數據,使數據文件處於一致性的狀態
180729 23:18:23 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.9 based on MySQL server 5.7.13 Linux (x86_64) (revision id: a467167cdd4)
xtrabackup: cd to /backups/2018-07-30_11-01-37/
xtrabackup: This target seems to be not prepared yet.
InnoDB: Number of pools: 1
xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(3127097)
......
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 3129915
180729 23:18:30 completed OK!
[root@slave ~]# rm -rf /usr/local/mysql/data/  #在slave上刪除原有的數據
[root@slave ~]# vim /etc/my.cnf  #配置my.cnf的數據目錄路徑,否則會報錯,要和master一致
datadir=/usr/local/mysql/data
[root@slave ~]# innobackupex --copy-back /backups/2018-07-30_11-01-37/  #在slave上數據恢復
180729 23:32:03 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".
......
180729 23:32:08 completed OK!  #看到completed OK就是恢復正常了
[root@slave ~]# ll /usr/local/mysql/data/  #slave上查看數據目錄,可以看到數據已經恢復,但是屬主會有問題,需要進行修改,所以一般使用mysql的運行用戶進行恢復,否則需要進行修改屬主和屬組信息
total 188432
-rw-r----- 1 root root 79691776 Jul 29 23:32 ibdata1
-rw-r----- 1 root root 50331648 Jul 29 23:32 ib_logfile0
-rw-r----- 1 root root 50331648 Jul 29 23:32 ib_logfile1
-rw-r----- 1 root root 12582912 Jul 29 23:32 ibtmp1
drwxr-x--- 2 root root       20 Jul 29 23:32 kim
drwxr-x--- 2 root root     4096 Jul 29 23:32 mysql
drwxr-x--- 2 root root     4096 Jul 29 23:32 performance_schema
drwxr-x--- 2 root root       20 Jul 29 23:32 repppp
drwxr-x--- 2 root root     4096 Jul 29 23:32 wordpress
-rw-r----- 1 root root      482 Jul 29 23:32 xtrabackup_info
[root@slave ~]# chown -R mysql.mysql /usr/local/mysql/data/  #修改屬主屬組
[root@slave ~]# /etc/init.d/mysqld start  #啓動mysql
Starting MySQL. SUCCESS! 
[root@slave ~]# mysql -uroot -p -e "show databases;"  #查看數據,是否恢復
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| kim                |
| mysql              |
| performance_schema |
| repppp             |
| wordpress          |
+--------------------+

總結全庫備份與恢復三步曲:

a. innobackupex全量備份,並指定備份目錄路徑;

b. 在恢復前,需要使用--apply-log參數先進行合併數據文件,確保數據的一致性要求;

c. 恢復時,直接使用--copy-back參數進行恢復,需要注意的是,在my.cnf中要指定數據文件目錄的路徑。

 

3、xtrabackup增量備份與恢復

使用innobackupex進行增量備份,每個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實現。在進行增量備份時,首先要進行一次全量備份,第一次增量備份是基於全備的,之後的增量備份都是基於上一次的增量備份的,以此類推。

要實現第一次增量備份,可以使用下面的命令進行:

基於全量備份的增量備份與恢復
做一次增量備份(基於當前最新的全量備份)
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --incremental /backups/ --incremental-basedir=/backups/2018-07-30_11-01-37
1. 準備基於全量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2018-07-30_11-01-37
2. 準備基於增量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2018-07-30_11-01-37 --incremental-dir=/backups/2018-07-30_13-51-47/
3. 恢復
innobackupex --copy-back --defaults-file=/etc/my.cnf /opt/2017-01-05_11-04-55/
解釋:
1. 2018-07-30_11-01-37指的是完全備份所在的目錄。
2. 2018-07-30_13-51-47指定是第一次基於2018-07-30_11-01-37增量備份的目錄,其他類似以此類推,即如果有多次增量備份。每一次都要執行如上操作。

需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。

"準備"(prepare)增量備份與整理完全備份有着一些不同,尤其要注意的是:
①需要在每個備份 (包括完全和各個增量備份)上,將已經提交的事務進行"重放"。"重放"之後,所有的備份數據將合併到完全備份上。
②基於所有的備份將未提交的事務進行"回滾"

(1)增量備份演示

[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/   #全備數據
[root@master ~]# mysql -uroot -p  #在master上創建student庫並創建testtb表插入若干數據
Enter password: 
mysql> create database student;
Query OK, 1 row affected (0.03 sec)

mysql> use student;
Database changed
mysql> create table testtb(id int);
Query OK, 0 rows affected (0.07 sec)

mysql> insert into testtb values(1),(10),(99);
Query OK, 3 rows affected (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from testtb;
+------+
| id   |
+------+
|    1 |
|   10 |
|   99 |
+------+
3 rows in set (0.00 sec)

mysql> quit;
Bye

#使用innobackupex進行增量備份
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 --incremental /backups/ --incremental-basedir=/backups/2018-07-30_11-01-37/
......
180730 13:51:50 Executing UNLOCK TABLES
180730 13:51:50 All tables unlocked
180730 13:51:50 Backup created in directory '/backups/2018-07-30_13-51-47/'
MySQL binlog position: filename 'mysql-bin.000005', position '664'
180730 13:51:50 [00] Writing /backups/2018-07-30_13-51-47/backup-my.cnf
180730 13:51:50 [00]        ...done
180730 13:51:50 [00] Writing /backups/2018-07-30_13-51-47/xtrabackup_info
180730 13:51:50 [00]        ...done
xtrabackup: Transaction log of lsn (3158741) to (3158741) was copied.
180730 13:51:50 completed OK!
[root@master backups]# ll  #查看備份數據
total 0
drwxr-x--- 7 root root 232 Jul 30 11:01 2018-07-30_11-01-37  #全量備份數據目錄
drwxr-x--- 8 root root 273 Jul 30 13:51 2018-07-30_13-51-47  #增量備份數據目錄
[root@master 2018-07-30_11-01-37]# cat xtrabackup_checkpoints #查看全量備份的xtrabackup_checkpoints
backup_type = full-backuped  #備份類型爲全量備份
from_lsn = 0  #lsn從0開始
to_lsn = 3127097  #lsn到3127097結束
last_lsn = 3127097
compact = 0
recover_binlog_info = 0

[root@master 2018-07-30_13-51-47]# cat xtrabackup_checkpoints   #查看增量備份的xtrabackup_checkpoints
backup_type = incremental  #備份類型爲增量備份
from_lsn = 3127097  #lsn從3127097開始
to_lsn = 3158741    #lsn到啊3158741結束
last_lsn = 3158741  
compact = 0
recover_binlog_info = 0

(2)增量備份後數據恢復演示

(1)模擬mysql故障,刪除數據目錄所有數據
[root@master ~]# /etc/init.d/mysqld stop  #模擬mysql故障,停止mysql
Shutting down MySQL.. SUCCESS! 
[root@master ~]# rm -rf /usr/local/mysql/data/*  #刪除數據目錄中的所有數據

(2)合併全備數據目錄,確保數據的一致性
[root@master ~]# innobackupex --apply-log --redo-only /backups/2018-07-30_11-01-37/
180730 14:05:27 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.4.9 based on MySQL server 5.7.13 Linux (x86_64) (revision id: a467167cdd4)
xtrabackup: cd to /backups/2018-07-30_11-01-37/
......
......
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 3127106
InnoDB: Number of pools: 1
180730 14:05:29 completed OK!

(3)將增量備份數據合併到全備數據目錄當中
[root@master ~]# innobackupex --apply-log --redo-only /backups/2018-07-30_11-01-37/ --incremental-dir=/backups/2018-07-30_13-51-47/
180730 14:06:42 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".
......
......
180730 14:06:44 [00]        ...done
180730 14:06:44 completed OK!
[root@master ~]# cat /backups/2018-07-30_11-01-37/xtrabackup_checkpoints 
backup_type = log-applied  #查看到數據備份類型是增加
from_lsn = 0  #lsn從0開始
to_lsn = 3158741  #lsn結束號爲最新的lsn
last_lsn = 3158741
compact = 0
recover_binlog_info = 0

(4)恢復數據
[root@master ~]# innobackupex --copy-back /backups/2018-07-30_11-01-37/
180730 14:07:51 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".
.......
.......
180730 14:08:17 [01]        ...done
180730 14:08:17 completed OK!
[root@master ~]# ll /usr/local/mysql/data/
total 77844
-rw-r----- 1 root root 79691776 Jul 30 14:08 ibdata1
drwxr-x--- 2 root root       20 Jul 30 14:08 kim
drwxr-x--- 2 root root     4096 Jul 30 14:08 mysql
drwxr-x--- 2 root root     4096 Jul 30 14:08 performance_schema
drwxr-x--- 2 root root       20 Jul 30 14:08 repppp
drwxr-x--- 2 root root       56 Jul 30 14:08 student
drwxr-x--- 2 root root     4096 Jul 30 14:08 wordpress
-rw-r----- 1 root root       21 Jul 30 14:08 xtrabackup_binlog_pos_innodb
-rw-r----- 1 root root      554 Jul 30 14:08 xtrabackup_info
[root@master ~]# chown -R mysql.mysql /usr/local/mysql/data  #更改數據的屬主屬組
[root@master ~]# /etc/init.d/mysqld start  #啓動mysql
Starting MySQL.Logging to '/usr/local/mysql/data/master.err'.
.. SUCCESS! 
[root@master ~]# mysql -uroot -p -e "show databases;"  #查看數據是否恢復
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| kim                |
| mysql              |
| performance_schema |
| repppp             |
| student            |
| wordpress          |
+--------------------+

 總結:

(1)增量備份需要使用參數--incremental指定需要備份到哪個目錄,使用incremental-dir指定全備目錄;

(2)進行數據備份時,需要使用參數--apply-log redo-only先合併全備數據目錄數據,確保全備數據目錄數據的一致性;

(3)再將增量備份數據使用參數--incremental-dir合併到全備數據當中;

(4)最後通過最後的全備數據進行恢復數據,注意,如果有多個增量備份,需要逐一合併到全備數據當中,再進行恢復。

 

 

#1.  --user=root 指定備份的用戶

#2.  --password=root指定備份用戶的密碼

#3.  --defaults-file=/etc/my.cnf 指定的備份數據的配置文件

#4.  /opt/ 指定備份後的數據保存路徑

 

 

 

 

 

 

 

 

 

 

發佈了68 篇原創文章 · 獲贊 18 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章