首页 > 代码库 > 基于Innobackupex的完全恢复

基于Innobackupex的完全恢复

    对于MySQL的完全恢复,我们可以借助于Innobackupex的多重备份加上binlog来将数据库恢复到故障点。这里的完全恢复是相对于时点恢复(也叫不完全恢复)。本文主要演示了基于Innobackupex如何做一个完全恢复,供大家参考。

    有关Innobackupex的备份恢复的知识点请参考以下链接:
        Innobackupex 全备数据库
        使用mysqlbinlog提取二进制日志
        基于Innobackupex的全备恢复
        基于Innobackupex的增备及恢复

1、完全恢复的概念

    完全恢复是指使用备份加上binlog日志将数据库恢复到最新的时间点。
    完全恢复的依赖条件为完整的数据库备份及binlog存在,只要2者完整存在,我们即可以将其完整的还原到最新状态。
    完全恢复的概念不限于热备与逻辑备份(mysqldump)方式,都可以实现完全恢复。

2、演示备份过程

a、创建演示环境
robin@localhost[(none)]> show variables like ‘version‘;  --当前MySQL版本
+---------------+------------+
| Variable_name | Value      |
+---------------+------------+
| version       | 5.6.12-log |
+---------------+------------+

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、创建一个增备
--在创建增备前插入一条记录到tb
robin@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 
3、演示恢复过程
--再次新增一条记录,该记录在保存在binlog,而不会存在于任何备份,这条记录用于验证完全恢复
robin@localhost[tempdb]> insert into tb values(3,‘Inbinlog‘);
Query OK, 1 row affected (0.01 sec)

--当前的binlog位置
robin@localhost[(none)]> show master status;
+--------------------+----------+--------------+------------------+-------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------------+----------+--------------+------------------+-------------------+
| inst3606bin.000014 |     1200 |              |                  |                   |
+--------------------+----------+--------------+------------------+-------------------+

--使用binlog events命令来查看我们最后insert的一条记录
robin@localhost[(none)]> show binlog events in ‘inst3606bin.000014‘ limit 7,10;
+--------------------+------+------------+-----------+-------------+---------------------------------------------------+
| Log_name           | Pos  | Event_type | Server_id | End_log_pos | Info                                              |
+--------------------+------+------------+-----------+-------------+---------------------------------------------------+
| inst3606bin.000014 |  668 | Query      |      3606 |         751 | BEGIN                                             |
| inst3606bin.000014 |  751 | Query      |      3606 |         862 | use `tempdb`; insert into tb values(2,‘Incbak‘)   |
| inst3606bin.000014 |  862 | Xid        |      3606 |         893 | COMMIT /* xid=449096 */                           |
| inst3606bin.000014 |  893 | Query      |      3606 |         973 | FLUSH ENGINE LOGS                                 |
| inst3606bin.000014 |  973 | Query      |      3606 |        1056 | BEGIN                                             |
| inst3606bin.000014 | 1056 | Query      |      3606 |        1169 | use `tempdb`; insert into tb values(3,‘Inbinlog‘) |
| inst3606bin.000014 | 1169 | Xid        |      3606 |        1200 | COMMIT /* xid=449997 */                           |
+--------------------+------+------------+-----------+-------------+---------------------------------------------------+

--查看binlog的位置
robin@localhost[(none)]> show variables like ‘log_bin_basename‘;
+------------------+------------------------------------+
| Variable_name    | Value                              |
+------------------+------------------------------------+
| log_bin_basename | /data/inst3606/log/bin/inst3606bin |
+------------------+------------------------------------+

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> sql -P3606
robin@localhost[(none)]> use tempdb;

--如下,我们可以看到记录3, ‘Inbinlog‘记录并没有被恢复
robin@localhost[tempdb]> select * from tb;
+------+---------+
| id   | val     |
+------+---------+
|    1 | fullbak |    --Author: Leshami
|    2 | Incbak  |    --Blog  : http://blog.csdn.net/leshami
+------+---------+
2 rows in set (0.00 sec)

e、使用binlog做完全恢复
SHELL> cd /hotbak/inc/
SHELL> more xtrabackup_binlog_info    --从innobackupex获得binlog的位置
inst3606bin.000014      893

--使用mysqlbinlog 追加的最新
SHELL> mysqlbinlog /data/inst3606/log/bin/inst3606bin.000014 --start-position=893 > |mysql -urobin -pxxx -P3606 -S /tmp/mysql3606.sock

--验证,可以看到第3条记录以及被恢复
SHELL> mysql -urobin -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 | Inbinlog |
+------+----------+   
4、小结
a、对于完全恢复,我们需要使用备份加binlog两者结合的方式来实现
b、在恢复期间,首先使用带read-only的apply-log方式来prepare全备
c、接下来使用带read-only的apply-log方式来prepare增备,仅最后一个增备可以不用read-only
d、停止原有实例,并copy-back后启动恢复后的实例
e、从Innobakcupex备份信息中获取最后的binlog日志及位置信息

f、使用mysqlbinlog方式将日志追加到最新时刻         

技术分享          

基于Innobackupex的完全恢复