delete、update忘加where条件误操作恢复过程演示
update、delete没有带where条件,误操作,如何恢复呢?
我现在有一张学生表,我要把小于60更新成不及格。
mysql> select * from student; +----+------+-------+-------+ | id | name | class | score | +----+------+-------+-------+ | 1 | a | 1 | 56 | | 2 | b | 1 | 61 | | 3 | c | 2 | 78 | | 4 | d | 2 | 45 | | 5 | e | 3 | 76 | | 6 | f | 3 | 89 | | 7 | g | 4 | 43 | | 8 | h | 4 | 90 | +----+------+-------+-------+ 8 rows in set (0.02 sec)
结果,忘带where条件了,
mysql> update student set score='failure'; Query OK, 8 rows affected (0.11 sec) Rows matched: 8 Changed: 8 Warnings: 0 mysql> select * from student; +----+------+-------+---------+ | id | name | class | score | +----+------+-------+---------+ | 1 | a | 1 | failure | | 2 | b | 1 | failure | | 3 | c | 2 | failure | | 4 | d | 2 | failure | | 5 | e | 3 | failure | | 6 | f | 3 | failure | | 7 | g | 4 | failure | | 8 | h | 4 | failure | +----+------+-------+---------+ 8 rows in set (0.01 sec)
把整张表的记录都给更新成不及格了。
传统的方法是:利用最近的全量备份+增量binlog备份,恢复到误操作之前的状态,那么随着表的记录增大,binlog的增多,恢复起来很费时费力。
现在通过一个简单的方法,可以恢复到误操作之前的状态。
我的binlog日志设置为binlog_format = ROW,
首先,创建一个普通权限的账号(切记不能是SUPER权限),例如:
GRANT ALL PRIVILEGES ON yourDB.* TO 'admin_read_only'@'%' IDENTIFIED BY '123456'; flush privileges;
把read_only打开,设置数据库只读,
mysql> set global read_only = 1; Query OK, 0 rows affected (0.01 sec)
把刚才创建的admin_read_only账号给运维,让运维把前端程序(PHP/JSP/.NET等)的用户名改下,然后重启前端程序(PHP/JSP/.NET等),这样再连接进来的用户对数据库的访问只能读不能写,保证恢复的一致性。
通过binlog先找到那条语句
[root@M1 data]# /usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS mysql-bin.000001 | grep -B 15 'failure'| more /*!*/; # at 192 #121124 23:55:15 server id 25 end_log_pos 249 CRC32 0x83a12fbc Table_map: `test`.`student` mapped to number 76 # at 249 #121124 23:55:15 server id 25 end_log_pos 549 CRC32 0xcf7d2635 Update_rows: table id 76 flags: STMT_END_F ### UPDATE test.student ### WHERE ### @11=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='56' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @11=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='61' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ --More--
然后把那条binlog给导出来
[root@M1 data]# /usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS mysql-bin.000001 | sed -n '/# at 249/,/COMMIT/p' > /opt/1.txt [root@M1 data]# [root@M1 data]# more /opt/1.txt # at 249 #121124 23:55:15 server id 25 end_log_pos 549 CRC32 0xcf7d2635 Update_rows: table id 76 flags: STMT_END_F ### UPDATE test.student ### WHERE ### @11=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='56' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @11=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='61' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=1 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=3 /* INT meta=0 nullable=0 is_null=0 */ ### @2='c' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=2 /* INT meta=0 nullable=1 is_null=0 */ ### @4='78' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=3 /* INT meta=0 nullable=0 is_null=0 */ ### @2='c' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=2 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=4 /* INT meta=0 nullable=0 is_null=0 */ ### @2='d' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=2 /* INT meta=0 nullable=1 is_null=0 */ ### @4='45' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=4 /* INT meta=0 nullable=0 is_null=0 */ ### @2='d' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=2 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=5 /* INT meta=0 nullable=0 is_null=0 */ ### @2='e' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @33=3 /* INT meta=0 nullable=1 is_null=0 */ ### @4='76' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=5 /* INT meta=0 nullable=0 is_null=0 */ ### @2='e' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @33=3 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=6 /* INT meta=0 nullable=0 is_null=0 */ ### @2='f' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @33=3 /* INT meta=0 nullable=1 is_null=0 */ ### @4='89' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=6 /* INT meta=0 nullable=0 is_null=0 */ ### @2='f' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @33=3 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=7 /* INT meta=0 nullable=0 is_null=0 */ ### @2='g' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='43' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=7 /* INT meta=0 nullable=0 is_null=0 */ ### @2='g' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE test.student ### WHERE ### @1=8 /* INT meta=0 nullable=0 is_null=0 */ ### @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='90' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=8 /* INT meta=0 nullable=0 is_null=0 */ ### @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ # at 549 #121124 23:55:15 server id 25 end_log_pos 580 CRC32 0x378c91b0 Xid = 531 COMMIT/*!*/; [root@M1 data]#
其中,这些是误操作之前的数据
### @1=8 /* INT meta=0 nullable=0 is_null=0 */ ### @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='90' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
这些是误操作之后的数据
### @1=8 /* INT meta=0 nullable=0 is_null=0 */ ### @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @3=4 /* INT meta=0 nullable=1 is_null=0 */ ### @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
这里,@1/@2/@3/@4对应的表字段是id,name,class,score
现在,就要进行最后一步的恢复操作了,只需把这些binlog转成成SQL语句,然后将其导入进去。
[root@M1 opt]# sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' 1.txt
| sed -r '/WHERE/{:a;N;/@4/!ba;s/### @2.*//g}'
| sed 's/### //g;s/\/\*.*/,/g'
| sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g'
| sed '/^$/d' > ./recover.sql
[root@M1 opt]#
[root@M1 opt]# cat recover.sql
UPDATE test.student
SET
@11=1 ,
@2='a' ,
@3=1 ,
@4='56' ,
WHERE
@11=1 ;
UPDATE test.student
SET
@1=2 ,
@2='b' ,
@3=1 ,
@4='61' ,
WHERE
@1=2 ;
UPDATE test.student
SET
@1=3 ,
@2='c' ,
@3=2 ,
@4='78' ,
WHERE
@1=3 ;
UPDATE test.student
SET
@1=4 ,
@2='d' ,
@3=2 ,
@4='45' ,
WHERE
@1=4 ;
UPDATE test.student
SET
@1=5 ,
@2='e' ,
@33=3 ,
@4='76' ,
WHERE
@1=5 ;
UPDATE test.student
SET
@1=6 ,
@2='f' ,
@33=3 ,
@4='89' ,
WHERE
@1=6 ;
UPDATE test.student
SET
@1=7 ,
@2='g' ,
@3=4 ,
@4='43' ,
WHERE
@1=7 ;
UPDATE test.student
SET
@1=8 ,
@2='h' ,
@3=4 ,
@4='90' ,
WHERE
@1=8 ;
[root@M1 opt]#
再把@1/@2/@3/@4对应的表字段是id,name,class,score,替换掉
[root@M1 opt]# sed -i 's/@1/id/g;s/@2/name/g;s/@3/class/g;s/@4/score/g' recover.sql [root@M1 opt]# sed -i -r 's/(score=.*),/\1/g' recover.sql
[root@M1 opt]#
[root@M1 opt]# cat recover.sql
UPDATE test.student
SET
id=1 ,
name='a' ,
class=1 ,
score='56'
WHERE
id=1 ;
UPDATE test.student
SET
id=2 ,
name='b' ,
class=1 ,
score='61'
WHERE
id=2 ;
UPDATE test.student
SET
id=3 ,
name='c' ,
class=2 ,
score='78'
WHERE
id=3 ;
UPDATE test.student
SET
id=4 ,
name='d' ,
class=2 ,
score='45'
WHERE
id=4 ;
UPDATE test.student
SET
id=5 ,
name='e' ,
class=3 ,
score='76'
WHERE
id=5 ;
UPDATE test.student
SET
id=6 ,
name='f' ,
class=3 ,
score='89'
WHERE
id=6 ;
UPDATE test.student
SET
id=7 ,
name='g' ,
class=4 ,
score='43'
WHERE
id=7 ;
UPDATE test.student
SET
id=8 ,
name='h' ,
class=4 ,
score='90'
WHERE
id=8 ;
[root@M1 opt]#
OK。最激动人心的一幕到来了,我们进行恢复:
mysql> select * from student; +----+------+-------+---------+ | id | name | class | score | +----+------+-------+---------+ | 1 | a | 1 | failure | | 2 | b | 1 | failure | | 3 | c | 2 | failure | | 4 | d | 2 | failure | | 5 | e | 3 | failure | | 6 | f | 3 | failure | | 7 | g | 4 | failure | | 8 | h | 4 | failure | +----+------+-------+---------+ 8 rows in set (0.02 sec) mysql> source /opt/recover.sql Query OK, 1 row affected (0.11 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.95 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.16 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.80 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.08 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.09 sec) Rows matched: 1 Changed: 1 Warnings: 0 Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from student; +----+------+-------+-------+ | id | name | class | score | +----+------+-------+-------+ | 1 | a | 1 | 56 | | 2 | b | 1 | 61 | | 3 | c | 2 | 78 | | 4 | d | 2 | 45 | | 5 | e | 3 | 76 | | 6 | f | 3 | 89 | | 7 | g | 4 | 43 | | 8 | h | 4 | 90 | +----+------+-------+-------+ 8 rows in set (0.02 sec)
mysql>
出处http://hcymysql.blog.51cto.com/5223301/1070148
delete、update忘加where条件误操作恢复过程演示的更多相关文章
- 记一次生产mysql数据误操作恢复过程
提示:建议每次对数据库进行修改时都做下备份 注意:以下Mysql开启的是row格式的binlog日志,确定到误操作具体时间可能有些麻烦,默认的格式就能很快找出来.这里开启row的原因是还有一种更快的方 ...
- MySQL 误操作后数据恢复(update,delete忘加where条件)
在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者D ...
- MySQL 误操作后数据恢复(update,delete忘加where条件)【转】
在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句 写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者 ...
- MySQL 误删数据、误更新数据(update,delete忘加where条件)
MySQL 误操作后数据恢复(update,delete忘加where条件) 关键词:mysql误删数据,mysql误更新数据 转自:https://www.cnblogs.com/gomysql/p ...
- 如何避免这个delete from tb_name不带条件的操作
那么,我们如何避免这个delete from tb_name不带条件的呢?其实是有办法的,但这只针对运维DBA或者DBA在操作时候有用,但对于PHP和JAVA程序,它的连接操作方式,就没办法避免了 s ...
- Oracle数据库常见的误操作恢复方法(上)
实验环境:Linux6.4 + Oracle 11g 面向读者:Oracle开发维护人员 概要: 1.误操作drop了emp表 2.误操作delete了emp表 3.误操作delete了emp表的部分 ...
- mongo 误操作恢复数据
场景:我往同一个集合里面插入 三条数据 aa:aa bb:bb cc:cc .后来我后悔了,不想插入 bb:bb,通过oplog重放过滤好 bb:bb这条数据. 原理: 1.通过 oplog.r ...
- mysql update 忘加 where 文件恢复
前提条件:mysql :data_row_format=rowmysql> show variables like '%image%';+------------------+-------+| ...
- 将Ctrl+Alt+Delete键进行屏蔽,防止误操作重启服务器
[root@bgw-t ~]# vi /etc/init/control-alt-delete.conf #exec /sbin/shutdown -r now "Control-Alt- ...
随机推荐
- String.format Tutorial
String format(String format, Object... args) The format specifiers for general, character, and numer ...
- ARM指令和Thumb指令区别
Thumb指令集 ]的问题而提出的,它具有16为的代码密度.Thumb不是一个完整的体系结构,不能指望处理程序只执行Thumb指令而不支持ARM指令集.因此,Thumb指令只需要支持通用功能,必要时, ...
- (转) int argc, char* argv[] 的用法
int main(int argc, char* argv[]) 這兩個參數的作用是什麼呢?argc 是指命令行輸入參數的個數,argv存儲了所有的命令行參數.假如你的程式是hello.exe,如果在 ...
- redis学习研究--基础知识
以下内容多为摘抄转载: 1. Redis 是什么 Redis是一个开源的使用ANSI C语言编写的基于内存的key/value存储系统,与memcache类似,但它支持的value类型更多,包括:字符 ...
- Js 导出Excel IE ActiveX控件
function ExportExcel() { var oXL = new ActiveXObject("Excel.Application"); //创建excel应用程序对象 ...
- 利用radio实现纯css选项卡切换
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtIAAABCCAIAAAD18aaXAAAG70lEQVR4nO3dO5KrPBCGYRY0VV4OEX
- 在 .NET Framework 2.0上使用LINQ
附件:System.Linq.dll.7z 此为从System.Core.dll中剥离的Linq,含有System.Linq.Enumerable类所有扩展方法,可以在客户只安装了.Net 2.0的环 ...
- Apache Commons Pool 故事一则
Apache Commons Pool 故事一则 最近工作中遇到一个由于对commons-pool的使用不当而引发的问题,习得正确的使用姿势后,写下这个简单的故事,帮助理解Apache Commons ...
- c++ ifstream ofstream 文件流
#include <fstream>ofstream //文件写操作 内存写入存储设备 ifstream //文件读操作,存储设备读区到内存中fstream //读写操作,对打开的文件可进 ...
- bzoj1654 [Usaco2006 Jan]The Cow Prom 奶牛舞会
Description The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in ...