昨天的事情,同事让我删除某条数据,我使用了上下键,没有注意那张表,直接把后面的条件删掉,加上分号,回车了。。。。啊。。。。
幸亏数据不是很多,有备份数据,但是那样回复太慢了。另辟蹊跷,这个也是跟别人学得。下面开始。。
先把binlog考到一个临时的目录,如果没有记录操作前的pos,只能手动找了,说个笨方法,根据执行的命令查看一下这条命令的位置
mysqlbinlog -vv --base64-output=DECODE-ROWS binlog-mysql-7.000007 | grep -n "DELETE FROM `test`.`tt`"
179298:### DELETE FROM `test`.`tt`
然后看好以下这个位置前面的若干行;
DELIMITER /*!*/;
# at 4
#140520 14:03:53 server id 1 end_log_pos 106 Start: binlog v 4, server v 5.1.73-log created 140520 14:03:53 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
SfB6Uw8BAAAAZgAAAGoAAAABAAQANS4xLjczLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABJ8HpTEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 1553209
# at 1553259
# at 1554274
# at 1555289
# at 1556304
# at 1557319
就是这个位置。pos=1559972
或者直接用前面的那个179298 ,直接
mysqlbinlog -vv binlog-mysql-7.000007 | sed -n '217175,$p'
这里还需要注意的是,这个文件结尾是不是自己需要的,因为数据库在你cp的时候很有可能还会写数据。。。
mysqlbinlog -vv --base64-output=DECODE-ROWS binlog-mysql-7.000007 | sed -n '179298,$p'| sed 's/^### //g;s/^#.*//g;s/COMMIT.*//g;s/DELIMITER.*//g;s/ROLLBACK.*//g;s#/.*[/;]$##g'
这个就是把那些和SQL语句不想管的全部都替换掉。
DELETE FROM `test`.`tt`
WHERE
@1=221
@2=222
@3='BZ001117'
@4=0
@5=NULL
@6=0
@7=0
@8=NULL
类似于这样的SQL了。接下来你该知道怎么做了吧。
接着上面那条命令继续
后面就是把这个SQL换成insert into。
mysqlbinlog -vv --base64-output=DECODE-ROWS binlog-mysql-7.000007 | sed -n '179298,$p'| sed 's/^### //g;s/^#.*//g;s/COMMIT.*//g;s/DELIMITER.*//g;s/ROLLBACK.*//g;s#/.*[/;]$##g;s/`//g;s/DELETE FROM/INSERT INTO /g;s/WHERE/VALUES /g;s/\(VALUES\)/\1(/g;s/\(@[1-7]=\)\(.*\)/\2,/g;s/\(@.=\)\(.*\)/\2);/g' >2.sql
结果是这样子,
INSERT INTO test.tt
VALUES(
221 ,
222 ,
'BZ001117' ,
0 ,
NULL ,
0 ,
0 ,
NULL );
好像可以了,那就试试
mysql> select count(*) from tt;
+----------+
| count(*) |
+----------+
| 221 |
+----------+
1 row in set (0.00 sec)
果然OK
解决问题了,最后说的是,任何操作头脑要清楚,不要盲目,看清楚在执行。
这个我感觉是最快的恢复误删除的方法。