基于GTID方式对binlog进行恢复(利用GTID实现日志截取)
数据库数据异常恢复(痛点情况)
情况一:日志文件被清理过,可能建库语句所在日志已经丢失;(在后面课程章节处理)
项目背景:一个数据库三年前就创建了,但是日志信息只记录一个月,这个库被误删除了;
解决方案:
A计划:最近一次全备+全备之后,误删除之前所有binlog,进行一同恢复;(全备数据+增量数据
)
B计划:利用延时从库,进行数据恢复;
情况二:所需日志跨越多个文件,如何进行日志信息的截取;
解决方案:
A计划:只有position号的方式,可以进行分段截取,进行分段恢复数据;
B计划:根据Datatime时间信息方式,可能会出现准确性不高的情况(因为每一秒可能有多个事件产生);
C计划:启用GTID(全局事务ID)方式,无论跨越多少个日志文件,每个事务操作的事件ID信息都是唯一且递增的(5.6+引入);
实践操作:
C计划:基于GTID方式对binlog进行管理(利用GTID实现日志截取)
数据库异常恢复情况环境准备:
# 刷新新的binlog日志进行操作
mysql> flush logs;
-- 生成新的binlog日志信息
# 确认新的日志编号是否是连续的
mysql> create database test5;
mysql> show binlog events in "binlog.000004"
-- 可以看出新的binlog日志文件中,记录的gtid编号信息是延续了上一个binlog日志gtid集合信息,继续连续进行记录;
# 进行基本的数据库SQL语句操作:
mysql> create database gtdb;
mysql> use gtdb;
mysql> create table t1(id int);
mysql> insert into t1 values(1);
mysql> L
mysql> insert into t1 values(2);
mysql> commit;
mysql> insert into t1 values(3);
mysql> commit;
# 进行binlog事件信息查看
mysql> show binlog events in 'binlog.000004';
-- 可以获取以上的数据操作事件信息,
数据库模拟异常情况破坏操作:
mysql> drop database gtdb;
-- 模拟破坏性操作,删除数据库
数据库异常情况数据恢复操作:
# 根据日志信息查看相关的事件情况(获取GTID编号范围)
mysql> show binlog events in 'binlog.000004';
# 需要恢复建库开始,删除之前的所有操作(即所有binlog日志信息),实现日志信息的截取
[root@oldboyxiaoq ~]# mysqlbinlog --include-gtids='7afe4f8c-5e36-11ed-b083-000c29d44f34:3-7' /data/3306/data/binlog.000004 >/tmp/gtid.sql
-- 依据binlog日志的GTID信息,即可获取到想要恢复数据信息;
# 根据截取的日志信息,进行数据库服务数据恢复
mysql> set sql_log_bin=0;
-- 建议在进行数据日志恢复数据时,将数据恢复时执行的SQL语句信息,不做binlog日志记录;恢复后别忘在改为1;
mysql> source /tmp/gtid.sql
-- 默认此时报错恢复失败,因为GTID截取的日志恢复数据时,具有幂等性,由于binlog中已经记录了3-7的GTID事件信息
mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000004 | 1905 | | | 7afe4f8c-5e36-11ed-b083-000c29d44f34:1-8 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
-- 通过查看确认,核实清楚binlog中已经记录了3-7的GTID事件信息
# 利用GTID日志信息恢复报错处理方式一:将系统中日志中的GTID信息清除掉(不建议)
# 利用GTID日志信息恢复报错处理方式二:删除与幂等性冲突的记录信息
[root@oldboyxiaoq ~]# mysqlbinlog --skip-gtids --include-gtids='7afe4f8c-5e36-11ed-b083-000c29d44f34:3-7' /data/3306/data/binlog.000004 >/tmp/gtid.sql
-- 表示跳过gtid的检查过程,即截取的日志中不再含有GTID的配置语句信息,自然解决了幂等性冲突问题;
-- 开启了GTID之后,依然可以使用pos方式进行日志信息截取与恢复;
# 查看确认数据信息是否恢复
mysql> use gtdb;
mysql> show tables;
mysql> select * from t1;
-- 查看test1数据库中的t1表的数据信息是否恢复
# 操作扩展:可以实现排除指定gtid信息不做日志记录截取
[root@oldboyxiaoq ~]# mysqlbinlog --exclude-gtids='7afe4f8c-5e36-11ed-b083-000c29d44f34:4' --include-gtids='7afe4f8c-5e36-11ed-b083-000c29d44f34:3-7' /data/3306/data/binlog.000004
# 操作扩展:跨多日志文件信息截取
[root@oldboyxiaoq ~]# mysqlbinlog --skip-gtids --include-gtids='7afe4f8c-5e36-11ed-b083-000c29d44f34:1-10' /data/3306/data/binlog.000001 /data/3306/data/binlog.000002 /data/3306/data/binlog.000003 >/tmp/gtid.sql