关闭

mysql delete错误使用where条件的操作恢复(模拟oracle闪回)

523人阅读 评论(0) 收藏 举报
分类:


先准备数据:

CREATE TABLE `qq1` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `class_id` int NOT NULL DEFAULT 0,
  `first_name` varchar(20) NOT NULL DEFAULT '',
  `last_name` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(product)root@localhost [test]> select * from qq1;
+----+----------+------------+-----------+
| id | class_id | first_name | last_name |
+----+----------+------------+-----------+
|  1 |      101 | lo         | 1gang     |
|  2 |      101 | zhou       | 2gang     |
|  3 |      102 | wone       | 3gang     |
|  4 |      101 | huo        | 4gang     |
|  5 |      102 | son        | 5gang     |
|  6 |      102 | dong       | 6gang     |
|  7 |      103 | qo         | 7gang     |
|  8 |      103 | dao        | 8gang     |
+----+----------+------------+-----------+
8 rows in set (0.00 sec)

现在要删除id大于5的记录,但不小心,将条件写成大于4。如下:
(product)root@localhost [test]> delete from qq1 where id>4;
Query OK, 4 rows affected (0.00 sec)

(product)root@localhost [test]> select * from qq1;
+----+----------+------------+-----------+
| id | class_id | first_name | last_name |
+----+----------+------------+-----------+
|  1 |      101 | lo         | 1gang     |
|  2 |      101 | zhou       | 2gang     |
|  3 |      102 | wone       | 3gang     |
|  4 |      101 | huo        | 4gang     |


通过binlog先找到那条语句:
-bash-4.1$ mysqlbinlog --no-defaults -v -v --base64-output=decode-rows mysql-bin.000143|grep -A 15 '### DELETE FROM `test`.`qq1`'|more
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=102 /* INT meta=0 nullable=0 is_null=0 */
###   @3='son' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='5gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=6 /* INT meta=0 nullable=0 is_null=0 */
###   @2=102 /* INT meta=0 nullable=0 is_null=0 */
###   @3='dong' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='6gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=7 /* INT meta=0 nullable=0 is_null=0 */
###   @2=103 /* INT meta=0 nullable=0 is_null=0 */
###   @3='qo' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='7gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=8 /* INT meta=0 nullable=0 is_null=0 */
###   @2=103 /* INT meta=0 nullable=0 is_null=0 */
###   @3='dao' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='8gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
# at 15124169
#160828  8:43:47 server id 65303306  end_log_pos 15124200 CRC32 0xf8c4dd77      Xid = 26350786
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

现在要分析binlog,把误操作的delete语句保存到文本中:

mysqlbinlog --no-defaults -v -v --base64-output=decode-rows mysql-bin.000143|sed -n '/DELETE FROM `test`.`qq1`/,/COMMIT/p' >/data/mysql/mysql3306/logs/2.sql
cat 2.sql
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2=102 /* INT meta=0 nullable=0 is_null=0 */
###   @3='son' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='5gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=6 /* INT meta=0 nullable=0 is_null=0 */
###   @2=102 /* INT meta=0 nullable=0 is_null=0 */
###   @3='dong' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='6gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=7 /* INT meta=0 nullable=0 is_null=0 */
###   @2=103 /* INT meta=0 nullable=0 is_null=0 */
###   @3='qo' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='7gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### DELETE FROM `test`.`qq1`
### WHERE
###   @1=8 /* INT meta=0 nullable=0 is_null=0 */
###   @2=103 /* INT meta=0 nullable=0 is_null=0 */
###   @3='dao' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @4='8gang' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
# at 15124169
#160828  8:43:47 server id 65303306  end_log_pos 15124200 CRC32 0xf8c4dd77      Xid = 26350786
COMMIT/*!*/;
接下来转换成标准的sql语句:
cat 2.sql|sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;' | sed -r 's/(@4.*),/\1;/g' | sed 's/@[1-9]=//g'>delete.sql

上面命令分段说明:
sed -n '/###/p'  ---打印###开头的行;
sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;'  ---先删除每行前的"### ",再将每行后面/*到*\部分删除,将DELETE FROM用INSERT INTO替换,将WHERE
用select 替换;
sed -r 's/(@4.*),/\1;/g'  ---将@4那行后面的,号用;分替换
sed 's/@[1-9]=//g' ---将每行类似@1=删除

-bash-4.1$ cat delete.sql
INSERT INTO `test`.`qq1`
SELECT
  5 ,
  102 ,
  'son' ,
  '5gang' ;
INSERT INTO `test`.`qq1`
SELECT
  6 ,
  102 ,
  'dong' ,
  '6gang' ;
INSERT INTO `test`.`qq1`
SELECT
  7 ,
  103 ,
  'qo' ,
  '7gang' ;
INSERT INTO `test`.`qq1`
SELECT
  8 ,
  103 ,
  'dao' ,
  '8gang' ;

(product)root@localhost [test]> select * from qq1;
+----+----------+------------+-----------+
| id | class_id | first_name | last_name |
+----+----------+------------+-----------+
|  1 |      101 | lo         | 1gang     |
|  2 |      101 | zhou       | 2gang     |
|  3 |      102 | wone       | 3gang     |
|  4 |      101 | huo        | 4gang     |

(product)root@localhost [test]> source delete.sql
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

(product)root@localhost [test]> select * from qq1;
+----+----------+------------+-----------+
| id | class_id | first_name | last_name |
+----+----------+------------+-----------+
|  1 |      101 | lo         | 1gang     |
|  2 |      101 | zhou       | 2gang     |
|  3 |      102 | wone       | 3gang     |
|  4 |      101 | huo        | 4gang     |
|  5 |      102 | son        | 5gang     |
|  6 |      102 | dong       | 6gang     |
|  7 |      103 | qo         | 7gang     |
|  8 |      103 | dao        | 8gang     |
+----+----------+------------+-----------+
8 rows in set (0.00 sec)

被删除的数据已回来了。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:169622次
    • 积分:3534
    • 等级:
    • 排名:第10324名
    • 原创:190篇
    • 转载:2篇
    • 译文:1篇
    • 评论:26条
    最新评论