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

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

作者: miniy_7 | 来源:发表于2019-10-29 10:57 被阅读0次

    照成事故的原因可以说非常悲催了。因为线上数据库做迁移,由之前一台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中,才能使用。下面我们讲一下还原的步骤:

    • 第一步:在老库 Data目录中ibtmp1ibdata1ibtmp1ib_logfile1auto.cnf五个文件覆盖到线下模拟环境中,同时将mysql-log.0000025日志文件考入线下模拟环境data中。
    • 第二步:开启线下模拟环境的binlog日志(修改my.ini文件开启)。重启数据库服务,此时查看线下模拟环境的binlog开启情况。
    mysql> show variables like 'log_%'; // 没有开启log_bin的值是OFF,开启之后是ON
    
    mysql>show binary logs; // 查看binlog 文件列表
    

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

    image.png
    image.png
    • 第三步:在线下模拟环境的Data目录有个mysql-bin.index文件,这个是用富文本可以编辑的。按照他的格式,我们将mysql-log.0000025文件加入,重启数据库服务。
      image.png
      image.png

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

    image.png
    • 第四步:使用 show binlog events in 'mysql-bin.000025'; 命令就可以查看了。但是这种方式几乎得不到什么有用的信息。
      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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/bohwvctx.html