本文介绍了怎样用percona xtrabackup做全量备份及如何利用全量备份(不用增量备份)加binlog做完全恢复(将数据恢复到故障时刻)。
一 试验步骤
1.1 备份
#对数据库做备份
innobackupex --port=3307 --user=XtrabackupUser --password=123456 /download/bak/xtrbak/
备份完成后,会提示……completed OK!
备份完成后,会在备份路径下生成一个以备份时间命名的子目录,如:
[root@pc1 xtrbak]# pwd
/download/bak/xtrbak
[root@pc1 xtrbak]# ll
total 4
drwxr-x---. 5 root root 4096 Mar 17 15:44 2020-03-17_05-30-14
备份文件内容如下:
[root@pc1 xtrbak]# cd 2020-03-17_05-30-14
[root@pc1 2020-03-17_05-30-14]# ll
total 12340
-rw-r-----. 1 root root 426 Mar 17 05:30 backup-my.cnf
drwxr-x---. 2 root root 4096 Mar 17 05:30 dan_test
drwxr-x---. 2 root root 4096 Mar 17 05:30 dba
-rw-r-----. 1 root root 332 Mar 17 05:30 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 17 05:30 ibdata1
drwxr-x---. 2 root root 4096 Mar 17 05:30 mysql
drwxr-x---. 2 root root 4096 Mar 17 05:30 performance_schema
drwxr-x---. 2 root root 12288 Mar 17 05:30 sys
-rw-r-----. 1 root root 106 Mar 17 05:30 xtrabackup_binlog_info
-rw-r-----. 1 root root 113 Mar 17 05:30 xtrabackup_checkpoints
-rw-r-----. 1 root root 611 Mar 17 05:30 xtrabackup_info
-rw-r-----. 1 root root 2560 Mar 17 05:30 xtrabackup_logfile
1.2 故障模拟
删除数据文件:
cd /data/server/mysql_3307/
mv data data_bak
重启数据库失败:
Starting MySQL. ERROR! The server quit without updating PID file (/data/server/mysql_3307/data/pc1.pid)
1.3 恢复
1.3.1 prepare
在创建备份后,备份数据其实处于不可用状态。因为在redo log中可能存在未提交的事务和已经提交的事务,需要通过准备阶段来使数据达到一致性的状态。通过此阶段,备份数据就可以用来恢复了。
在准备阶段,需要指定选项--apply-log和备份路径。
innobackupex --apply-log /download/bak/xtrbak/2020-03-17_05-30-14
如果最后输出completed ok,则表明数据达到一致状态。
1.3.2 使用innobackupex做恢复
在prepare阶段后,如果需要用备份数据来恢复数据库,则需要指定--copy-back和备份数据所在的目录即可。
#如果数据库没被关闭,需要关闭数据库:
service mysqld stop
#如果数据目录不为空,则将数据目录设置为空
cd /data/server/mysql_3307/
mv data data_bak
#在恢复机器上恢复数据:
innobackupex --copy-back /download/bak/xtrbak/2020-03-17_05-30-14
chown -R mysql:mysql data
此时,数据恢复到了备份时刻的状态。
1.3.3 利用binlog做完全恢复
关闭相应的应用接口,阻止往数据库里写入数据,防止数据错乱。
service mysqld start
#查看应该从哪个binlog及position进行恢复
[root@pc1 2020-03-17_05-30-14]# cat xtrabackup_binlog_info
mysql-bin.000030 650 a4ac8cd2-e17c-11e9-a602-080027040516:1-86,
d4d2f1d2-66f2-11ea-972a-080027040516:1-17
#查看有哪些binlog需要恢复(上面阴影部分的binlog及其之后的binlog都需要恢复)
mysql> show binary logs;
……
| mysql-bin.000030 | 953 |
| mysql-bin.000031 | 537 |
| mysql-bin.000032 | 537 |
| mysql-bin.000033 | 234 |
| mysql-bin.000034 | 234 |
+------------------+-----------+
34 rows in set (0.00 sec)
#执行flush logs,以防止恢复最后一个binlog时,会重复复制,因为恢复binlog本身的操作也会记录到binlog里。
#恢复
/usr/local/mysql/bin/mysqlbinlog --skip-gtids=true --start-position=650 mysql-bin.000030 | mysql -u root -p
/usr/local/mysql/bin/mysqlbinlog --skip-gtids=true mysql-bin.000031 mysql-bin.000032 mysql-bin.000033 mysql-bin.000034 | mysql -u root -p
--注意,必须得加上skip-gtid=true,否则虽然语句执行没报错,但是实际上却未执行。
/*
如果我们是要恢复数据到源数据库或者和源数据库有相同 GTID 信息的实例,那么就要使用该参数。因为包含的 GTID 已经在源数据库执行过了,根据 GTID 特性,一个 GTID 信息在一个数据库只能执行一次,所以不会恢复成功。
如果是要恢复到其他实例的数据库并且不包含源实例的 GTID 信息,那么可以不使用该参数。
*/
--关于如何做增量备份,可以参考https://blog.csdn.net/yabingshi_tech/article/details/104953662