实际工作中总会发生数据误删除的场景,在没有备份情况下,如何快速恢复误删数据就显得非常重要。

本文基于MySQL的binlog日志机制,当日志格式设置为“binlog_format=ROW”时,记录一步一步手动解析binlog、恢复误删数据的全过程,供大家参考使用。

一、确定删除时间段

查看数据库日志名字,查看操作事件,确认删除的具体时间,以定位删除的日志内容。

show master logs;

show binlog events in 'binlog.000067';

show binlog events in 'binlog.000067' FROM 1293303 LIMIT 0, 20;

通过类似如上的语句可确定具体的日志名字,具体的操作时间点或position

mysql> show binlog events in 'binlog.000002' FROM 2853160 LIMIT 0, 20;
+---------------+---------+----------------+-----------+-------------+--------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------+---------+----------------+-----------+-------------+--------------------------------------+
| binlog.000002 | 2853160 | Query | 1 | 2853246 | BEGIN |
| binlog.000002 | 2853246 | Table_map | 1 | 2853315 | table_id: 94 (liking.wp_options) |
| binlog.000002 | 2853315 | Update_rows | 1 | 2859755 | table_id: 94 flags: STMT_END_F |
| binlog.000002 | 2859755 | Query | 1 | 2859842 | COMMIT |
| binlog.000002 | 2859842 | Anonymous_Gtid | 1 | 2859921 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 2859921 | Query | 1 | 2860007 | BEGIN |
| binlog.000002 | 2860007 | Table_map | 1 | 2860076 | table_id: 94 (liking.wp_options) |
| binlog.000002 | 2860076 | Update_rows | 1 | 2866516 | table_id: 94 flags: STMT_END_F |
| binlog.000002 | 2866516 | Query | 1 | 2866603 | COMMIT |
| binlog.000002 | 2866603 | Anonymous_Gtid | 1 | 2866682 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 2866682 | Query | 1 | 2866759 | BEGIN |
| binlog.000002 | 2866759 | Table_map | 1 | 2866828 | table_id: 94 (liking.wp_options) |
| binlog.000002 | 2866828 | Delete_rows | 1 | 2866936 | table_id: 94 flags: STMT_END_F |
| binlog.000002 | 2866936 | Query | 1 | 2867014 | COMMIT |
| binlog.000002 | 2867014 | Anonymous_Gtid | 1 | 2867093 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 2867093 | Query | 1 | 2867179 | BEGIN |
| binlog.000002 | 2867179 | Table_map | 1 | 2867247 | table_id: 95 (liking.wp_postmeta) |
| binlog.000002 | 2867247 | Update_rows | 1 | 2867347 | table_id: 95 flags: STMT_END_F |
| binlog.000002 | 2867347 | Query | 1 | 2867434 | COMMIT |
| binlog.000002 | 2867434 | Anonymous_Gtid | 1 | 2867513 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
+---------------+---------+----------------+-----------+-------------+--------------------------------------+

二、取到指定时间段的所有sql语句

mysqlbinlog --no-defaults --base64-output=decode-rows -vv --start-datetime="2022-10-27 16:54:00" --stop-datetime="2022-10-27 18:27:00" binlog.000288 > liking.sql

三、取delete语句

sed -n '/### DELETE FROM 数据脱敏.数据脱敏数据脱敏/,/COMMIT/p' liking.sql > liking-1.sql

得到类似如下结果:

head -50 liking-1.sql
### DELETE FROM `数据脱敏`.`数据脱敏数据脱敏`
### WHERE
### @1=222248 /* INT meta=0 nullable=0 is_null=0 */
### @2='数据脱敏数据脱敏' /* VARSTRING(256) meta=256 nullable=1 is_null=0 */
[此处省略第3~45个记录行]
### @46='数据脱敏' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
### @47='订单' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
### @48='数据脱敏' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */

四、只保留以###开始的行数据

sed -n '/^###/'p liking-1.sql > liking-2.sql

五、去掉开头的###字符

sed 's/### //g' liking-2.sql > liking-3.sql

得到类似如下结果:

head -50 liking-3.sql
DELETE FROM `数据脱敏`.`数据脱敏数据脱敏`
WHERE
@1=222248 /* INT meta=0 nullable=0 is_null=0 */
@2='数据脱敏数据脱敏' /* VARSTRING(256) meta=256 nullable=1 is_null=0 */
[此处省略第3个~第45个字段]
@46='数据脱敏' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
@47='订单' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
@48='数据脱敏' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */

六、以#作分隔符将以/*开始的内容用,替换

sed 's#/*.*#,#g' liking-3.sql > liking-4.sql

得到如下结果:

head -50 liking-4.sql
DELETE FROM `数据脱敏`.`数据脱敏数据脱敏`
WHERE
@1=222248 ,
@2='数据脱敏数据脱敏' ,
[此处省略第3个~第45个字段]
@46='数据脱敏' ,
@47='订单' ,
@48='数据脱敏' ,

七、浏览结果做对应处理

鉴于还有一些insert、update语句,只取出前面的delete语句:

sed -n '1,493200p' liking-4.sql > liking-5.sql

八、全文替换关键字,将delete改成insert

将'DELETE FROM'改成'INSERT INTO'

将'WHERE'改成'SELECT'

sed 's#DELETE FROM#INSERT INTO#g' liking-5.sql > liking-6.sql

sed 's#WHERE#SELECT#g' liking-6.sql > liking-7.sql

得到如下结果:

head -50 liking-7.sql
INSERT INTO `数据脱敏`.`数据脱敏数据脱敏数据脱敏`
SELECT
@1=222248 ,
@2='数据脱敏数据脱敏' ,
[此处省略第3个~第45个字段]
@46='数据脱敏' ,
@47='订单' ,
@48='数据脱敏' ,

九、匹配'@48='开头以','结尾的行,把','替换成';'

sed -r 's#(@48=.)(,)#\1;#g' liking-7.sql > liking-8.sql

-r: 是指将正则表达式中的需要转义的字符设置成不需转义

括号用来匹配连续出现的内容

.
标识匹配除换行符\n外的任何单元符

为了把','去掉,单独(,)

\1是用来取()表示符的第一个,并在后面拼接上';'

本次恢复的记录都是48个字段,最后加分号,标识SQL结束,比较容易理解。

得到类似如下结果:

INSERT INTO `数据脱敏`.`数据脱敏数据脱敏数据脱敏`
SELECT
@1=222248 ,
@2='数据脱敏数据脱敏' ,
[此处省略第3个~第45个字段]
@46='数据脱敏' ,
@47='订单' ,
@48='数据脱敏' ;

十、把'@??='替换成'',也就是去掉类似'@11='字样部分

sed -r 's#(@.=)(.)#\2#g' liking-8.sql > liking-9.sql

得到类似如下结果:

head -50 liking-9.sql
INSERT INTO `数据脱敏`.`数据脱敏数据脱敏`
SELECT
222248 ,
'CMHE-202200393' ,
'数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏' ,
4.1772e+07 ,
'\'8000062202216124' ,
[此处省略第6个~第45个字段]
'数据脱敏' ,
'订单' ,
'马蕾' ;

十一、最后拼接 commit 语句

sed -i '$a commit;' liking-9.sql

查看最后几行确认:

tail -51 liking-9.sql
INSERT INTO `数据脱敏`.`数据脱敏数据脱敏`
SELECT
251837 ,
'CMHE-202101003' ,
'数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏' ,
5.04e+08 ,
'\'8000004202200006' ,
[此处省略第6个~第45个字段]
'数据脱敏' ,
'订单' ,
'陈鹏3' ;
commit;

十二、浏览、调整个别异常格式字段

此时需大概浏览得到的文本结果,尤其关注转义符,如有必要,需及时调整。

发现尚存在类似如下字段格式

''8000004202200006'

如需去掉'

则如下操作:

sed "s#\'##g" liking-9.sql > liking-10.sql

最后确认如下:

tail -51 liking-10.sql
INSERT INTO `数据脱敏`.`数据脱敏数据脱敏`
SELECT
251837 ,
'CMHE-202101003' ,
'数据脱敏数据脱敏数据脱敏数据脱敏数据脱敏' ,
5.04e+08 ,
'8000004202200006' ,
[此处省略第6个~第45个字段]
'数据脱敏' ,
'订单' ,
'陈鹏3' ;
commit;

十三、执行恢复数据

经过审视、调整后,此时得到的结果,已经可以正常执行INSERT操作恢复数据了!

写在最后,再次强调,备份是运维第一要务,备份的重要性再怎么强调也不为过,除非你可以承受数据丢失带来的后果。

数据千万行,备份最重要;数据不备份,丢失泪两行!

参考文档:

https://blog.csdn.net/qq_37701372/article/details/115188461

MySQL误删恢复方法2的更多相关文章

  1. 二.误删除MySQL用户,恢复方法

    误删除MySQL用户导致无法进入数据库 一.方法一 1.停止数据库 [root@db02 ~]# /etc/init.d/mysqld stop 2.跳过授权表,跳过网络启动数据库 [root@db0 ...

  2. oracle数据库误删恢复方法

    一.如果只是误删部分数据或者某条数据可以通过 1.select * from 误删除的表明 as of timestamp to_Date('恢复年月日  时分秒', '恢复时间格式')       ...

  3. windows系统下系统变量path误删恢复方法

    每台计算机安装程序不同,环境变量path会有不同,若误删了环境变量path,可以如下完美解决.   Win+R 输入regedit打开注册表(开始-运行里输入regedit) 找到  HKEY_LOC ...

  4. Mysql误删表中数据与误删表的恢复方法

    由于头两天面试时被问了这样一个问题,如果某同事误删了某个表,你该怎么恢复? 当时想了一下,因为博主没有遇到过这个问题,但是也多少了解一些,所以就回答通过mysql的binlog日志进行恢复. 面试官当 ...

  5. MySQL全备+binlog恢复方法之伪装master【原创】

    利用mysql全备 +binlog server恢复方法之伪装master 单实例试验 一.试验环境 10.72.7.40 实例 mysql3306为要恢复的对象,mysql3306的全备+binlo ...

  6. MySQL密码的恢复方法

    MySQL密码的恢复方法之一 1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态 ...

  7. mysql导出csv/sql/newTable/txt的方法,mysql的导入txt/sql方法...mysql备份恢复mysqlhotcopy、二进制日志binlog、直接备份文件、备份策略、灾难恢复.....................................................

    mysql备份表结构和数据 方法一. Create table new_table_nam备份到新表:MYSQL不支持: Select * Into new_table_name from old_t ...

  8. IIS误删了默认网站,恢复方法

    有时候安装好IIS后,会不小心把IIS的默认网站删除.重新去新建可能会出现一些错误例如"提示文件已存在无法执行"等奇怪的错误,下面是具体的默认网站的恢复方法 找到目录C:\wind ...

  9. MySQL 误删数据、误更新数据(update,delete忘加where条件)

    MySQL 误操作后数据恢复(update,delete忘加where条件) 关键词:mysql误删数据,mysql误更新数据 转自:https://www.cnblogs.com/gomysql/p ...

  10. 6种innodb数据字典恢复方法

    6种innodb数据字典恢复方法 https://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html frm文件重 ...

随机推荐

  1. 前端学习C语言 - 初级指针

    初级指针 本篇主要介绍:指针和变量的关系.指针类型.指针的运算符.空指针和野指针.指针和数组.指针和字符串.const 和指针.以及gdb 调试段错误. 基础概念 指针是一种特殊的变量.存放地址的变量 ...

  2. Mybatis-plus自定义Sql注入器

    最近在学习mybatis-plus,知道了在mp中通过AbstractSqlInjector将BaseMapper中的方法注入到了Mybatis容器,这样这些方法才可以正常执行. 下面是一个关系图 那 ...

  3. Taurus .Net Core 微服务开源框架:Admin 插件【4-2】 - 配置管理-Mvc【含请求日志打印】

    前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[4-1] - 配置管理-Kestrel[含https启用] 本篇继续介绍下一个内容: 1.系统配置节点:Mvc 配置 ...

  4. 曲线艺术编程 coding curves 第十四章 其它曲线(Miscellaneous Curves)

    第十四章 其它曲线(Miscellaneous Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ ...

  5. 解决Pyonth读取 yaml文件的中文字体,报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe5

    解决方法: 打开pycharm,点击files>setting  如下 改成UTF-8即可 改完后,之前的yaml文件里面的中文会出现乱码情况   删除后重写  即可

  6. 2023-07-13:如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。 花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串 定义下面几条语

    2023-07-13:如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串. 花括号展开的表达式可以看作一个由 花括号.逗号 和 小写英文字母 组成的字符串 定义下面几条语 ...

  7. sql相关小知识—

    数据库系统达到了数据独立性是因为采用了三级模式结构 人们为数据库设计了一个严谨的体系结构,数据库领域公认的标准结构是三级模式结构,它包括外模式.概念模式.内模式,有效地组织.管理数据,提高了数据库的逻 ...

  8. vue项目node_modules文件过大问题

    node_modules目录下.cache下最大文件删除即可(vue-loader)

  9. tensorflow.js 对视频 / 直播人脸检测和特征点收集

    前言: 这里要介绍的是 Tensorflow.js 官方提供的两个人脸检测模型,分别是 face-detection 和 face-landmarks-detection.他们不但可以对视频中的人间进 ...

  10. 手工搭建并配置apache,php,mysql环境服务器

    1,安装apache2.4: 从apache官网中下载windows版本的apache二进制文件,解压 打开apache目录中的bin目录,在其中打开cmd窗口,使用命令: httpd -k inst ...