误删mysql数据的一次辛酸史

生产数据库delete垃圾数据忘记添加where,导致整个表清空,瞬间血槽满了。。。。

解决方案如下

1.查看是否启用binlog,并找到日志存储路径

log_bin为ON表示开启了日志记录,否则该文章的解决方案不适用

mysql> show variables like'log_bin%';
#展示结果
+---------------------------------+--------------------------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------------------------+
| log_bin | ON |
| log_bin_basename | /home/programs/mysql-5.6.26/data/mysql-bin |
| log_bin_index | /home/programs/mysql-5.6.26/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
+---------------------------------+--------------------------------------------------

datadir为日志文件的存储路径

show variables like '%datadir%';
#展示结果
+---------------------------------+--------------------------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------------------------+
| datadir | /var/lib/mysql/ |
+---------------------------------+--------------------------------------------------+

 

2.抓取需要恢复的日志

进入日志存储路径,日志文件的命名格式一般为mysql-bin.*  *为版本。根据delete执行的时间查询日志

mysqlbinlog --no-defaults --base64-output=decode-rows -v --database=demo-data --start-datetime="2021-12-07 17:48:54" --stop-datetime="2021-12-07 17:48:55" mysql-bin.000023>mysqllogdata.sql
#--
database 指定数据名称

 

其它文章大部分没使用--no-defaults,若mysql指定的默认编码不匹配时,执行命令会出现

 

  如上命令会抓取日志到mysqllogdata.sql中,抓取的内容如下:

 

 这个地方我花费的时间比较多,因为按照时间段抓取难免会抓取到其它线程的执行语句;有查到可以通过日志位置抓取的命令,但抓取日志并没有抓全,命令如下:

mysqlbinlog --no-defaults --base64-output=decode-rows -v --database=demo-data --start-position="145894884" mysql-bin.000023

 

最终解决方案只能是先按照时间段抓取日志,然后再删除其中其它执行命令,如有其它更好的方式,欢迎评论区留言。

3.日志文件替换

抓取出的日志文件为DELETE命令,下一步需要将命令替换成INSERT命令,linux替换指令

cat mysqllogdata_n.sql | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/;INSERT INTO/g;s/WHERE/SELECT/g;' |sed -r 's/(@17.*),/\1;/g' | sed 's/@1=//g'| sed 's/@[1-9]=/,/g' | sed 's/@[1-9][0-9]=/,/g' > mysqllogOK_n.sql

 

替换完后的日志文件

 请注意,第一条INSERT命令前会多一个';',需要删除。

4.执行insert脚本

经过一两个小时的折腾后,终于来到了最关键的地方,执行insert脚本恢复数据,方法有很多,就不详细说了;我是直接将脚本内容粘贴到Navicat执行,linux可进入数据库后执行如下命令

source /var/lib/maysql/mysqllogOK_n.sql

 

检查无误后下班回家。

 

 本文参考文章https://www.cnblogs.com/-mrl/p/9959365.html

posted @ 2021-12-08 17:04  周仙僧  阅读(29)  评论(0编辑  收藏  举报