基於Innobackupex的不完全恢複,Innobackupex恢複
對於MySQL的不完全恢複,我們可以藉助於Innobackupex的多重備份加上binlog來將資料庫恢複到任意時刻。這裡的不完全恢複(也叫時間點復原)是相對於完全恢複。本文主要示範了基於Innobackupex如何做一個不完全恢複,供大家參考。
有關Innobackupex的備份恢複的知識點請參考以下連結:
Innobackupex 全備資料庫
使用mysqlbinlog提取二進位日誌
基於Innobackupex的全備恢複
基於Innobackupex的增備及恢複
基於Innobackupex的完全恢複
1、不完全恢複的概念
不完全恢複,即時間點復原,是指使用備份加上binlog日誌將資料庫恢複到任意指定的時間點。
不完全恢複依賴於完整的Database Backup與binlog備份,只要2者存在,任意資料丟失,誤操作,都可以恢複到任意指定的時間點。
不完全恢複的概念不限於熱備與邏輯備份(mysqldump)方式,都可以實現不完全恢複。
2、示範備份過程
a、建立示範環境robin@localhost[(none)]> show variables like 'version'; --當前MySQL版本+---------------+------------+| Variable_name | Value |+---------------+------------+| version | 5.6.12-log |+---------------+------------+robin@localhost[(none)]> reset master;Query OK, 0 rows affected (0.03 sec)robin@localhost[(none)]> use tempdb; robin@localhost[tempdb]> create table tb(id smallint,val varchar(20)); robin@localhost[tempdb]> insert into tb values(1,'fullbak'); --建立一個全備SHELL> innobackupex --user=robin -password=xxx --port=3606 --socket=/tmp/mysql3606.sock --defaults-file=/etc/my3606.cnf \ > /hotbak/full --no-timestamp b、建立一個增備--在建立增備前插入一條記錄到tbrobin@localhost[tempdb]> insert into tb values(2,'Incbak'); SHELL> innobackupex --user=robin -password=xxx --port=3606 --socket=/tmp/mysql3606.sock --defaults-file=/etc/my3606.cnf \ > --incremental /hotbak/inc --incremental-basedir=/hotbak/full --no-timestamp --再次新增一條記錄robin@localhost[tempdb]> insert into tb values(3,'pointrecover');Query OK, 1 row affected (0.01 sec)--記下當前的時間點用於後續的不完全恢複robin@localhost[tempdb]> system date;Thu Dec 25 11:53:54 CST 2014--類比誤操作robin@localhost[tempdb]> truncate table tb;Query OK, 0 rows affected (0.01 sec)c、再次全備SHELL> innobackupex --user=robin -password=xxx --port=3606 --socket=/tmp/mysql3606.sock --defaults-file=/etc/my3606.cnf \> /hotbak/full2 --no-timestamp--全備後新增一張表robin@localhost[tempdb]> create table tb_after_truncate(id int,val varchar(20));Query OK, 0 rows affected (0.02 sec)
3、示範恢複過程
--下面理清一下思路:--當前備份情況: 全備+增備+全備--我們在增備之後truncate了表tb,然後又建立了一個全備,建立了一個表tb_after_truncate。--此時我們需要將資料庫恢複到truncate(誤操作)之前--解決方案:我們需要利用第一次的全備+增備+binglog來恢複到truncate前,當前第二次全備用不上。a、先做基於全備的apply,注意,此時使用了--redo-only SHELL> innobackupex --apply-log --redo-only --user=robin -password=xxx --port=3606 \ > --defaults-file=/etc/my3606.cnf /hotbak/full b、基於增備的apply, --此時沒有--redo-only,如果有多個增備,僅僅最後一個增備無需指定--redo-only SHELL> innobackupex --apply-log --user=robin -password=xxx --port=3606 --defaults-file=/etc/my3606.cnf \ > /hotbak/full --incremental-dir=/hotbak/inc c、進行copy back SHELL> mysqldown -P3606 --copy back前關閉執行個體 SHELL> netstat -nltp|grep mysql|grep 3606 SHELL> mv /data/inst3606/data3606 /data/inst3606/data3606bk SHELL> mkdir -p /data/inst3606/data3606 SHELL> innobackupex --user=robin -password=xxx --port=3606 --copy-back /hotbak/full --defaults-file=/etc/my3606.cnf SHELL> chown -R mysql:mysql /data/inst3606/data3606 d、啟動恢複後的執行個體 SHELL> mysqld_safe --defaults-file=/etc/my3606.cnf &SHELL> mysql -uroot -pxxx -P3606 -S /tmp/mysql3606.sock \> -e "select * from tempdb.tb"Warning: Using a password on the command line interface can be insecure.+------+---------+| id | val |+------+---------+| 1 | fullbak || 2 | Incbak |+------+---------+--擷取增量之後的log positionSHELL> cd /hotbak/inc/SHELL> more xtrabackup_binlog_infoinst3606bin.000001 774--這裡使用了stop-datetime去將日誌追加到truncate之前SHELL> mysqlbinlog /data/inst3606/log/bin/inst3606bin.000001 --start-position=774 --stop-datetime="2014-12-25 11:53:54" \> |mysql -urobin -pxxx -P3606 -S /tmp/mysql3606.sock--驗證結果如下,可以看到已經恢複到truncate之前了SHELL> mysql -uroot -pxxx -P3606 -S /tmp/mysql3606.sock \> -e "select * from tempdb.tb"Warning: Using a password on the command line interface can be insecure.+------+--------------+| id | val |+------+--------------+| 1 | fullbak || 2 | Incbak || 3 | pointrecover |+------+--------------+--如果我們需要繼續恢複後面的事務,我們可以找出truncate前後位置,然後跳過這個positionSHELL> mysqlbinlog /data/inst3606/log/bin/inst3606bin.000001 --start-datetime="2014-12-25 11:53:54"|grep truncate -A5truncate table tb/*!*/;# at 1180#141225 11:55:35 server id 3606 end_log_pos 1260 CRC32 0x12f55fc5 Query thread_id=928 exec_time=0 error_code=0SET TIMESTAMP=1419479735/*!*/;/*!\C latin1 *//*!*/;--create table tb_after_truncate(id int,val varchar(20))/*!*/;# at 1392#141225 13:06:47 server id 3606 end_log_pos 1415 CRC32 0xf956f311 StopDELIMITER ;# End of log file--我們找出的position為1260,跳過1260之前的繼續追加binlogSHELL> mysqlbinlog /data/inst3606/log/bin/inst3606bin.000001 --start-position=1260 \> |mysql -urobin -pxxx -P3606 -S /tmp/mysql3606.sock--驗證追加後的結果,可以看到表tb_after_truncate存在[mysql@app ~]$ mysql -uroot -pxxx -P3606 -S /tmp/mysql3606.sock \> -e "desc tempdb.tb_after_truncate"Warning: Using a password on the command line interface can be insecure.+-------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+-------------+------+-----+---------+-------+| id | int(11) | YES | | NULL | || val | varchar(20) | YES | | NULL | |+-------+-------------+------+-----+---------+-------+
4、小結
a、不完全恢複(時間點復原)與完全恢複操作方式上基本等同
b、不完全恢複我們需要確定需要恢複到的時間點或binlog position
c、一旦確定了需要恢複的時間點,選擇自上一次全備以來所有備份來進行恢複
d、恢複完成後再使用binlog日誌追加到確定的時間點
e、追加binlog日誌可以基於position,也可以基於datetime
f、也可以跳過故障點,繼續追加後面的binlog日誌至最新,如本文尾部的示範