【MySQL】记录一次线上数据丢失后通过binlog 日志找回的

2019-10-29  本文已影响0人  miniy_7

照成事故的原因可以说非常悲催了。因为线上数据库做迁移,由之前一台window服务器MySQL5.7.17版本迁移到另外一台Linux服务器MySQL8.0.17版本。因为了省事,在未做数据库备份的前提下直接使用了navicat 的表在线复制功能去做,结果出现异常了。新库中没有将表与数据复制过去,结果老库中表直接变成了一个自己不认识的样子。出现该情况吓得里面找备份库去还原。找到一个非常相近的备份库,是两个小时前的备份。只能先将这个还原到新库Mysql 8.0.17上,检查没有多大问题后,脑子瓦特的将老库window MySQL5.7.17 的库删除后又重新建了同名库后(删除库表示不能通过data还原)直接卸载了。是的直接卸载了,还没平稳度过一天发现线上出问题了,丢失了极少数的数据。数据找回之旅开始了!

备份!备份!备份! 数据库所有操作先备份,真的很重要!

上述中被卸载的 MySQL 5.7.17(小版本号也很重要),为了模拟生产上的环境,我们在线下电脑上安装了此版本。在原老库服务器上拷贝了老库的Data目录,忘记一点前提 原老数据库开启了binlog日志备份,在老库的Data目录中存在大量的日志备份文件。根据日志时间判断,最有用的是一个文件是mysql-log.0000025,我们需要的数据也存在其中。下一步我们想办法打开此文件。MySQL binlog 日志没有很好的可视化工具,尝试过使用文本编辑器打开,结果全是乱码,无法可视。只能通过MySQLbinlog工具进行查看,这种查看方式首先要将日志环境放入mysql中,才能使用。下面我们讲一下还原的步骤:

mysql> show variables like 'log_%'; // 没有开启log_bin的值是OFF,开启之后是ON

mysql>show binary logs; // 查看binlog 文件列表

查看文件列表有没有发现,我们的mysql-log.0000025文件没有在其中,不着急下一步。

image.png
image.png

再次执行show binary logs;命令,日志文件已经成果还原。

image.png

好了,至此我们已经成功还原了模拟环境,下一步进行数据操作

方式一:使用mysqlbinlog.exe 导出sql 文件找出可执行的sql

// 原始导出 sql 文件,但是内容都是base64 编码后的。
mysqlbinlog mysql-bin.000025  > a.sql
// 导出base64解码后的 sql 文件,但是出现问题 中文乱码。
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000025  > a.sql

使用导出base64解码后的 sql 文件,但是出现问题 中文乱码,但是基本可视。


image.png

由于乱码加上数据量巨大,直接找sql这种方式容易出错不可行。

方式二:使用mysqlbinlog.exe 直接还原到线下模拟环境

由于我们只是丢失了个别时间段的时间,所以我们使用指定时间的数据恢复方式进行处理。

mysqlbinlog --start-datetime="2018-04-27 20:58:18" --stop-datetime="2018-04-27 20:58:35" --database=dbName mysql-bin.000025 |mysql -uroot -p

--start-datetime--stop-datetime的时间如何找,我们通过方式1 中导出的sql 文件,找到每个BEGIN开始的时间,推算出我们需要的开始和结束时间。或者还可以使用指定位置来恢复,不过我们没有尝试。

image.png
通过此方法最终成功找回数据。

最后说明:数据无价,该备份要备份,该开binlog不要偷懒!

参考博客
https://www.ilanni.com/?p=7911

上一篇下一篇

猜你喜欢

热点阅读