mysql資料庫備份工具:Xtrabackup的使用例子。
大資料量備份與還原,始終是個難點。當MYSQL超10G,用mysqldump來匯出就比較慢了。這裡介紹一個強大的開源工具Xtrabackup。 |
Xtrabackup簡介
Xtrabackup是由percona提供的mysql資料庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb資料庫進行熱備的工具,是商業備份工具InnoDB Hotbackup的一個很好的替代品。特點:
(1)備份過程快速、可靠; (2)備份過程不會打斷正在執行的事務; (3)能夠基於壓縮等功能節約磁碟空間和流量; (4)自動實現備份檢驗; (5)還原速度快;
Xtrabackup安裝
其最新版的軟體可從 http://www.percona.com/software/percona-xtrabackup/ 獲得。本文基於CentOS6.6的系統,因此,直接下載相應版本的rpm包安裝即可。
[[email protected] xtrabackup]# yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL //安裝依賴包
[[email protected] xtrabackup]# rpm -ivh percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm warning: percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY Preparing... ########################################### [100%] 1:percona-xtrabackup ########################################### [100%]
Xtrabackup備份的實現
1、完全備份
# innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
如果要使用一個最小許可權的使用者進行備份,則可基於如下命令建立此類使用者:
mysql> CREATE USER ’feiyu'@’localhost’ IDENTIFIED BY ’s3cret’; mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM ’feiyu’; mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ’feiyu’@’localhost’; mysql> FLUSH PRIVILEGES;
使用innobakupex備份時,其會呼叫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目錄來儲存備份資料。
2、準備(prepare)一個完全備份
一般情況下,在備份完成後,資料尚且不能用於恢復操作,因為備份的資料中可能會包含尚未提交的事務或已經提交但尚未同步至資料檔案中的事務。因此,此時資料檔案仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至資料檔案也使得資料檔案處於一致性狀態。
innobakupex命令的–apply-log選項可用於實現上述功能。如下面的命令:
# innobackupex --apply-log /path/to/BACKUP-DIR
如果執行正確,其最後輸出的幾行資訊通常如下:
xtrabackup: starting shutdown with innodb_fast_shutdown = 1 120407 9:01:36 InnoDB: Starting shutdown... 120407 9:01:40 InnoDB: Shutdown completed; log sequence number 92036620 120407 09:01:40 innobackupex: completed OK!
在實現“準備”的過程中,innobackupex通常還可以使用–use-memory選項來指定其可以使用的記憶體的大小,預設通常為100M。如果有足夠的記憶體可用,可以多劃分一些記憶體給prepare的過程,以提高其完成速度。
3、從一個完全備份中恢復資料
innobackupex命令的–copy-back選項用於執行恢復操作,其通過複製所有資料相關的檔案至mysql伺服器DATADIR目錄中來執行恢復過程。innobackupex通過backup-my.cnf來獲取DATADIR目錄的相關資訊。
# innobackupex --copy-back /path/to/BACKUP-DIR
如果執行正確,其輸出資訊的最後幾行通常如下:
innobackupex: Starting to copy InnoDB log files innobackupex: in '/backup/2012-04-07_08-17-03' innobackupex: back to original InnoDB log directory '/mydata/data' innobackupex: Finished copying back files. 120407 09:36:10 innobackupex: completed OK!
請確保如上資訊的最行一行出現“innobackupex: completed OK!”。
當資料恢復至DATADIR目錄以後,還需要確保所有資料檔案的屬主和屬組均為正確的使用者,如mysql,否則,在啟動mysqld之前還需要事先修改資料檔案的屬主和屬組。如:
# chown -R mysql:mysql /mydata/data/
4、使用innobackupex進行增量備份
每個InnoDB的頁面都會包含一個LSN資訊,每當相關的資料發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實現。
要實現第一次增量備份,可以使用下面的命令進行:
# innobackupex --incremental /backup --incremental-basedir=BASEDIR
(要對與完全備份實行增量備份,basedir指完全備份的目錄,要對上一次增量備份再執行增量備份,則指定上一次 增量備份的目錄)
其中,BASEDIR指的是完全備份所在的目錄,此命令執行結束後,innobackupex命令會在/backup目錄中建立一個新的以時間命名的目錄以存放所有的增量備份資料。另外,在執行過增量備份之後再一次進行增量備份時,其–incremental-basedir應該指向上一次的增量備份所在的目錄。
需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。
“準備”(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指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;
5、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
6、匯入或匯出單張表
預設情況下,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;
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='^feiyu[.]tb1' /path/to/backup
(b)使用–tables-file 此選項的引數需要是一個檔名,此檔案中每行包含一個要備份的表的完整名稱;如:
# echo -e 'feiyu.tb1\nmageedu.tb2' > /tmp/tables.txt # innobackupex --tables-file=/tmp/tables.txt /path/to/backup
(c)使用–databases 此選項接受的引數為資料名,如果要指定多個數據庫,彼此間需要以空格隔開;同時,在指定某資料庫時,也可以只指定其中的某張表。此外,此選項也可以接受一個檔案為引數,檔案中每一行為一個要備份的物件。如:
# innobackupex --databases="feiyu testdb" /path/to/backup
(2)整理(preparing)部分備份 prepare部分備份的過程類似於匯出表的過程,要使用–export選項進行:
# innobackupex --apply-log --export /pat/to/partial/backup
此命令執行過程中,innobackupex會呼叫xtrabackup命令從資料字典中移除缺失的表,因此,會顯示出許多關於“表不存在”類的警告資訊。同時,也會顯示出為備份檔案中存在的表建立.exp檔案的相關資訊。
(3)還原部分備份 還原部分備份的過程跟匯入表的過程相同。當然,也可以通過直接複製prepared狀態的備份直接至資料目錄中實現還原,不要此時要求資料目錄處於一致狀態。
下面實際演示其完整的備份流程:
←#14#[email protected] /tmp/full-backup →innobackupex --user=root /tmp/full-backup/ #完全備份 InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy and Percona LLC and/or its affiliates 2009-2013. All Rights Reserved. 。。。。。。。。。。 xtrabackup: The latest check point (for incremental): '2987626' xtrabackup: Stopping log copying thread. .>> log scanned up to (2987626) xtrabackup: Creating suspend file '/tmp/full-backup/2015-06-25_05-58-26/xtrabackup_log_copied' with pid '7858' xtrabackup: Transaction log of lsn (2987626) to (2987626) was copied. 150625 05:58:30 innobackupex: All tables unlocked innobackupex: Backup created in directory '/tmp/full-backup/2015-06-25_05-58-26' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 2383 150625 05:58:30 innobackupex: Connection to database server closed 150625 05:58:30 innobackupex: completed OK!
mysql> insert into tutors(tname) values('stu00011');#在資料庫中插入資料 Query OK, 1 row affected (0.03 sec) mysql> insert into tutors(tname) values('stu00012'); Query OK, 1 row affected (0.00 sec)
←#246#[email protected] /tmp →innobackupex --incremental /tmp/full-backup/ --incremental-basedir=/tmp/full-backup/2015-06-25_05-58-26/ #做增量備份 InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy and Percona LLC and/or its affiliates 2009-2013. All Rights Reserved. 。。。。。。。。。。。 xtrabackup: Creating suspend file '/tmp/full-backup/2015-06-25_06-00-48/xtrabackup_log_copied' with pid '8663' xtrabackup: Transaction log of lsn (2988209) to (2988209) was copied. 150625 06:00:53 innobackupex: All tables unlocked innobackupex: Backup created in directory '/tmp/full-backup/2015-06-25_06-00-48' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 2924 150625 06:00:53 innobackupex: Connection to database server closed 150625 06:00:53 innobackupex: completed OK!
mysql> insert into tutors(tname) values('stu00014'); #再次插入資料 Query OK, 1 row affected (0.02 sec) mysql> insert into tutors(tname) values('stu00015'); Query OK, 1 row affected (0.00 sec)
←#247#[email protected] /tmp →innobackupex --incremental /tmp/full-backup/ --incremental-basedir=/tmp/full-backup/2015-06-25_06-00-48 #再次做增量備份 InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy and Percona LLC and/or its affiliates 2009-2013. All Rights Reserved 。。。。。。。。。 xtrabackup: Creating suspend file '/tmp/full-backup/2015-06-25_06-02-41/xtrabackup_log_copied' with pid '9259' xtrabackup: Transaction log of lsn (2988781) to (2988781) was copied. 150625 06:02:45 innobackupex: All tables unlocked innobackupex: Backup created in directory '/tmp/full-backup/2015-06-25_06-02-41' innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 3465 150625 06:02:46 innobackupex: Connection to database server closed 150625 06:02:46 innobackupex: completed OK!
←#266#[email protected] /tmp/full-backup/2015-06-25_05-58-26 →cat xtrabackup_checkpoints #檢視日誌序列號是否一致 backup_type = log-applied from_lsn = 0 to_lsn = 2987626 last_lsn = 2987626 compact = 0 ←#267#[email protected] /tmp/full-backup/2015-06-25_05-58-26 →cd ../2015-06-25_06-00-48/ ←#268#[email protected] /tmp/full-backup/2015-06-25_06-00-48 →cat xtrabackup_checkpoints backup_type = incremental from_lsn = 2987626 to_lsn = 2988209 last_lsn = 2988209 compact = 0 ←#269#[email protected] /tmp/full-backup/2015-06-25_06-00-48 →cd ../2015-06-25_06-02-41/ ←#270#[email protected] /tmp/full-backup/2015-06-25_06-02-41 →cat xtrabackup_checkpoints backup_type = incremental from_lsn = 2988209 to_lsn = 2988781 last_lsn = 2988781 compact = 0
←#248#[email protected] /tmp →innobackupex --apply-log --redo-only /tmp/full-backu2015-06-25_05-58-26/ #做準備 InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy and Percona LLC and/or its affiliates 2009-2013. All Rights Reserved. [notice (again)] If you use binary log and don't use any hack of group commit, the binary log position seems to be: InnoDB: Last MySQL binlog file position 0 2241, file name ./mysql-bin.000001 xtrabackup: starting shutdown with innodb_fast_shutdown = 1 InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 2987626 150625 06:04:03 innobackupex: completed OK! ←#249#[email protected] /tmp →innobackupex --apply-log --redo-only /tmp/full-backu2015-06-25_05-58-26/ --incremental-dir=/tmp/full-backup/2015-06-25_06-00-48/ #合併第一次增量備份檔案 。。。。。。。。。。 innobackupex: Copying '/tmp/full-backup/2015-06-25_06-00-48/management/admin.frm' to '/tmp/full-backup/2015-06-25_05-58-26/management/admin.frm' 150625 06:05:28 innobackupex: completed OK! ←#251#[email protected] /tmp →innobackupex --apply-log --redo-only /tmp/full-backu2015-06-25_05-58-26/ --incremental-dir=/tmp/full-backup/2015-06-25_06-02-41/ #合併第二次增量備份檔案 。。。。。。。。。。。。。。。。 innobackupex: Copying '/tmp/full-backup/2015-06-25_06-02-41/management/classinfo.frm' to '/tmp/full-backup/2015-06-25_05-58-26/management/classinfo.frm' innobackupex: Copying '/tmp/full-backup/2015-06-25_06-02-41/management/admin.frm' to '/tmp/full-backup/2015-06-25_05-58-26/management/admin.frm' 150625 06:07:10 innobackupex: completed OK! ←#258#[email protected] ~ →rm -rf /mydata/data1/* #刪除資料檔案目錄 ←#259#[email protected] ~ →innobackupex --copy-back /tmp/full-backup/2015-06-25_05-58-26/ #恢復 。。。。。。。。。。。。。。。。 innobackupex: Starting to copy InnoDB log files innobackupex: in '/tmp/full-backup/2015-06-25_05-58-26' innobackupex: back to original InnoDB log directory '/mydata/data1' innobackupex: Finished copying back files. 150625 06:12:29 innobackupex: completed OK! ←#276#[email protected] /mydata/data1 →chown -R mysql.mysql ./* #修改屬主和屬組