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语句的文件。

把文件中的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
最终SQL
执行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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容