Xtrabackup簡介
Percona XtraBackup是開源免費的MySQL數據庫熱備份軟件,它能對InnoDB和XtraDB存儲引擎的數據庫非阻塞地備份(對於MyISAM的備份同樣需要加表鎖)。XtraBackup支持所有的Percona Server、MySQL、MariaDB和Drizzle。
XtraBackup優勢
1、無需停止數據庫進行InnoDB熱備 2、增量備份MySQL 3、流壓縮到傳輸到其它服務器 4、能比較容易地創建主從同步 5、備份MySQL時不會增大服務器負載 |
Xtrabackup安裝
CentOS6.5_X86-64bit下的安裝方法:
首先我們需要到官網去獲得軟件包,我這裏使用的是rpm格式的:
percona-xtrabackup-2.1.8-733.rhel6.x86_64.rpm
http://www.percona.com/downloads/XtraBackup/LATEST/RPM/rhel6/x86_64/
percona-toolkit-2.2.4-1.noarch.rpm
http://www.percona.com/downloads/percona-toolkit/2.0.4/
因爲這個套件工具裏面包含了幾個工具,這些工具是用perl腳本編寫的;在安裝是需要依賴於幾個perl的軟件包,在我們的系統CD裏面就已經有了,所以我這裏就搭建了一個本地yum源來安裝了
[root@Master ~]# yum install \ percona-xtrabackup-2.1.8-733.rhel6.x86_64.rpm \ percona-toolkit-2.2.4-1.noarch.rpm |
Xtrabackup工具介紹
安裝XtraBackup後,其實會有幾個工具:
[root@Master ~]# rpm -ql percona-xtrabackup /usr/bin/innobackupex /usr/bin/innobackupex-1.5.1 /usr/bin/xbcrypt /usr/bin/xbstream /usr/bin/xtrabackup /usr/bin/xtrabackup_55 /usr/bin/xtrabackup_56 /usr/share/doc/percona-xtrabackup-2.1.8 /usr/share/doc/percona-xtrabackup-2.1.8/COPYING [root@Master ~]# 每個工具介紹如下: innobackupex: 這個是其實是下面三個工具的一個perl腳本封裝,可以備份MyISAM, InnoDB, XtraDB表。 xtrabackup: 一個由C編譯而來的二進制文件,只能備份InnoDB和XtraDB數據。 xbcrypt: 用來加密或解密備份的數據。 xbstream: 用來解壓或壓縮xbstream格式的壓縮文件。 建議使用perl封裝的innobackupex來作數據庫備份,因爲比較容易使用。所以下面只介紹innobackupex的使用。其它的使用參考: http://www.percona.com/doc/percona-xtrabackup/2.1/manual.html |
Xtrabackup備份的實現
1.準備工作:
(1)實現如果要使用一個最小權限的用戶進行備份,則可基於如下命令創建此類用戶:
MariaDB [(none)]> CREATE USER 'larry'@'localhost' IDENTIFIED BY 'QAZWSX123'; MariaDB [(none)]> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'larry'@'localhost'; MariaDB [(none)]> GRANT RELOAD,LOCK TABLES, REPLICATION CLIENT ON *.* TO 'larry'@'localhost'; MariaDB [(none)]> FLUSH PRIVILEGES; |
(2)創建備份數據存放目錄:
[root@Master ~]# mkdir /backups |
2.一個完整備份的實現
(1)備份操作:(使用備份用戶備份我當前系統上的所有庫)
準備一個測試數據庫: MariaDB [(none)]> SET sql_log_bin=0; //導入過程中無需記錄到二進制日誌中 MariaDB [(none)]> source /root/hellodb.sql MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | hellodb | | information_schema | | mysql | | performance_schema | | test | +--------------------+ MariaDB [(none)]> SET sql_log_bin=1; //導入完成開啓二進制日誌 MariaDB [hellodb]> USE hellodb; Database changed MariaDB [hellodb]> CREATE TABLE tb1 (ID INT); MariaDB [hellodb]> SHOW TABLES; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | tb1 | | teachers | | toc | +-------------------+ MariaDB [hellodb]> 進行一次完整備份: [root@Master ~]# innobackupex --user=larry --password=QAZWSX123 /backups .......... .......... innobackupex: Backup created in directory '/backups/2014-04-01_12-41-31' innobackupex: MySQL binlog position: filename 'maria-bin.000001', position 441 140401 12:02:20 innobackupex: Connection to database server closed 140401 12:02:20 innobackupex: completed OK! 這裏我是用的是備份用戶,命令執行後屏幕有大量的輸出信息,這裏只是截取了後面幾段重要的信息: 1.它將備份數據文件存放到了我新建的備份數據存放目錄,並且它保存至了一個以時間命令的目錄中。 2.binlogs文件的時間點,備份時它正處於那個二進制日誌文件的哪個點上 3.完成備份立即斷開與databases server的連接 4.通知備份完成 在備份目錄中也有幾個文件值得關注: 其中: (1)xtrabackup_checkpoints —— 備份類型(如完全或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息;TARE 每個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目錄來存儲備份數據。 |
3.模擬數據誤刪除並準備一個完全備份:
[root@Master ~]# rm -rf /mydata/data/* 一般情況下,在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。 innobakupex命令的--apply-log選項可用於實現上述功能。如下面的命令: [root@Master ~]# innobackupex --user=larry --password=QAZWSX123 --apply-log /backups/2014-04-01_12-41-31/ ........ ........ ........ xtrabackup: starting shutdown with innodb_fast_shutdown = 1 InnoDB: FTS optimize thread exiting. InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 2071686 140401 12:47:58 innobackupex: completed OK! 如果執行正確,其最後輸出的幾行信息通常如上: 在實現“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的內存的大小,默認通常爲100M。如果有足夠的內存可用,可以多劃分一些內存給prepare的過程,以提高其完成速度。 切記,不能再剛整理(準備)完成就用來恢復,什麼時候需要恢復就什麼時候整理! |
3.從一個完全備份中恢復數據
注意:恢復不用啓動MySQL innobackupex命令的--copy-back選項用於執行恢復操作,其通過複製所有數據相關的文件至mysql服務器DATADIR目錄中來執行恢復過程。innobackupex通過backup-my.cnf來獲取DATADIR目錄的相關信息。 [root@Master ~]# innobackupex --copy-back --user=larry --password=QAZWSX123 /backups/2014-04-01_12-41-31/ ........ ........ ........ 140401 12:56:00 innobackupex: completed OK! 如果執行正確,其輸出信息的最後幾行通常如上: [root@Master ~]# ls /mydata/data/ //數據文件已經恢復過來 hellodb ib_logfile0 mysql test ibdata1 ib_logfile1 performance_schema xtrabackup_binlog_pos_innodb [root@Master ~]# 但是這些恢復回來的數據文件屬主和屬組都是root,所以需要修改爲mysql. [root@Master ~]# chown -R mysql:mysql /mydata/data/ [root@Master data]# service mysqld start Starting MySQL [ OK ] [root@Master data]# |
4.驗證完整備份恢復結果:
MariaDB [(none)]> use hellodb; MariaDB [hellodb]> SHOW TABLES; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | tb1 | | teachers | | toc | +-------------------+ 在完成備份恢復後我們應當立即做一次完整備份: [root@Master data]# innobackupex --user=larry --password=QAZWSX123 /backups ....... ....... innobackupex: Backup created in directory '/backups/2014-04-01_13-06-56' innobackupex: MySQL binlog position: filename 'maria-bin.000001', position 441 140401 13:07:00 innobackupex: Connection to database server closed 140401 13:07:00 innobackupex: completed OK! |
5.使用innobackupex進行增量備份
爲了實驗效果再次操作一下數據庫,對數據進行改動: MariaDB [hellodb]> USE hellodb; MariaDB [hellodb]> CREATE TABLE t2 (Name CHAR(20)); MariaDB [hellodb]> INSERT INTO t2 VALUE ('larry'); MariaDB [hellodb]> select * from t2; +-------+ | Name | +-------+ | larry | +-------+ 每個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實現。 要實現第一次增量備份,可以使用下面的命令進行: [root@Master ~]# innobackupex --incremental /backups/ --incremental-basedir=/backups/2014-04-01_13-06-56/ ........ ........ innobackupex: Backup created in directory '/backups/2014-04-01_13-23-09' innobackupex: MySQL binlog position: filename 'maria-bin.000001', position 737 140401 13:23:14 innobackupex: Connection to database server closed 140401 13:23:14 innobackupex: completed OK! //第一次增量完成! 說明: --incremental 明確說明我們的操作是增量備份 --incremental-basedir= 明確說明我們是相對於誰做增量(上次完全/上次增量),如果每一次都相對於上次的完全備份做增量備份,那就是差異備份! 需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。 第二次增量備份 還是先改變一下數據: MariaDB [(none)]> CREATE DATABASE newdb; MariaDB [(none)]> USE newdb; MariaDB [newdb]> CREATE TABLE newtable (ID INT); MariaDB [newdb]> INSERT INTO newtable value (10); MariaDB [newdb]> select * from newtable; +------+ | ID | +------+ | 10 | +------+ [root@Master ~]# innobackupex --incremental /backups/ --incremental-basedir=/backups/2014-04-01_13-23-09/ 注意:這次我們是相對於上次增量做的增量備份! ....... ....... ....... innobackupex: Backup created in directory '/backups/2014-04-01_13-43-33' innobackupex: MySQL binlog position: filename 'maria-bin.000001', position 1152 140401 13:34:11 innobackupex: Connection to database server closed 140401 13:34:11 innobackupex: completed OK! 兩次增量備份完成後,如果數據又被修改,但是沒有做增量備份,那麼此刻只能依靠二進制文件進行恢復了: MariaDB [(none)]> USE hellodb; MariaDB [hellodb]> INSERT INTO tb1 value (30); 模擬將服務停止: [root@Master ~]# service mysqld stop Shutting down MySQL.. [ OK ] [root@Master ~]# rm -rf /mydata/data/* |
6.恢復操作:
“準備”(prepare)增量備份與整理完全備份有着一些不同,尤其要注意的是: (1)需要在每個備份(包括完全和各個增量備份)上,將已經提交的事務進行“重放”。“重放”之後,所有的備份數據將合併到完全備份上。 (2)基於所有的備份將未提交的事務進行“回滾”。 於是,操作就變成了: # innobackupex --apply-log --redo-only BASE-DIR 接着執行: # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1 而後是第二個增量: # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2 其中BASE-DIR指的是完全備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作; 準備第一次完全備份: [root@Master ~]# innobackupex --apply-log --redo-only /backups/2014-04-01_13-06-56/ 準備第一次增量備份: [root@Master ~]# innobackupex --apply-log --redo-only /backups/2014-04-01_13-23-09/ 準備第二次增量份: [root@Master data]# innobackupex --apply-log --redo-only /backups/2014-04-01_13-06-56/ --incremental-dir=/backups/2014-04-01_13-43-33/ 用準備好的完整備份恢復數據: [root@Master data]# innobackupex --apply-log --redo-only /backups/2014-04-01_13-06-56/ --incremental-dir=/backups/2014-04-01_13-43-33/ 數據目錄中的文件現在已經恢復: [root@Master ~]# ls /mydata/data/ hellodb ibdata1 ib_logfile0 ib_logfile1 mysql newdb performance_schema test 修改屬主屬組 [root@Master ~]# chown -R mysql:mysql /mydata/data/ 還原時間點: [root@Master ~]# mysqlbinlog /mydata/binlogs/maria-bin.000001 > /backups/inc.sql
[root@Master ~]# mysqlbinlog /mydata/binlogs/maria-bin.000001 > /backups/inc.sql [root@Master 2014-04-01_13-43-33]# mysql [root@Master 2014-04-01_13-43-33]# cd [root@Master ~]# service mysqld start Starting MySQL.. [ OK ] [root@Master ~]# mysql MariaDB [(none)]> set sql_log_bin=0; MariaDB [(none)]> source /backups/inc.sql; MariaDB [(none)]> USE newdb; MariaDB [newdb]> select * from newtable; +------+ | ID | +------+ | 10 | +------+ |
OK! 至此所有數據已經恢復回來了! |
下面在介紹一下這個備份工具的其他功能(在此不做示例)
1.Xtrabackup的“流”及“備份壓縮”功能
Xtrabackup對備份的數據文件支持“流”功能,即可以將備份的數據通過STDOUT傳輸給tar程序進行歸檔,而不是默認的直接保存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。如:
innobackupex --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz |
甚至也可以使用類似如下命令將數據備份至其它服務器:
innobackupex --stream=tar /backup | ssh [email protected] "cat - > /backups/`date +%F_%H-%M-%S`.tar" |
此外,在執行本地備份時,還可以使用--parallel選項對多個文件進行並行複製。此選項用於指定在複製時啓動的線程數目。當然,在實際進行備份時要利用此功能的便利性,也需要啓用innodb_file_per_table選項或共享的表空間通過innodb_data_file_path選項存儲在多個ibdata文件中。對某一數據庫的多個文件的複製無法利用到此功能。其簡單使用方法如下:
innobackupex --parallel /path/to/backup |
同時,innobackupex備份的數據文件也可以存儲至遠程主機,這可以使用--remote-host選項來實現:
innobackupex [email protected] /path/IN/REMOTE/HOST/to/backup |
2.導入或導出單張表
默認情況下,InnoDB表不能通過直接複製表文件的方式在mysql服務器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實現此種功能,不過,此時需要“導出”表的mysql服務器啓用了innodb_file_per_table選項(嚴格來說,是要“導出”的表在其創建之前,mysql服務器就啓用了innodb_file_per_table選項),並且“導入”表的服務器同時啓用了innodb_file_per_table和innodb_expand_import選項。
(1)“導出”表
導出表是在備份的prepare階段進行的,因此,一旦完全備份完成,就可以在prepare過程中通過--export選項將某表導出了:
innobackupex --apply-log --export /path/to/backup |
此命令會爲每個innodb表的表空間創建一個以.exp結尾的文件,這些以.exp結尾的文件則可以用於導入至其它服務器。
(2)“導入”表
要在mysql服務器上導入來自於其它服務器的某innodb表,需要先在當前服務器上創建一個跟原表表結構一致的表,而後才能實現將表導入:
mysql> CREATE TABLE mytable (...) ENGINE=InnoDB; |
然後將此表的表空間刪除:
mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE; |
接下來,將來自於“導出”表的服務器的mytable表的mytable.ibd和mytable.exp文件複製到當前服務器的數據目錄,然後使用如下命令將其“導入”:
mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE; |
3.使用Xtrabackup對數據庫進行部分備份
Xtrabackup也可以實現部分備份,即只備份某個或某些指定的數據庫或某數據庫中的某個或某些表。但要使用此功能,必須啓用innodb_file_per_table選項,即每張表保存爲一個獨立的文件。同時,其也不支持--stream選項,即不支持將數據通過管道傳輸給其它程序進行處理。
此外,還原部分備份跟還原全部數據的備份也有所不同,即你不能通過簡單地將prepared的部分備份使用--copy-back選項直接複製回數據目錄,而是要通過導入表的方向來實現還原。當然,有些情況下,部分備份也可以直接通過--copy-back進行還原,但這種方式還原而來的數據多數會產生數據不一致的問題,因此,無論如何不推薦使用這種方式。
(1)創建部分備份
創建部分備份的方式有三種:正則表達式(--include), 枚舉表文件(--tables-file)和列出要備份的數據庫(--databases)。
(a)使用--include
使用--include時,要求爲其指定要備份的表的完整名稱,即形如databasename.tablename,如:
innobackupex --include='^mageedu[.]tb1' /path/to/backup |
(b)使用--tables-file
此選項的參數需要是一個文件名,此文件中每行包含一個要備份的表的完整名稱;如:
#echo -e 'mageedu.tb1\nmageedu.tb2' > /tmp/tables.txt #innobackupex --tables-file=/tmp/tables.txt /path/to/backup |
(c)使用--databases
此選項接受的參數爲數據名,如果要指定多個數據庫,彼此間需要以空格隔開;同時,在指定某數據庫時,也可以只指定其中的某張表。此外,此選項也可以接受一個文件爲參數,文件中每一行爲一個要備份的對象。如:
#innobackupex --databases="mageedu testdb" /path/to/backup |
(2)整理(preparing)部分備份
prepare部分備份的過程類似於導出表的過程,要使用--export選項進行:
innobackupex --apply-log --export /pat/to/partial/backup |
此命令執行過程中,innobackupex會調用xtrabackup命令從數據字典中移除缺失的表,因此,會顯示出許多關於“表不存在”類的警告信息。同時,也會顯示出爲備份文件中存在的表創建.exp文件的相關信息。
(3)還原部分備份
還原部分備份的過程跟導入表的過程相同。當然,也可以通過直接複製prepared狀態的備份直接至數據目錄中實現還原,不要此時要求數據目錄處於一致狀態。
OK!Xtrabackup備份工具的使用方法介紹至此!