MySQL 備份和恢復(三)Xtrabackup實現熱備:完全備份+增量備份

Percona XtraBackup is the world’s only open-source, free MySQL hot backup software that performs non-blocking backups for InnoDB and XtraDB databases. With Percona XtraBackup, you can achieve the following benefits:

  • Backups that complete quickly and reliably

  • Uninterrupted transaction processing during backups

  • Savings on disk space and network bandwidth

  • Automatic backup verification

  • Higher uptime due to faster restore time

以上摘自官方文檔對Xtrabackup的描述。


Xtrabackup是Percona公司的開源mysql熱備軟件,軟件自身支持完全備份和增量備份,功能強大,使用簡單,且備份結束會自動檢查備份的可用性。對於InnoDB和XtraDB可以實現無阻塞的備份。


Xtrabackup會在備份目錄下自動生成以當前日期和時間爲名的目錄,目錄下包含當前備份所有數據文件和豐富的當前備份時的狀態信息。



實例演示:

xtrabackup的安裝,安裝包可從官網下載http://www.percona.com/software/percona-xtrabackup,官方提供了二進制和源碼包,根據自己需要下載

/* 下載官方的rpm包安裝,xtrabackup要依賴perl-DBD-mysql包,不想手動解決依賴關係可以yum localinstall安裝 */
[root@console ~]# yum localinstall --nogpgcheck percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm -y

/* xtrabackup安裝後生成的文件不多 */
[root@console ~]# rpm -ql percona-xtrabackup
/usr/bin/innobackupex        /* 備份時用的命令,會根據mysql版本自動調用xtrabackup_{55,56} */
/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.4
/usr/share/doc/percona-xtrabackup-2.1.4/COPYING    /* 文檔只有一個軟件授權文件,沒有man文檔,不過--help給出的幫助信息也比較豐富 */

備份過程:

/* 在庫db1中準備一張表tb1,做效果比較用 */
MariaDB [(none)]> CREATE DATABASE db1;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> USE db1
Database changed
MariaDB [db1]> CREATE TABLE `tb1` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `Name` varchar(30) NOT NULL,   `Gender` enum('F','M','O') NOT NULL,   PRIMARY KEY (`id`) );
Query OK, 0 rows affected (0.22 sec)

MariaDB [db1]> DESC tb1;
+--------+-------------------+------+-----+---------+----------------+
| Field  | Type              | Null | Key | Default | Extra          |
+--------+-------------------+------+-----+---------+----------------+
| id     | int(11)           | NO   | PRI | NULL    | auto_increment |
| Name   | varchar(30)       | NO   |     | NULL    |                |
| Gender | enum('F','M','O') | NO   |     | NULL    |                |
+--------+-------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

MariaDB [db1]> INSERT INTO tb1 (Name,Gender) VALUES ('Tom','M'),('Jerry','F');
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [db1]> SELECT * FROM tb1;
+----+-------+--------+
| id | Name  | Gender |
+----+-------+--------+
|  1 | Tom   | M      |
|  2 | Jerry | F      |
+----+-------+--------+
2 rows in set (0.00 sec)

/* 創建一個用於備份的最小權限的用戶 */
MariaDB [(none)]> CREATE USER 'bakuser'@'localhost' IDENTIFIED BY 'backupass';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'bakuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT RELOAD,LOCK TABLES,REPLICATION CLIENT ON *.* TO 'bakuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)


現在先做一次完全備份:

/* 全備只需指定用於備份的用戶名、密碼和備份路徑即可,最後出現innobackupex: completed OK! 則代表備份成功 */
[root@node1 ~]# innobackupex --user=bakuser --password=backupass /innobackup/
innobackupex: Backup created in directory '/innobackup/2014-07-31_09-27-36'
innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 1270
140731 09:27:39  innobackupex: Connection to database server closed
140731 09:27:40  innobackupex: completed OK!

/* 看一下備份都生成了哪些文件,除了數據庫文件外還多了一些文件,注意由於我用root登陸系統,備份後的文件屬主屬組都是root,恢復後要改爲運行mysqld進程的用戶,不然mysql起不來 */
[root@node1 ~]# cd /innobackup/2014-07-31_09-27-36/
[root@node1 2014-07-31_09-27-36]# ll
total 18476
-rw-r--r--. 1 root root      260 Jul 31 09:27 backup-my.cnf /* 備份命令用到的配置選項信息 */
drwx------. 2 root root     4096 Jul 31 09:27 db1    
drwx------. 2 root root     4096 Jul 31 09:27 hellodb
-rw-r-----. 1 root root 18874368 Jul 31 09:27 ibdata1
drwx------. 2 root root     4096 Jul 31 09:27 mydb
drwxr-xr-x. 2 root root     4096 Jul 31 09:27 mysql
drwxr-xr-x. 2 root root     4096 Jul 31 09:27 performance_schema
drwxr-xr-x. 2 root root     4096 Jul 31 09:27 test
-rw-r--r--. 1 root root       13 Jul 31 09:27 xtrabackup_binary    /* 記錄備份過程實際用的備份程序 */
-rw-r--r--. 1 root root       24 Jul 31 09:27 xtrabackup_binlog_info    /* 記錄備份時的二進制日誌文件和當前的位置 */
-rw-r-----. 1 root root       89 Jul 31 09:27 xtrabackup_checkpoints    /* 記錄備份類型、
狀態(是否prepared)、是否壓縮、備份的LSN(Log Sequence Number日誌序列號)範圍等信息 */
-rw-r-----. 1 root root     2560 Jul 31 09:27 xtrabackup_logfile    /* xtrabackup自己的日誌文件,新版本中不直接可見 */

[root@node1 2014-07-31_09-27-36]# cat backup-my.cnf 
# This MySQL options file was generated by innobackupex.

# The MySQL server
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=5242880
innodb_fast_checksum=0
innodb_page_size=16384
innodb_log_block_size=512
[root@node1 2014-07-31_09-27-36]# cat xtrabackup_binary 
xtrabackup_55[root@node1 2014-07-31_09-27-36]# 
[root@node1 2014-07-31_09-27-36]# cat xtrabackup_binlog_info 
mysql-bin.000001	1270		
[root@node1 2014-07-31_09-27-36]# cat xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 1660869
last_lsn = 1660869
compact = 0
[root@node1 2014-07-31_09-27-36]# file xtrabackup_logfile 
xtrabackup_logfile: data


全備完成後,對數據庫做一些修改後再做一次增備:

/* 第一次增量備份,--incremental 備份類型爲增量, --incremental-basedir 指定這次增備是相對哪一個備份做的增量,這裏是相對全備  */
[root@node1 innobackup]# innobackupex --user=bakuser --password=backupass --incremental /innobackup/ --incremental-basedir=/innobackup/2014-07-31_09-27-36/
innobackupex: Backup created in directory '/innobackup/2014-07-31_11-51-19'
innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 1525
140731 11:51:48  innobackupex: Connection to database server closed
140731 11:51:48  innobackupex: completed OK!

/* 做些修改,做第二次增備 */
MariaDB [db1]> DELETE FROM tb1 WHERE Name='Tom';
Query OK, 1 row affected (0.09 sec)

MariaDB [db1]> UPDATE tb1 SET Gender='F' WHERE Name='Dongfang Bubai';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [db1]> SELECT * FROM tb1;
+----+----------------+--------+
| id | Name           | Gender |
+----+----------------+--------+
|  2 | Jerry          | F      |
|  3 | Bob            | M      |
|  4 | Dongfang Bubai | F      |
+----+----------------+--------+
3 rows in set (0.00 sec)

/* incremental-basedir 相對第一次增量的增量 */
[root@node1 innobackup]# innobackupex --user=bakuser --password=backupass --incremental /innobackup/ --incremental-basedir=/innobackup/2014-07-31_11-51-19/
innobackupex: Backup created in directory '/innobackup/2014-07-31_11-59-29'
innobackupex: MySQL binlog position: filename 'mysql-bin.000001', position 1922
140731 11:59:33  innobackupex: Connection to database server closed
140731 11:59:33  innobackupex: completed OK!

/* 第二次增備完成後,再做一些數據修改操作,以模擬實際生產環境數據庫突然崩潰場景 */
MariaDB [db1]> INSERT INTO tb1 (Name,Gender) VALUES ('Kangshifu Guamian','O');
Query OK, 1 row affected (0.04 sec)

/* 將二進制日誌備份出來一份,生產環境中二進制日誌切記不要和數據文件放在一起,
最好不要在同一分區甚至同一物理磁盤, 以免一旦玉石俱焚,悔之晚矣 */
[root@node1 innobackup]# mysql -e 'SHOW MASTER STATUS;'
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |     2168 |              |                  |
+------------------+----------+--------------+------------------+
[root@node1 innobackup]# cp /mydata/data/
aria_log.00000001   hellodb/            ib_logfile1         mysql-bin.000001    node1.bob.org.pid
aria_log_control    ibdata1             mydb/               mysql-bin.index     performance_schema/
db1/                ib_logfile0         mysql/              node1.bob.org.err   test/
[root@node1 innobackup]# cp /mydata/data/mysql-bin.000001 /innobackup/

/* 人工讓數據庫徹底崩盤 */
[root@node1 innobackup]# service mysqld stop
Shutting down MySQL..                                      [  OK  ]
[root@node1 innobackup]# rm -rf /mydata/data/*

恢復

    xtrabackup的恢復比較特殊,恢復前要先執行prepare過程,prepare主要完成把已提交的事務數據同步到數據文件,未完成的事務則回滾,這是對於只有一個完全備份來說。當還需要結合其他的增備時,則在些過程只需要將已提交的事務同步,未提交的事務則不用回滾,因爲在本次備份時未提交的事務可能會在下一備份中已經提交,以避免這種無謂的勞動。

/* 注意 backup_type 和 to_lsn的變化 */
[root@node1 innobackup]# cat 2014-07-31_09-27-36/xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 1660869
last_lsn = 1660869
compact = 0 

/* Prepare全備,--apply-log 指定要prepare, --redo-only 只處理已提交事務,未提交的事務則不回滾
 backup_type由full-backuped --> full-prepared */
[root@node1 innobackup]# innobackupex --apply-log --redo-only /innobackup/2014-07-31_09-27-36/
...
140731 15:05:53  innobackupex: completed OK!
[root@node1 innobackup]# cat 2014-07-31_09-27-36/xtrabackup_checkpoints 
backup_type = full-prepared
from_lsn = 0
to_lsn = 1660869
last_lsn = 1660869
compact = 0

/* prepare 增備1, --incremental-dir 增備的路徑 */
[root@node1 innobackup]# innobackupex --apply-log --redo-only /innobackup/2014-07-31_09-27-36/ --incremental-dir /innobackup/2014-07-31_11-51-19/

/* 再來看full backup 的 to_lsn 已經 --> 增備1 的 to_lsn了,此時增量1也就退出舞臺了 */
[root@node1 innobackup]# cat 2014-07-31_11-51-19/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1660869
to_lsn = 1661993
last_lsn = 1661993
compact = 0
[root@node1 innobackup]# cat 2014-07-31_09-27-36/xtrabackup_checkpoints 
backup_type = full-prepared
from_lsn = 0
to_lsn = 1661993
last_lsn = 1661993
compact = 0

/* prepare 增備2,增量1已經prepare上去了,所以基準還是全備,--incremental-dir 指向增量2 */
[root@node1 innobackup]# innobackupex --apply-log /innobackup/2014-07-31_09-27-36/ --incremental-dir=/innobackup/2014-07-31_11-59-29/

/* 完事後再瞅一眼,全備的 to_lsn 已經 --> 增量2 的了 */
[root@node1 innobackup]# cat 2014-07-31_09-27-36/xtrabackup_checkpoints 
backup_type = full-prepared
from_lsn = 0
to_lsn = 1664255
last_lsn = 1664255
compact = 0
[root@node1 innobackup]# cat 2014-07-31_11-59-29/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 1661993
to_lsn = 1664255
last_lsn = 1664255
compact = 0

至此,恢復的預準備工作已完成,兩個增備也完成了歷史使命,恢復只要用全備的一個就可以了:

/* 恢復過程灰常簡單,恢復過程也不需要啓動mysql, 但是備份過程是一定要啓動mysql的,因爲要以備份用戶身份連到Mysql上的嘛 */
[root@node1 innobackup]# innobackupex --copy-back /innobackup/2014-07-31_09-27-36/
/* 現在還不能啓動mysql, 對了,屬主屬組還沒改 */
[root@node1 innobackup]# ll /mydata/data/
total 18456
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 db1
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 hellodb
-rw-r--r--. 1 root root 18874368 Jul 31 15:54 ibdata1
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 mydb
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 mysql
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 performance_schema
drwxr-xr-x. 2 root root     4096 Jul 31 15:54 test
[root@node1 innobackup]# chown -R mysql.mysql /mydata/data/*

/* 現在就可以啓動了 。。 */
[root@node1 innobackup]# service mysqld start
Starting MySQL.....                                        [  OK  ]

/* 正常啓動,數據都在 */
MariaDB [db1]> SELECT * FROM tb1;
+----+----------------+--------+
| id | Name           | Gender |
+----+----------------+--------+
|  2 | Jerry          | F      |
|  3 | Bob            | M      |
|  4 | Dongfang Bubai | F      |
+----+----------------+--------+
3 rows in set (0.00 sec)

再加上最後的二進制日誌恢復,整個恢復過程就全搞顛了

[root@node1 innobackup]# cat /innobackup/2014-07-31_11-59-29/xtrabackup_binlog_info 
mysql-bin.000001	1922		
[root@node1 innobackup]# mysqlbinlog --start-position=1922 mysql-bin.000001 > 11.sql
[root@node1 innobackup]# mysql < 11.sql 

MariaDB [(none)]> SELECT * FROM db1.tb1;
+----+-------------------+--------+
| id | Name              | Gender |
+----+-------------------+--------+
|  2 | Jerry             | F      |
|  3 | Bob               | M      |
|  4 | Dongfang Bubai    | F      |
|  5 | Kangshifu Guamian | O      |
+----+-------------------+--------+
4 rows in set (0.01 sec)
/* 二進制日誌恢復,kangshifu guamian finnaly O 出鍋了 */


To be continued ...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章