XtraBackup備份恢復模擬實踐

XtraBackup是Percona公司開發的一款很好用的數據備份工具,支持對InnoDB引擎數據的熱備份,對MyISAM引擎的數據做備份時需要鎖表,詳細信息參見官網或其他資源。【XtracBackup官網】

1. 實驗環境

1.1 系統環境:

操作系統:CentOS 6.5 64位
主機地址:10.0.0.26
主機名:mysql01
mysql版本:mysql-5.6.36
XtraBackup版本:2.4.12 

2. 軟件安裝

2.1 安裝mysql服務

MySQL服務詳細安裝過程請參考上一篇文章【慢查詢可視化介紹】
這裏需要注意的是,必須要開啓log-bin功能,而且日誌文件最好不要和數據文件放在同一個目錄,以免對實驗造成影響。下面是mysql的基本配置,如果缺少其中某一項則可能會出現報錯。

[mysqld]
basedir=/opt/mysql-5.6.36/
datadir=/opt/mysql/data
log-bin=/opt/mysql/log/mysql-bin
slow_query_log_file = /opt/mysql/log/slow.log

[client]
socket=/opt/mysql/tmp/mysql.sock

2.2 安裝XtraBackup工具

1、安裝XtraBackup的依賴:

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL

2、下載安裝XtraBackup:

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.12-1.el6.x86_64.rpm --no-check-certificate
yum -y localinstall percona-xtrabackup-24-2.4.12-1.el6.x86_64.rpm

3、檢查是否安裝成功:

[root@mysql01 data]# xtrabackup -v
xtrabackup: recognized server arguments: --datadir=/opt/mysql/data --log_bin=/opt/mysql/log/mysql-bin 
xtrabackup version 2.4.12 based on MySQL server 5.7.19 Linux (x86_64) (revision id: 170eb8c)

3. 生產案例描述

3.1 備份策略

某公司使用mysql數據庫作爲生產環境,對數據庫的備份策略爲全量+增量,具體如下:
1、每週六00:00通過XtraBackup進行一次數據全量備份

0 0 * *  6   full.sh

2、週日-週五每天01:00通過XtraBackup進行數據增備

0 1 * * 0-5  inc.sh

3、開啓binlog日誌功能

3.2 故障描述

在星期二的下午2點,某開發人員不小心誤刪了一張表,大概10GB左右,需要對該表進行恢復操作。在刪表到開始恢復的這段時間內,可能還在繼續對其他表進行寫入操作。

3.3 恢復思路

1、斷開數據庫的連接,以防止二次破壞
2、準備上週六全備,並--apply-log  redo-only
3、合併增量,週日、週一、--apply-log --redoonly 週二--apply-log
4、在測試庫恢復以上數據,數據的目前狀態應該週二凌晨1:00
5、需要恢復的數據狀態是下午2點鐘左右,從1點開始的binlog恢復到刪除之前那個events的position。
6、導出刪除的表,恢復到生產庫,驗證數據可用性、完整性。
7、啓動應用連接數據庫。

4. 實踐過程

4.1 環境模擬

1、創建備份相關目錄:

    mkdir /backup/xbackup/full    #<==全備目錄
    mkdir /backup/xbackup/inc1   #<==增備目錄1
    mkdir /backup/xbackup/inc2   #<==增備目錄2
    mkdir /backup/xbackup/inc3   #<==增備目錄3

2、創建數據庫和表:
創建數據庫test,在test下創建表test和SC。其中test是需要刪除的表,而SC是一直有數據寫入的表

create database test character set utf8 collate utf8_general_ci;
use test;
create table test(id int,name char(20),age int);
drop table SC;
create table SC(
SCid int(12) NOT NULL auto_increment COMMENT '主鍵',
Cno int(10) NOT NULL COMMENT '課程號',
Sno int(10) NOT NULL COMMENT '學號',
Grade tinyint(2) NOT NULL COMMENT '學生成績',
PRIMARY KEY (SCid)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.2 模擬數據寫入過程

時間規劃爲2018-07-20(週五)----2018-07-24(週二)![]
1、模擬全備前數據寫入:

date -s 2018-07-20
insert into test values(1,'小紅',11);
insert into test values(2,'小黃',12);
INSERT INTO SC(Sno,Cno,Grade) values(0001,1001,1);

XtraBackup備份恢復模擬實踐
2、週六數據全備及之後數據寫入:

date -s 2018-07-21
innobackupex --user=root --password=123456 --no-timestamp /backup/xbackup/full/
date -s 08:00:00
insert into test values(3,'小藍',13);
INSERT INTO SC(Sno,Cno,Grade) values(0002,1002,2);
commit;

XtraBackup備份恢復模擬實踐
3、週日1點進行增備(20180722)和增量數據模擬:

date -s 2018-07-22
date -s 01:00:00
innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/xbackup/full/ /backup/xbackup/inc1
date -s 14:00:00
insert into test values(4,'小白',14);
INSERT INTO SC(Sno,Cno,Grade) values(0003,1003,3);
commit;

XtraBackup備份恢復模擬實踐
4、週一1點進行增備(20180723)和增量數據模擬:

date -s 2018-07-23
date -s 01:00:00
innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/xbackup/inc1/ /backup/xbackup/inc2
date -s 17:00:00
insert into test values(5,'小黑',15);
INSERT INTO SC(Sno,Cno,Grade) values(0004,1004,4);
commit;

XtraBackup備份恢復模擬實踐
5、週二1點進行增備(20180724)和增量數據模擬:

date -s 2018-07-24
date -s 01:00:00
innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/xbackup/inc2/ /backup/xbackup/inc3
date -s 04:00:00
insert into test values(6,'小黃',16);
INSERT INTO SC(Sno,Cno,Grade) values(0005,1005,5);
commit;

XtraBackup備份恢復模擬實踐

4.3 模擬刪除test表

在下午兩點的時候刪除表test,在此之後還繼續對其他表進行操作。

date -s 14:00:00
drop table test;
INSERT INTO SC(Sno,Cno,Grade) values(0006,1006,6);

XtraBackup備份恢復模擬實踐

5. 數據恢復

5.1 數據恢復準備

想要恢復數據,需要XtraBackup備份到星期二01:00點的數據,以及binlog在星期二01:00點之後到14:00這一段時間之類的數據。根據這兩部分的數據,即可恢復表刪除之前時間點的數據。
1、獲取XtraBackup到星期二01:00的完整數據:

innobackupex --apply-log --redo-only /backup/xbackup/full/
innobackupex --apply-log --redo-only --incremental-dir=/backup/xbackup/inc1 /backup/xbackup/full/
innobackupex --apply-log --redo-only --incremental-dir=/backup/xbackup/inc2 /backup/xbackup/full/
innobackupex --apply-log --incremental-dir=/backup/xbackup/inc3 /backup/xbackup/full/
innobackupex --apply-log /backup/xbackup/full/
詳細備份參數請參考官方文檔或其他資料。

2、確認binlog的起點:
在XtraBackup的備份文件xtrabackup_binlog_info中會記錄binlog的文件及起始位置。
XtraBackup備份恢復模擬實踐

3、確認DROP語句之前的binlog位置:

mysqlbinlog --start-position=3295 /opt/mysql/log/mysql-bin.000006 >> /tmp/tmp.sql
cat /tmp/tmp.sql 

XtraBackup備份恢復模擬實踐
4、恢復成sql文件:
通過上面兩步,可以發現binlog的起始位置,以及DROP之前一個的結束位置。通過這兩個position可以生成從01:00開始到14:00這一段時間內的數據庫增量文件。

mysqlbinlog --start-position=3295 --stop-position=3782 /opt/mysql/log/mysql-bin.000006 > /tmp/recover.sql

5.2 數據恢復方案一

通過另外一臺測試庫恢復。將XtraBackup和binlog的恢復文件發送到另外一臺測試數據庫(10.0.0.27,mysql02),通過這臺測試數據庫將數據恢復到14:00的狀態,再通過mysqldump備份出test表,最終傳輸到mysql01將數據恢復。
1、傳輸備份文件到mysql02:

scp -rp /backup/xbackup/full/ [email protected]:/tmp/
scp -rp /tmp/recover.sql [email protected]:/tmp/

2、測試庫恢復XtraBackup數據:
再數據恢復之前,需要將測試庫的data目錄清空

innobackupex --copy-back /tmp/full/
chown -R mysql.mysql /opt/mysql/data/
/etc/init.d/mysqld start

XtraBackup備份恢復模擬實踐
3、測試庫恢復binlog數據:

source /tmp/recover.sql

XtraBackup備份恢復模擬實踐
到此,已恢復到了刪表前一個時間點的數據,這時我們將test表導出並恢復到正式庫即可。

mysqldump -uroot -p123456 test test > /tmp/test_test.sql
mysql -uroot -p123456 < /tmp/test_test.sql
刪除表恢復到刪除時間點過程結束!

5.3 數據恢復方案二

從XtraBackup抽取表文件恢復。相對於方案一來說,不需要恢復全部數據庫,也不需要再其他庫上進行恢復,但是此種方式需要清楚建表的結構。
1、導出表:
導出表是在備份的prepare階段進行的,因此,一旦完全備份完成,就可以在prepare過程中通過--export選項將某表導出了。
導出前:
XtraBackup備份恢復模擬實踐
導出表命令:

innobackupex --apply-log --export /backup/xbackup/full/
此命令會爲每個innodb表的表空間創建一個以.exp結尾的文件,這些以.exp結尾的文件則可以用於導入至其它服務器。

導出後:可以看出多了表結構等兩個文件
XtraBackup備份恢復模擬實踐
2、創建相同結構的表並刪除此表的表空間:

create table test(id int,name char(20),age int);
alter table test.test discard tablespace;      #<==必須通過命令刪除,不能手動刪除文件

3、複製test.ibd和test.exp文件到數據目錄:

[root@mysql01 test]# pwd
/backup/xbackup/full/test
[root@mysql01 test]# cp test.ibd /opt/mysql/data/test/
[root@mysql01 test]# cp test.exp /opt/mysql/data/test/
[root@mysql01 test]# chown -R mysql.mysql /opt/mysql/data/test/*

4、使用命令導入表

alter table test import tablespace;

XtraBackup備份恢復模擬實踐
5、通過binlog恢復tests表01:00-14:00的增量數據
單表恢復只涉及到了test表,因此不需要其他表的數據,需要從recover.sql中過濾出test表

grep test /tmp/recover.sql > /tmp/test.sql
source /tmp/test.sql

XtraBackup備份恢復模擬實踐

5.4 兩種方案的比較

方案1

不需要知道原來的表結構,主庫也只需要source sql文件,但是需要恢復全部數據庫,並且需要在兩臺主機上傳輸數據,在數據量大的時候比較慢。

方案2

需要知曉表結構,相對來說更簡單快捷。

至此,XtraBackup備份及恢復實踐完畢!!!

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