mysql数据恢复思路

记一次mysql的重大失误处理

今天下午,客户端突然有人反应历史记录消失了,当时一脸懵逼,不知道咋回事
之后研发看了看,说那张表的数据没有了,只有13多的,之前的数据都清空了

顿时慌了,这是把运维往死里搞

开始解决问题

首先这是一个我们自建的数据库,开启了binlog,做了主从,但从库是刚刚做的,就是前天刚做的,之前都是没有的

不过备份了数据,数据量75G,是个全量备份,不知道怎么能只获取其中一张表的数据,而且消失了两天的数据。。。

追究问题:研发写的代码逻辑问题,使用的是delete语句对数据库操作,一般都会添加where条件,但没有逻辑判断强制where条件。(划重点)
建议:研发禁用delete语句,改为update语句

找到最新的binlog文件,然后对此进行分析
定位到了删除语句delete,确实有一条没有where条件。。。最后发现删了不止一张表,幸好只有3张表,数据量是1w,1w,8w。数据量不大

使用mysqlbinlog mysql-bin.000057 | grep -iw “delete” 再过滤表名,定位到删除语句,同时确定了原因就是以为没有加删除条件导致的后果。

解决思路:
定位到最后一条删除语句的position,在找到第一条的position,将binlog转化为sql语句,然后导入数据库,即将删除之前的语句进行恢复,然后导入到从库(从库先断开)
备份变成insert语句,最后在主库上执行insert插入(不确定对主键有没有影响)

将对应的库的名称,和所执行的定位导出为sql
mysqlbinlog mysql-bin.000057 --start-position=132161008 --stop-position=769321368 --database=xxxxxxxDb > rollback.sql

基本就是按这个操作来得,因为没有备份,不敢轻易在主库上执行sql,怕对线上数据有影响,尽量使损失最小。

一个坑就是start-position点怎么查找的。现将之前的备份导出到一个干净的库,将这个库的内容导出。然后找出当时binlog的position,最后再执行mysqlbinlog mysql-bin.000057 --start-position=132161008 --stop-position=769321368 --database=xxxxxxxDb > insert.sql 得到insert语句,再将语句在新库上执行,然后导出数据库,即获得当时删除前的所有数据,然后在导入到线上数据库

中途有咨询过dba和网友,给了一些建议,包括了美团开发的工具flashback,但最后还是选择了这种方式,那几种方法都测试失败了,为了稳妥,还是用了上面的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章