mysqldump是一種邏輯備份方式,將數據轉換成sql文件,其最大的缺陷就是備份和恢復時間很長,對於一個小於10G的數據庫而言,這個速度仍是能夠接受的,可是若是數據庫較大,那在使用mysqldump備份就很是不合適了。python
lvm是一種採用邏輯卷快照功能對數據進行備份,能夠實現幾乎熱備,可是備份過程較爲複雜(來回切換終端),很難用shell腳本直接實現,不過如今彷佛有個工具mylvmbackup能夠實現自動化備份,可是沒有嘗試過,改天我也試試。mysql
Xtrabackup對MyISAM表只能實現溫備,而且不支持增量備份,因此每次對MyISAM表備份都是全備正則表達式
XtraBackup更多高級特性一般只能在innodb存儲引擎上實現,並且高級特性還都依賴於mysql數據庫對innodb引擎實現了單獨表空間,不然沒辦法實現單表或單庫導出sql
mysql> show global variables like '%innodb_file_per_table%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+
那麼今天就和你們聊聊第三款開源備份工具xtrabackup:shell
官方站點:http://www.percona.com數據庫
官方在線文檔:http://www.percona.com/doc/percona-xtrabackup/2.2/bash
最新軟件包下載地址:http://www.percona.com/downloads/XtraBackup/服務器
1、簡介app
Xtrabackup是由percona提供的mysql數據庫開源熱備工具。特色以下:ssh
(1)備份過程快速、可靠;
(2)備份過程不會打斷正在執行的事務;
(3)可以基於壓縮等功能節約磁盤空間和流量;
(4)自動實現備份檢驗;
(5)還原速度快;
2、安裝
XtraBackup目前最新版爲2.2.9,本篇博客採用yum安裝方式
一、yum安裝
# yum -y install libaio perl-Time-HiRes perl-DBD-MySQL perl-IO-Socket-SSL # rpm -ivh http://www.percona.com/downloads/XtraBackup/XtraBackup-2.2.9/binary/redhat/6/x86_64/percona-xtrabackup-2.2.9-5067.el6.x86_64.rpm
二、查看Xtrabackup安裝的工具
# rpm -ql percona-xtrabackup |grep bin /usr/bin/innobackupex /usr/bin/xbcrypt /usr/bin/xbstream /usr/bin/xtrabackup
三、XtraBackup中主要包含了三個工具
xbsteam:支持流式備份
xtrbackup:用於熱備innodb、xtradb表中數據的工具,不能備份其它類型的表,也不能備份數據表結構
innobackupex:是將xtrabackup進行封裝的perl腳本,提供了備份MyISAM表的能力
3、innobackupex幾個很是重要的參數
--apply-log
通常狀況下,在備份完成後,數據尚且不能用於恢復操做,由於備份的數據中可能會包含還沒有提交的事務或已經提交但還沒有同步至數據文件中的事務。所以,此時數據文件仍處理不一致狀態。「準備」的主要做用正是經過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。
--redo-only
準備(prepare)增量備份與整理徹底備份有着一些不一樣,尤爲要注意的是:
(1)須要在每一個備份(包括徹底和各個增量備份)上,將已經提交的事務進行「重放」。「重放」以後,全部的備份數據將合併到徹底備份上。
(2)基於全部的備份將未提交的事務進行「回滾」。
--copy-back
該選項用於執行恢復(還原)操做,其經過複製全部數據相關的文件至mysql服務器DATADIR目錄中來執行恢復過程。innobackupex經過backup-my.cnf來獲取DATADIR目錄的相關信息。
4、innobackup備份語法
徹底備份+徹底恢復
徹底備份 # innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/ 準備一個徹底備份 # innobackupex --apply-log /path/to/BACKUP-DIR 從一個徹底備份中恢復數據 # innobackupex --copy-back /path/to/BACKUP-DIR 修改datadir目錄權限 # chown -R mysql:mysql /mydata/data/
徹底備份+增量備份+徹底恢復
徹底備份: # innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/ 第一次增量備份 # innobackupex --user=DBUSER --password=DBUSERPASS --incremental /backup --incremental-basedir=BASEDIR 第二次增量備份 # innobackupex --user=DBUSER --password=DBUSERPASS --incremental /backup --incremental-basedir=BASEDIR 準備: 執行徹底備份redo # innobackupex --apply-log --redo-only BASE-DIR 執行第一次增量備份redo # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1 執行第二次增量備份redo # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2 還原: # innobackupex --copy-back BASE-DIR 解釋: 其中BASE-DIR指的是徹底備份所在的目錄, 而INCREMENTAL-DIR-1指的是第一次增量備份的目錄, INCREMENTAL-DIR-2指的是第二次增量備份的目錄, 其它依次類推,即若是有屢次增量備份,每一次都要執行如上操做;
5、以上兩種方式案列重放
徹底備份+徹底恢復
一、實驗前的準備工做 # service mysqld stop # rm -rf /mydata/data/* # /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ --basedir=/usr/local/mysql/ # service mysqld start # mysqladmin -uroot -p password 123456 # mysql -uroot -p123456 mysql> create database jiaowu; mysql> use jiaowu; mysql> set sql_log_bin = 0; mysql> source /root/tutor.sql; //導入tutor數據表 mysql> set sql_log_bin = 1; mysql> select * from tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | +------+---------------+--------+------+ 9 rows in set (0.00 sec) 二、innobackupex對DB進行徹底備份 # innobackupex --user=root --password=123456 /backup/ 若是執行正確,其最後輸出的幾行信息一般以下: innobackupex: Backup created in directory '/backup/2015-03-18_21-00-17' innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 332 150318 21:00:23 innobackupex: Connection to database server closed 150318 21:00:23 innobackupex: completed OK! 三、查看備份目錄和文件 # ls /backup/ 2015-03-18_21-00-17 # ls /backup/2015-03-18_21-00-17/ backup-my.cnf jiaowu performance_schema xtrabackup_binlog_info xtrabackup_info ibdata1 mysql test xtrabackup_checkpoints xtrabackup_logfile 四、準備一個徹底備份 # innobackupex --user=root --password=123456 --apply-log /backup/2015-03-18_21-00-17/ #####模擬數據庫故障##### 五、這裏仍是採用老方法直接刪除全部的數據文件 # service mysqld stop # rm -rf /mydata/data/* 六、從一個徹底備份中恢復數據庫 # innobackupex --copy-back /backup/2015-03-18_21-00-17/ 七、修改數據目錄權限 # chown -R mysql.mysql /mydata/data/ 八、啓動mysqld服務 # service mysqld start 九、登錄mysql查看是不是否一致 # mysql -e 'use jiaowu;select * from tutor;' +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | +------+---------------+--------+------+ #數據已經成功恢復到數據庫當中
徹底備份+增量備份+徹底恢復
一、實驗前的準備工做 # service mysqld stop # rm -rf /mydata/data/* //刪除原來的備份文件 # rm -rf /backup/* # /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ --basedir=/usr/local/mysql/ # service mysqld start # mysqladmin -uroot -p password 123456 # mysql -uroot -p123456 mysql> create database jiaowu; mysql> use jiaowu; mysql> set sql_log_bin = 0; mysql> source /root/tutor.sql; //導入tutor數據表 mysql> set sql_log_bin = 1; mysql> select * from tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | +------+---------------+--------+------+ 9 rows in set (0.00 sec) 二、innobackupex對DB進行徹底備份 # innobackupex --user=root --password=123456 /backup/ 若是執行正確,其最後輸出的幾行信息一般以下: innobackupex: Backup created in directory '/backup/2015-03-18_21-14-49' innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 332 150318 21:14:54 innobackupex: Connection to database server closed 150318 21:14:54 innobackupex: completed OK! 三、僅查看備份目錄 # ls /backup/ 2015-03-18_21-14-49 四、操做數據庫並插入數據 # mysql jiaowu; mysql> insert into tutor(TID) values(11); mysql> insert into tutor(TID) values(12); mysql> insert into tutor(TID) values(13); mysql> select * from tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | | 11 | NULL | NULL | NULL | | 12 | NULL | NULL | NULL | | 13 | NULL | NULL | NULL | +------+---------------+--------+------+ 12 rows in set (0.00 sec) 五、執行第一次增量備份並查看備份目錄 # innobackupex --user=root --password=123456 --incremental /backup/ --incremental-basedir=/backup/2015-03-18_21-14-49/ # ls /backup/ 2015-03-18_21-14-49 2015-03-18_21-18-45 六、再次操做數據庫並插入多條數據 # mysql jiaowu; mysql> insert into tutor(TID) values(21); mysql> insert into tutor(TID) values(22); mysql> insert into tutor(TID) values(23); mysql> select * from tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | | 11 | NULL | NULL | NULL | | 12 | NULL | NULL | NULL | | 13 | NULL | NULL | NULL | | 21 | NULL | NULL | NULL | | 22 | NULL | NULL | NULL | | 23 | NULL | NULL | NULL | +------+---------------+--------+------+ 15 rows in set (0.00 sec) 七、執行第二次增量備份並查看備份文件 # innobackupex --user=root --password=123456 --incremental /backup/ --incremental-basedir=/backup/2015-03-18_21-18-45/ # ls /backup/ 2015-03-18_21-14-49 2015-03-18_21-18-45 2015-03-18_21-22-31 解釋: 2015-03-18_21-14-49:爲innobackupex的徹底備份目錄 2015-03-18_21-18-45:爲innobackupex的第一次增量備份目錄 2015-03-18_21-22-31:爲innobackupex的第二次增量備份目錄 八、開始準備innobackupex 首先執行徹底備份redo-only # innobackupex --user=root --password=123456 --apply-log --redo-only /backup/2015-03-18_21-14-49/ 執行第一個增量備份redo-only # innobackupex --user=root --password=123456 --apply-log --redo-only /backup/2015-03-18_21-14-49/ --incremental-dir=/backup/2015-03-18_21-18-45/ 執行第二個增量備份redo-only # innobackupex --user=root --password=123456 --apply-log --redo-only /backup/2015-03-18_21-14-49/ --incremental-dir=/backup/2015-03-18_21-22-31/ #####模擬數據庫故障##### 九、這裏仍是採用老方法直接刪除全部的數據文件 # service mysqld stop # rm -rf /mydata/data/* 十、從徹底備份中恢復數據庫 # innobackupex --user=root --password=123456 --copy-back /backup/2015-03-18_21-14-49/ 十一、修改數據目錄權限 # chown -R mysql.mysql /mydata/data/ 十二、啓動mysqld服務 # service mysqld start 1三、登錄mysql查看是不是否一致 # mysql -e 'use jiaowu;select * from tutor;' +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | | 11 | NULL | NULL | NULL | | 12 | NULL | NULL | NULL | | 13 | NULL | NULL | NULL | | 21 | NULL | NULL | NULL | | 22 | NULL | NULL | NULL | | 23 | NULL | NULL | NULL | +------+---------------+--------+------+ #兩次增量添加的數據也已經成功添加到數據庫當中。恢復成功
6、Xtrabackup的高級功能
流式壓縮功能
Xtrabackup對備份的數據文件支持「流」功能,便可以將備份的數據經過STDOUT傳輸給tar程序進行歸檔,而不是默認的直接保存至某備份目錄中。要使用此功能,僅須要使用--stream選項便可。如:
# innobackupex --user=root --password=123456 --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz
甚至也可使用相似以下命令將數據備份至其它服務器:強烈推薦這種方式
# innobackupex --user=root --password=123456 --stream=tar /backup | ssh root@192.168.1.100 'cat - > /backup/`date +%F_%H-%M-%S`.tar'
在執行本地備份時,還可使用--parallel選項對多個文件進行並行複製(暫時尚未看懂此選項)
此外,在執行本地備份時,還可使用--parallel選項對多個文件進行並行複製。此選項用於指定在複製時啓動的線程數目。固然,在實際進行備份時要利用此功能的便利性,也須要啓用innodb_file_per_table選項或共享的表空間經過innodb_data_file_path選項存儲在多個ibdata文件中。對某一數據庫的多個文件的複製沒法利用到此功能。其簡單使用方法以下: # innobackupex --parallel /path/to/backup 同時,innobackupex備份的數據文件也能夠存儲至遠程主機,這可使用--remote-host選項來實現: # innobackupex --remote-host=root@www.magedu.com /path/IN/REMOTE/HOST/to/backup
7、使用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狀態的備份直接至數據目錄中實現還原,不要此時要求數據目錄處於一致狀態。
案列演示:
對jiaowu數據庫進行備份和還原
一、查看數據庫和表 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | jiaowu | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> select * from jiaowu.tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | | 11 | NULL | NULL | NULL | | 12 | NULL | NULL | NULL | | 13 | NULL | NULL | NULL | | 21 | NULL | NULL | NULL | | 22 | NULL | NULL | NULL | | 23 | NULL | NULL | NULL | +------+---------------+--------+------+ 二、innobackupex進行備份 # innobackupex --user=root --password=123456 --databases='jiaowu' /opt/ 三、準備並導入jiaowu表 # innobackupex --user=root --password=123456 --apply-log --export /opt/2015-03-18_22-46-47/ 四、刪除jiaowu數據庫 # rm -rf /mydata/data/jiaowu 五、登錄數據庫查看是否還存在jiaowu數據庫 [root@localhost ~]# mysql -e 'show databases;' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ #jiaowu數據庫不存在了 六、還原jiaowu數據庫 # cp -a /opt/2015-03-18_22-46-47/jiaowu/ /mydata/data/ 七、修改jiaowu權限 # chown -R mysql.mysql /mydata/data/jiaowu 八、再次查看jiaowu數據庫是否存在 [root@localhost ~]# mysql -e 'use jiaowu;show tables;' +------------------+ | Tables_in_jiaowu | +------------------+ | tutor | +------------------+ #jiaowu數據庫已經被還原而且表tutor還在。成功!!!
8、導入或導出單張表
默認狀況下,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;
案列演示:
一、查看錶 mysql> use jiaowu; Database changed mysql> show tables; +------------------+ | Tables_in_jiaowu | +------------------+ | tutor | +------------------+ 1 row in set (0.00 sec) 二、修改表的存儲引擎爲InnoDB mysql> alter table tutor engine=innodb; Query OK, 15 rows affected (0.05 sec) Records: 15 Duplicates: 0 Warnings: 0 三、innobackupex對其進行備份 # innobackupex --user=root --password=123456 --databases='jiaowu.tutor' /opt/ 四、準備並導出 # innobackupex --user=root --password=123456 --apply-log --export /opt/2015-03-18_23-05-44/ 五、刪除此表的表空間 mysql> ALTER TABLE jiaowu.tutor DISCARD TABLESPACE; Query OK, 0 rows affected (0.01 sec) mysql> use jiaowu; Database changed mysql> select * from tutor; #數據已經不存在了 ERROR 1030 (HY000): Got error -1 from storage engine 六、接下來,未來自於「導出」表的服務器的mytable表的mytable.ibd和mytable.exp文件複製到當前服務器的數據目錄,而後使用以下命令將其「導入」:並修改權限 # cp /opt/2015-03-18_23-24-23/jiaowu/{tutor.exp,tutor.ibd} /mydata/data/jiaowu/ cp:是否覆蓋"/mydata/data/jiaowu/tutor.exp"? yes # chown -R mysql.mysql /mydata/data/jiaowu/* mysql> ALTER TABLE jiaowu.tutor IMPORT TABLESPACE; Query OK, 0 rows affected (0.00 sec) mysql> use jiaowu; Database changed mysql> select * from tutor; +------+---------------+--------+------+ | TID | Tname | Gender | Age | +------+---------------+--------+------+ | 1 | ZhengYansheng | M | 25 | | 2 | LiJian | M | 26 | | 3 | OuYangyu | M | 27 | | 4 | LuoChenghui | M | 25 | | 5 | LiuYunbo | M | 25 | | 6 | FuJian | M | 24 | | 7 | LiMenglu | F | 23 | | 8 | BaoYintu | M | 28 | | 9 | WangYana | F | 25 | | 11 | NULL | NULL | NULL | | 12 | NULL | NULL | NULL | | 13 | NULL | NULL | NULL | | 21 | NULL | NULL | NULL | | 22 | NULL | NULL | NULL | | 23 | NULL | NULL | NULL | +------+---------------+--------+------+ 15 rows in set (0.00 sec) #單表還原已經成功!結束。