mysql-回复DELETE数据

背景

测试小伙伴不小心执行了DELETE * FROM 表名语句,删除了测试服十几万条数据。由于测试还需要这些数据,所以只能进行恢复

步骤

找到所执行的DELETE语句并重定向到文件中

1.找到mysql的日志文件binlog(二进制)
2.筛选出执行的DELETE语句,并重定向到文件中方便查看
当执行DELETE * FROM 表名语句时,实际上是对表内的数据一条条执行DELETE FROM XXX WHERE XXXXXX。而由于binlog文件很大(基本几百M起步),所以需要根据执行DELETE * FROM xxx语句的大致时间,进行筛选。语句:mysqlbinlog -vv --start-datetime= 2020-06-10 10:10:00 binlog文件名 > 重定向文件名1
3.再根据重定向文件1中的内容再次筛选,列如我想要DELETE FROM `xxxx`.`t_channel这一行以及下面13行的内容。所以我会再次进行筛选并重定向生成新的文件:cat 重定向文件名1 -C 13 `DELETE FROM `xxxx`.`t_channel` > 重定向文件名2,这样我会得到一个只包含DELETE FROM XXX WHERE XXXXXX语句的文件。

mysql-回复DELETE数据

把文件中的DELETE语句改成INSERT语句

cat 重定向文件2 | sed -n  /###/p  | sed  s/### //g;s//*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;  |sed -r  s/(@6.*),/1;/g  | sed  s/@[1-9]=//g  | sed  s/@[1-9][0-9]=//g  > 最终文件.sql

mysql-回复DELETE数据

执行sql语句,恢复成功

PS.

  • 如果第二步有后面日期的DELETE语句存在干扰,可以指定开始位置+终止位置来进行筛选,只看binlog的前几行和后几行
    起始位置:
    mysqlbinlog -vv --start-datetime= 2020-06-10 10:10:00 binlog文件名| head -1000 |more
    终止位置:mysqlbinlog -vv --start-datetime= 2020-06-10 10:10:00 --stop-datetime= 2020-06-10 11:20:00 binlog文件名| tail -1000 |more

  • 以上操作只针对delete误操作有效,且binlog模式是行模式;如果是drop或者truncate语句造成的误操作,亦或者binlog不是row模式,在binlog文件里是找不到完整的被删除数据,这个时候可以思考通过备份进行恢复;

  • 如果在误操作很久之后才意识到数据被误删除,记不清误操作的大致时间,那么可以找到误操作所在的binlog文件,将binlog解析为可阅读文本形式,然后借助文本编辑命令找误操作位置,再恢复;如果这种方式很慢的话,可以思考通过备份恢复,或者从别的环境中导出这张表的数据再导入到当前环境中;

  • Mysqlbinlog命令重大参数
    -vv 将二进制转换为可阅读文本
    –start-datetime 起始时间
    –stop-datetime 终止时间
    –start-position 起始位置
    –stop-position 终止位置
    –base64-output=decode-row 查看最底层DML语句数据模块,前提是数据库参数binlog_rows_query_log_events打开

  • 虽然binlog2sql工具也可以快速解析binlog,生成回滚SQL,但只要清楚上面的命令和操作流程,恢复速度也不会比binlog2sql慢许多,更何况如果环境没有安装这个工具。

参考:https://blog.csdn.net/weixin_33811961/article/details/89593855

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...