Xtrabackup 備份大資料庫(全量備份和增量備份)
Xtrabackup
Xtrabackup是由percona開源的免費資料庫熱備份軟體,它能對InnoDB資料庫和XtraDB儲存引擎的資料庫非阻塞地備份(對於MyISAM的備份同樣需要加表鎖);mysqldump備份方式是採用的邏輯備份,其最大的缺陷是備份和恢複速度較慢,如果資料庫大於50G,mysqldump備份就不太適合。
Xtrabackup優點
 1)備份速度快,物理備份可靠
 2)備份過程不會打斷正在執行的事務(無需鎖表)
 3)能夠基於壓縮等功能節約磁碟空間和流量
 4)自動備份校正
 5)還原速度快
 6)可以流傳將備份傳輸到另外一台機器上
Xtrabackup原理
 Xtrabackup安裝完成後有4個可執行檔,其中2個比較重要的備份工具是innobackupex、xtrabackup
1)xtrabackup 是專門用來備份InnoDB表的,不能備份非Innodb表,和mysql server沒有互動;
2)innobackupex 是一個指令碼,用來備份非InnoDB表,同時會調用xtrabackup命令來備份InnoDB表,還會和mysql  server互動,比如鎖表、擷取位置點等。簡單地說,就是在xtrabackup基礎上做了一層封裝;
3)xbcrypt 加密解密備份工具
4)xbstream 流傳打包傳輸工具,類似tar
1)在使用InnoDB引擎表內部會維護一個redo記錄檔,我們也可以叫做交易記錄檔。交易記錄會儲存每一個InnoDB表資料的記錄修改
2)xtrabackup在啟動時會記住log sequence number(LSN)記錄序號,即當前的redo記錄的位置,並且複製所有資料檔案
3)複製過程需要一些時間,所以這期間如果資料檔案LSN有改動,它會運行一個後台進程,用於監控交易記錄,並不停地將交易記錄中每個資料檔案的修改都記下來
Xtrabackup安裝
官網下載Xtrabackup
1 ##https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.3.5/binary/RedHat/6/x86_64/percona-xtrabackup-2.3.5-1.el6.x86_64.rpm
搜尋下載幾個依賴rpm包
##http://rpmfind.net/linux/RPM/ 
perl-DBI-1.609-4.el6.x86_64.rpm 
perl-DBD-MySQL-4.013-3.el6.x86_64.rpm 
libev-4.04-2.el6.x86_64.rpm
安裝完成後檢查rpm包安裝情況
[root@db02 tools]# rpm -ivh percona-xtrabackup-2.3.5-1.el6.x86_64.rpm 
warning: percona-xtrabackup-2.3.5-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY 
Preparing...                ########################################### [100%] 
  1:percona-xtrabackup    ########################################### [100%] 
[root@db02 tools]# rpm -qa|grep xtrabackup 
percona-xtrabackup-2.3.5-1.el6.x86_64 
[root@db02 tools]# rpm -ql percona-xtrabackup-2.3.5-1.el6.x86_64 
/usr/bin/innobackupex #innobackupex指令碼工具 
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup #最主要的備份工具 
/usr/share/doc/percona-xtrabackup-2.3.5 
/usr/share/doc/percona-xtrabackup-2.3.5/COPYING
/usr/share/man/man1/innobackupex.1.gz 
/usr/share/man/man1/xbcrypt.1.gz 
/usr/share/man/man1/xbstream.1.gz 
/usr/share/man/man1/xtrabackup.1.gz
先對資料庫做一個全量備份
[root@db02 data]# innobackupex --defaults-file=/data/3306/my.cnf --user=root --password=li123456 /backup/full/ 
... 
60710 08:24:47 [00] Writing backup-my.cnf 
160710 08:24:47 [00]        ...done
160710 08:24:47 [00] Writing xtrabackup_info 
160710 08:24:47 [00]        ...done
xtrabackup: Transaction log of lsn (1672995) to (1672995) was copied. 
160710 08:24:47 completed OK!
此時可以看到/backup/full已經有了備份過來的資料檔案
[root@db02 full]# cd /backup/full/2016-07-10_08-24-43/ 
[root@db02 2016-07-10_08-24-43]# ll 
總用量 131108 
-rw-r----- 1 root root      387 7月  10 08:24 backup-my.cnf 
-rw-r----- 1 root root 134217728 7月  10 08:24 ibdata1 
drwx------ 2 root root      4096 7月  10 08:24 lichengbing 
drwx------ 2 root root      4096 7月  10 08:24 lilongzi 
drwx------ 2 root root      4096 7月  10 08:24 mysql 
drwx------ 2 root root      4096 7月  10 08:24 performance_schema 
-rw-r----- 1 root root        21 7月  10 08:24 xtrabackup_binlog_info 
-rw-r----- 1 root root      113 7月  10 08:24 xtrabackup_checkpoints #記錄LSN號檔案 
-rw-r----- 1 root root      503 7月  10 08:24 xtrabackup_info 
-rw-r----- 1 root root      2560 7月  10 08:24 xtrabackup_logfile 
[root@db02 2016-07-10_08-24-43]# cat xtrabackup_checkpoints  
backup_type = full-backuped #備份類型為全備 
from_lsn = 0 #起始LSN號(由於是全備所以起始LSN號為0開始) 
to_lsn = 1672995 #截止LSN號 
last_lsn = 1672995 
compact = 0 
recover_binlog_info = 0
現在全備已經完成了,我們來類比破壞資料,然後恢複資料。
首先停掉資料庫
[root@db02 3306]# mysqladmin -uroot -pli123456 -S /data/3306/mysql.sock shutdown 
[root@db02 3306]# mv /data/3306/data/ /data/3306/data_bak/ 
[root@db02 3306]# mkdir -p /data/3306/data/ #必須建立一個新的空data檔案夾用來恢複,不然恢複會報錯 
Original data directory /data/3306/data is not empty!
此時我們在開啟資料庫,探索資料庫檔案被破壞無法啟動了
[root@db02 3306]# mysqld_safe --defaults-file=/data/3306/my.cnf & 
160710 10:05:14 mysqld_safe Logging to '/data/3306/mysql_oldboy3306.err'. 
160710 10:05:14 mysqld_safe Starting mysqld daemon with databases from /data/3306/data
160710 10:05:15 mysqld_safe mysqld from pid file /data/3306/mysqld.pid ended 
# pid進程檔案無法啟動 
[1]+  Done                    mysqld_safe --defaults-file=/data/3306/my.cnf 
[root@db02 3306]# tail mysql_oldboy3306.err  
160710 10:05:15 InnoDB: 5.5.32 started; log sequence number 1595668 
160710 10:05:15 [Note] Recovering after a crash using /data/3306/mysql-bin
160710 10:05:15 [Note] Starting crash recovery... 
160710 10:05:15 [Note] Crash recovery finished. 
160710 10:05:15 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306 
160710 10:05:15 [Note]  - '0.0.0.0' resolves to '0.0.0.0'; 
160710 10:05:15 [Note] Server socket created on IP: '0.0.0.0'. 
160710 10:05:15 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist #提示相關資料庫表未找到 
160710 10:05:15 mysqld_safe mysqld from pid file /data/3306/mysqld.pid ended
準備全量恢複
[root@db02 3306]# innobackupex --defaults-file=/data/3306/my.cnf --user=root --password=li123456 --apply-log /backup/full/2016-07-10_08-24-43/ 
... 
InnoDB: Waiting for purge to start 
InnoDB: 5.6.24 started; log sequence number 1673228 
xtrabackup: starting shutdown with innodb_fast_shutdown = 1 
InnoDB: FTS optimize thread exiting. 
InnoDB: Starting shutdown... 
InnoDB: Shutdown completed; log sequence number 1673238 
160710 08:42:01 completed OK!
#這裡的apply-log參數意思就是在正真恢複資料庫資料之前,先將資料庫redo日誌狀態恢複
接下來才是將資料檔案恢複
[root@db02 3306]# innobackupex --defaults-file=/data/3306/my.cnf --copy-back /backup/full/2016-07-10_08-24-43/ 
... 
160710 08:43:41 [01]        ...done
160710 08:43:41 [01] Copying ./mysql/user.frm to /data/3306/data/mysql/user.frm 
160710 08:43:41 [01]        ...done
160710 08:43:41 [01] Copying ./mysql/tables_priv.MYI to /data/3306/data/mysql/tables_priv.MYI 
160710 08:43:41 [01]        ...done
160710 08:43:41 [01] Copying ./mysql/proxies_priv.MYI to /data/3306/data/mysql/proxies_priv.MYI 
160710 08:43:41 [01]        ...done
160710 08:43:41 completed OK!
再更改資料檔案屬組,啟動資料庫成功
[root@db02 3306]# chown -R mysql.mysql data 
[root@db02 data]# mysqld_safe --defaults-file=/data/3306/my.cnf & 
[1] 90409 
[root@db02 data]# mysql -uroot -pli123456 -S /data/3306/mysql.sock 
mysql> show databases; 
+--------------------+ 
| Database          | 
+--------------------+ 
| information_schema | 
| lichengbing        | #資料表恢複成功 
| lilongzi          | 
| mysql              | 
| performance_schema | 
+--------------------+ 
5 rows in set (0.00 sec)
再來類比一下增量備份
新插入幾行資料
[root@db02 opt]# mysql -uroot -pli123456 -S /data/3306/mysql.sock lichengbing < /opt/test2.sql 
mysql> select * from lichengbing.test; 
+----+-------+ 
| id | name  | 
+----+-------+ 
|  1 | one  | 
|  2 | two  | 
|  3 | three | 
|  4 | four  | #此時4、5、6相當於資料庫增量檔案 
|  5 | five  | 
|  6 | six  | 
+----+-------+ 
6 rows in set (0.00 sec)
增量備份
[root@db02 opt]# innobackupex --defaults-file=/data/3306/my.cnf --user=root --password=li123456 --incremental /backup/add/ --incremental-basedir=/backup/full/2016-07-10_08-24-43/ 
... 
160710 08:55:15 [00] Writing xtrabackup_info 
160710 08:55:15 [00]        ...done
xtrabackup: Transaction log of lsn (1673693) to (1673693) was copied. 
160710 08:55:15 completed OK! 
[root@db02 add]# cd /backup/add/2016-07-10_08-55-12/ 
[root@db02 2016-07-10_08-55-12]# cat xtrabackup_checkpoints  
backup_type = incremental 
from_lsn = 1672995 #增量備份的起始LSN號是靠讀取全備xtrabackup_checkpoints檔案得到的 
to_lsn = 1673693 #增量結束LSN號 
last_lsn = 1673693 
compact = 0 
recover_binlog_info = 0
增量恢複
增量恢複和全量恢複有著一些不同,需要注意的是:
1)需要在每個備份(包括完全備份和增量備份)上,將已經提交的事務進行“重放”,重放之後,所有的備份資料將合并到完全備份上;
2)基於所有備份將未提交的事務進行“復原”
關閉資料庫
[root@db02 ~]# mysqladmin -uroot -pli123456 -S /data/3306/mysql.sock shutdown
執行完全備份的前滾
[root@db02 ~]# innobackupex --defaults-file=/data/3306/my.cnf --user=root --pli123456 --apply-log --redo-only /backup/full/2016-07-10_08-24-43/
##--redo-only 在做增量恢複時,全量和增量備份的資料檔案在恢複前必須將在重做記錄檔中的已提交的事務前滾!此參數將會合并全備和增量備份的資料檔案,但不包括最後一次增量備份的資料檔案
將全備和增備合并
[root@db02 ~]# innobackupex --defaults-files=/data/3306/my.cnf --user=root --pli123456 --apply-log /backup/full/2016-07-10_08-24-43/ --incremental-dir=/backup/add/2016-07-10_08-55-12/ 
##/backup/full/2016-07-10_08-24-43/ 全備目錄 
##--incremental-dir=/backup/add/2016-07-10_08-55-12/ 增量目錄 
##--redo-only 只有一次增備,所以不需要加這個參數,如果有N次增備,依次恢複增備,除了最後一個每次都要加 --redo-only的參數
破壞資料庫,將全備和增備恢複回來
[root@db02 3306]# rm -fr data_bak 
[root@db02 3306]# mv data data_bak 
[root@db02 3306]# innobackupex --defaults-file=/data/3306/my.cnf --copy-back /backup/full/2016-07-10_08-24-43/ 
... 
160710 09:54:54 [01]        ...done
160710 09:54:54 [01] Copying ./mysql/user.frm to /data/3306/data/mysql/user.frm 
160710 09:54:54 [01]        ...done
160710 09:54:54 [01] Copying ./mysql/tables_priv.MYI to /data/3306/data/mysql/tables_priv.MYI 
160710 09:54:54 [01]        ...done
160710 09:54:55 [01] Copying ./mysql/proxies_priv.MYI to /data/3306/data/mysql/proxies_priv.MYI 
160710 09:54:55 [01]        ...done
160710 09:54:55 completed OK! 
[root@db02 3306]# chown -R mysql.mysql data
恢複成功,登陸查看
1234567891011121314 [root@db02 data]# mysqld_safe --defaults-file=/data/3306/my.cnf & 
[root@db02 data]# mysql -uroot -pli123456 -S /data/3306/mysql.sock 
mysql> select * from lichengbing.test; 
+----+-------+ 
| id | name  | 
+----+-------+ 
|  1 | one  | 
|  2 | two  | 
|  3 | three | 
|  4 | four  | 
|  5 | five  | 
|  6 | six  | 
+----+-------+ 
6 rows in set (0.00 sec)
其他一些備份樣本
指定Database Backup
[root@db02 each]# innobackupex --defaults-file=/data/3306/my.cnf  --user=root --password=li123456 --databases="lichengbing" /backup/each/
指定表備份
[root@db02 each]# innobackupex --defaults-file=/data/3306/my.cnf  --user=root --password=li123456 --databases="lichengbing test" /backup/each/
以壓縮格式備份
[root@db02 full]# innobackupex --defaults-file=/data/3306/my.cnf  --user=root --password=li123456 --stream=tar /backup/full/|gzip>/backup/full/back_`date +%F`.tar.gz
MySQL管理之使用XtraBackup進行熱備 
MySQL開源備份工具Xtrabackup備份部署 
MySQL Xtrabackup備份和恢複 
用XtraBackup實現MySQL的主從複製快速部署【主不鎖表】 
安裝和使用 Percona 推出的 Xtrabackup 備份 MySQL 
XtraBackup 的詳細介紹:請點這裡
XtraBackup 的:請點這裡
本文永久更新連結地址: