1. 程式人生 > 實用技巧 >MySQL入門篇(七)之Xtrabackup備份與恢復

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備份原理

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/XtraBackup/LATEST/

可以選擇rpm包方式安裝,也可以下載原始碼包編譯安裝,這裡直接採用rpm包的方式進行安裝

[root@master tools]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.9/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm
[root@master tools]# yum install -y percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm 
[root@master ~]# rpm -qa |grep xtrabackup
percona-xtrabackup-24-2.4.9-1.el7.x86_64

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/指定備份後的資料儲存路徑

關於阿里雲RDS物理備份資料使用xtrabackup工具恢復到本地mysql當中,請參考阿里雲文件:https://help.aliyun.com/knowledge_detail/41817.html?spm=5176.11065259.1996646101.searchclickresult.53d420cclqekK3