Mysql-Log-Restore

Mysql 基于日志的时间点恢复

前言:

数据库删除(delete)了某一张表的数据,但是日志存在,7天内的备份存在。
在恢复的过程中让正式环境正常运行,正式环境在恢复过程中会不断产生新的数据.

解决方法:

1. 使用flush logs在生产库生成新得log日志(方便我们复制旧得log日志)
2.将备份文件复制到本地
3.将主库的日志文件复制到本地
4.使用 mysqlbinlog 查找从备份文件时间开始至故障点的发生的数据
5.使用工具将mysqlbinlog抓出来的日志,去分析,筛选,修改
6.将修改好的日志文件导入到本地数据库中(即生产库的备份数据库)
7.停止生产库的服务,将生产环境新增的数据导出
8.将生产环境新增的数据复制到本地并导入本地数据库中
9.确认无误之后将生产环境数据导出,并导入到正式环境,并启动正式环境服务
10.当全部测试完成,建议重启Mysql数据库服务(以达到切换日志,或者手动flush logs)

操作方法如下:

前提条件Mysql数据库开启binlog功能,即my.cnf配置文件中有如下内容

 log-bin=mysql-bin  
 expire_logs_days=7(日志保留天数)

可以使用如下命令查看是否开启日志

show variables like '%log_bin%';

注意:log_bin是生成的bin-log的文件名,后缀则是6位数字的自增编码,从000001开始:

mysql_bin.000001 
mysql_bin.000002 
...... 

注:Mysql 重启后会自动新增一个日志,请找到备份点到故障点的所有日志文件

FlUSH LOGS切换日志

FLUSH LOGS;

注:在繁忙的数据库中,日志文件一直在做IO操作,从而导致不能直接将log日志复制出来,需要将日志切换才能将日志文件复制出来

附:日志的删除 REST MASTER 的严重性
REST MASTER;这条命令会删除所有日志文件,并将文件名和记录点进行重置归零,99%的情况下是用不到这条命令删除日志可以用PURGE MASTER LOGS…这样保险一点PURGE {MASTER | BINARY} LOGS TO ‘log_name’

查看操作日志
方法1:show binlog events
查看binlog日志的节点位置情况

show binlog events in 'mysql-bin.000001'  \G;

注:在日志量特别的大的时候不推荐使用(这在性能低下的服务器上是跑不动的)

方法2:mysqlbinlog 基于指定时间段的数据

mysqlbinlog --start-datetime="2020-11-12 00:00:00" --stop-datetime="2020-11-12 16:00:10"   mysql-bin.000001 >  mysqlRestore.sql

注:在日志量特别大的时候,推荐使用的方法。–start-datetime 和 –stop-datetime 可以分开使用。

方法3:mysqlbinlog 基于日志节点段的数据

mysqlbinlog --start-position=6200  --stop-position=6300 mysql-bin.000001 > mysqlRestore.sql

注:使用该方法你需要确定你的事件起始点和结束点,在你无法确定事件,查询出的数据非常大。–start-position 和–stop-position 可以分开使用

报错Error writing file 'xxx'( Errcode:28)

1.主要是mysql所在磁盘空间不足所致
2.查询表数据过大,生成临时表过大
清理磁盘,按时清理mysql生成的日志文件,查询表的话分段查询,优化sql语句

处理日志信息(方法多种多样,这边案例使用grep命令演示)
该处理过程具体问题具体分析,由于我这边是为了恢复一个叫做SKT11的表的数据,而数据库环境本身对于其他表的依赖较少,所以在恢复过程中,只获取SKT11的数据, -i 代表着不区分大小写

cat mysqlRestore.sql | grep  -i SKT11 > mysqlTest.sql

附:查看日志,所需了解的信息

at 4(事件开始点)#180903 16:19:12 (代表的是时间)
server id 1(主备复制时需要为每个MYSQL数据库指定唯一的SERVER ID,我的未配置,默认是1)
end_log_pos 123(事件结束点)
再看下边两个箭头:
at 123(事件开始点,和上边的事件结束点是对应的)
end_log_pos 154(事件结束点)at 4 和 at 123之间的内容就是事件内容

将数据导入到本地数据库
(方法多种多样,可以使用工具直接导入,也可以使用mysql客户端通道的形式)

cat mysqlTest.sql | mysql -uroot -p

将生产库新产生的数据导出,并导入到本地数据库(省略)
……

将本地数据库对应的表导入到生产库(省略)
……

Contents
  1. 1. Mysql 基于日志的时间点恢复
    1. 1.1. 前言:
    2. 1.2. 解决方法:
    3. 1.3. 操作方法如下:
|