zoukankan      html  css  js  c++  java
  • delete、update忘加where条件误操作恢复过程演示

    update、delete没有带where条件,误操作,如何恢复呢?

    我现在有一张学生表,我要把小于60更新成不及格。

     1 mysql> select * from student; 
     2 
     3 +----+------+-------+-------+ 
     4 
     5 | id | name | class | score | 
     6 
     7 +----+------+-------+-------+ 
     8 
     9 |  1 | a    |     1 | 56    |  
    10 
    11 |  2 | b    |     1 | 61    |  
    12 
    13 |  3 | c    |     2 | 78    |  
    14 
    15 |  4 | d    |     2 | 45    |  
    16 
    17 |  5 | e    |     3 | 76    |  
    18 
    19 |  6 | f    |     3 | 89    |  
    20 
    21 |  7 | g    |     4 | 43    |  
    22 
    23 |  8 | h    |     4 | 90    |  
    24 
    25 +----+------+-------+-------+ 
    26 
    27 8 rows in set (0.02 sec) 

    结果,忘带where条件了,

     1 mysql> update student set score='failure'; 
     2 
     3 Query OK, 8 rows affected (0.11 sec) 
     4 
     5 Rows matched: 8  Changed: 8  Warnings: 0 
     6 
     7  
     8 
     9 mysql> select * from student; 
    10 
    11 +----+------+-------+---------+ 
    12 
    13 | id | name | class | score   | 
    14 
    15 +----+------+-------+---------+ 
    16 
    17 |  1 | a    |     1 | failure |  
    18 
    19 |  2 | b    |     1 | failure |  
    20 
    21 |  3 | c    |     2 | failure |  
    22 
    23 |  4 | d    |     2 | failure |  
    24 
    25 |  5 | e    |     3 | failure |  
    26 
    27 |  6 | f    |     3 | failure |  
    28 
    29 |  7 | g    |     4 | failure |  
    30 
    31 |  8 | h    |     4 | failure |  
    32 
    33 +----+------+-------+---------+ 
    34 
    35 8 rows in set (0.01 sec) 

    把整张表的记录都给更新成不及格了。

    传统的方法是:利用最近的全量备份+增量binlog备份,恢复到误操作之前的状态,那么随着表的记录增大,binlog的增多,恢复起来很费时费力。

    现在通过一个简单的方法,可以恢复到误操作之前的状态。

    我的binlog日志设置为binlog_format = ROW,

    首先,创建一个普通权限的账号(切记不能是SUPER权限),例如:

    1 GRANT ALL PRIVILEGES ON yourDB.* TO 'admin_read_only'@'%' IDENTIFIED BY '123456'; 
    2 
    3 flush privileges; 

    把read_only打开,设置数据库只读,

    1 mysql> set global read_only = 1; 
    2 
    3 Query OK, 0 rows affected (0.01 sec) 

    把刚才创建的admin_read_only账号给运维,让运维把前端程序(PHP/JSP/.NET等)的用户名改下,然后重启前端程序(PHP/JSP/.NET等),这样再连接进来的用户对数据库的访问只能读不能写,保证恢复的一致性。

    通过binlog先找到那条语句

     1 [root@M1 data]# /usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS 
     2 
     3 mysql-bin.000001 | grep -B 15 'failure'| more 
     4 
     5 /*!*/; 
     6 
     7 # at 192 
     8 
     9 #121124 23:55:15 server id 25  end_log_pos 249 CRC32 0x83a12fbc         Table_map: `test`.`student` mapped to number 76 
    10 
    11 # at 249 
    12 
    13 #121124 23:55:15 server id 25  end_log_pos 549 CRC32 0xcf7d2635         Update_rows: table id 76 flags: STMT_END_F 
    14 
    15 ### UPDATE test.student 
    16 
    17 ### WHERE 
    18 
    19 ###   @11=1 /* INT meta=0 nullable=0 is_null=0 */ 
    20 
    21 ###   @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    22 
    23 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
    24 
    25 ###   @4='56' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    26 
    27 ### SET 
    28 
    29 ###   @11=1 /* INT meta=0 nullable=0 is_null=0 */ 
    30 
    31 ###   @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    32 
    33 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
    34 
    35 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    36 
    37 ### UPDATE test.student 
    38 
    39 ### WHERE 
    40 
    41 ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */ 
    42 
    43 ###   @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    44 
    45 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
    46 
    47 ###   @4='61' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    48 
    49 ### SET 
    50 
    51 ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */ 
    52 
    53 ###   @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    54 
    55 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
    56 
    57 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    58 
    59 --More-- 

    然后把那条binlog给导出来

      1 [root@M1 data]# /usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS 
      2 
      3 mysql-bin.000001 | sed -n '/# at 249/,/COMMIT/p' > /opt/1.txt   
      4 
      5 [root@M1 data]#  
      6 
      7 [root@M1 data]# more /opt/1.txt  
      8 
      9 # at 249 
     10 
     11 #121124 23:55:15 server id 25  end_log_pos 549 CRC32 0xcf7d2635         Update_rows: table id 76 flags: STMT_END_F 
     12 
     13 ### UPDATE test.student 
     14 
     15 ### WHERE 
     16 
     17 ###   @11=1 /* INT meta=0 nullable=0 is_null=0 */ 
     18 
     19 ###   @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     20 
     21 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
     22 
     23 ###   @4='56' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     24 
     25 ### SET 
     26 
     27 ###   @11=1 /* INT meta=0 nullable=0 is_null=0 */ 
     28 
     29 ###   @2='a' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     30 
     31 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
     32 
     33 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     34 
     35 ### UPDATE test.student 
     36 
     37 ### WHERE 
     38 
     39 ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */ 
     40 
     41 ###   @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     42 
     43 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
     44 
     45 ###   @4='61' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     46 
     47 ### SET 
     48 
     49 ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */ 
     50 
     51 ###   @2='b' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     52 
     53 ###   @3=1 /* INT meta=0 nullable=1 is_null=0 */ 
     54 
     55 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     56 
     57 ### UPDATE test.student 
     58 
     59 ### WHERE 
     60 
     61 ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */ 
     62 
     63 ###   @2='c' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     64 
     65 ###   @3=2 /* INT meta=0 nullable=1 is_null=0 */ 
     66 
     67 ###   @4='78' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     68 
     69 ### SET 
     70 
     71 ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */ 
     72 
     73 ###   @2='c' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     74 
     75 ###   @3=2 /* INT meta=0 nullable=1 is_null=0 */ 
     76 
     77 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     78 
     79 ### UPDATE test.student 
     80 
     81 ### WHERE 
     82 
     83 ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */ 
     84 
     85 ###   @2='d' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     86 
     87 ###   @3=2 /* INT meta=0 nullable=1 is_null=0 */ 
     88 
     89 ###   @4='45' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
     90 
     91 ### SET 
     92 
     93 ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */ 
     94 
     95 ###   @2='d' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
     96 
     97 ###   @3=2 /* INT meta=0 nullable=1 is_null=0 */ 
     98 
     99 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    100 
    101 ### UPDATE test.student 
    102 
    103 ### WHERE 
    104 
    105 ###   @1=5 /* INT meta=0 nullable=0 is_null=0 */ 
    106 
    107 ###   @2='e' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    108 
    109 ###   @33=3 /* INT meta=0 nullable=1 is_null=0 */ 
    110 
    111 ###   @4='76' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    112 
    113 ### SET 
    114 
    115 ###   @1=5 /* INT meta=0 nullable=0 is_null=0 */ 
    116 
    117 ###   @2='e' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    118 
    119 ###   @33=3 /* INT meta=0 nullable=1 is_null=0 */ 
    120 
    121 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    122 
    123 ### UPDATE test.student 
    124 
    125 ### WHERE 
    126 
    127 ###   @1=6 /* INT meta=0 nullable=0 is_null=0 */ 
    128 
    129 ###   @2='f' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    130 
    131 ###   @33=3 /* INT meta=0 nullable=1 is_null=0 */ 
    132 
    133 ###   @4='89' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    134 
    135 ### SET 
    136 
    137 ###   @1=6 /* INT meta=0 nullable=0 is_null=0 */ 
    138 
    139 ###   @2='f' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    140 
    141 ###   @33=3 /* INT meta=0 nullable=1 is_null=0 */ 
    142 
    143 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    144 
    145 ### UPDATE test.student 
    146 
    147 ### WHERE 
    148 
    149 ###   @1=7 /* INT meta=0 nullable=0 is_null=0 */ 
    150 
    151 ###   @2='g' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    152 
    153 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    154 
    155 ###   @4='43' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    156 
    157 ### SET 
    158 
    159 ###   @1=7 /* INT meta=0 nullable=0 is_null=0 */ 
    160 
    161 ###   @2='g' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    162 
    163 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    164 
    165 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    166 
    167 ### UPDATE test.student 
    168 
    169 ### WHERE 
    170 
    171 ###   @1=8 /* INT meta=0 nullable=0 is_null=0 */ 
    172 
    173 ###   @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    174 
    175 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    176 
    177 ###   @4='90' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    178 
    179 ### SET 
    180 
    181 ###   @1=8 /* INT meta=0 nullable=0 is_null=0 */ 
    182 
    183 ###   @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    184 
    185 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    186 
    187 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 
    188 
    189 # at 549 
    190 
    191 #121124 23:55:15 server id 25  end_log_pos 580 CRC32 0x378c91b0         Xid = 531 
    192 
    193 COMMIT/*!*/; 
    194 
    195 [root@M1 data]# 

    其中,这些是误操作之前的数据

    1 ###   @1=8 /* INT meta=0 nullable=0 is_null=0 */ 
    2 
    3 ###   @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    4 
    5 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    6 
    7 ###   @4='90' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 

    这些是误操作之后的数据

    1 ###   @1=8 /* INT meta=0 nullable=0 is_null=0 */ 
    2 
    3 ###   @2='h' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ 
    4 
    5 ###   @3=4 /* INT meta=0 nullable=1 is_null=0 */ 
    6 
    7 ###   @4='failure' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ 

    这里,@1/@2/@3/@4对应的表字段是id,name,class,score

    现在,就要进行最后一步的恢复操作了,只需把这些binlog转成成SQL语句,然后将其导入进去。

      1 [root@M1 opt]# sed '/WHERE/{:a;N;/SET/!ba;s/([^
    ]*)
    (.*)
    (.*)/3
    2
    1/}' 1.txt
      2 
      3 | sed -r '/WHERE/{:a;N;/@4/!ba;s/###   @2.*//g}' 
      4 
      5 | sed 's/### //g;s//*.*/,/g' 
      6 
      7 | sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g' 
      8 
      9 | sed '/^$/d' > ./recover.sql 
     10 
     11 [root@M1 opt]#  
     12 
     13 [root@M1 opt]# cat recover.sql  
     14 
     15 UPDATE test.student 
     16 
     17 SET 
     18 
     19   @11=1 , 
     20 
     21   @2='a' , 
     22 
     23   @3=1 , 
     24 
     25   @4='56' , 
     26 
     27 WHERE 
     28 
     29   @11=1 ; 
     30 
     31 UPDATE test.student 
     32 
     33 SET 
     34 
     35   @1=2 , 
     36 
     37   @2='b' , 
     38 
     39   @3=1 , 
     40 
     41   @4='61' , 
     42 
     43 WHERE 
     44 
     45   @1=2 ; 
     46 
     47 UPDATE test.student 
     48 
     49 SET 
     50 
     51   @1=3 , 
     52 
     53   @2='c' , 
     54 
     55   @3=2 , 
     56 
     57   @4='78' , 
     58 
     59 WHERE 
     60 
     61   @1=3 ; 
     62 
     63 UPDATE test.student 
     64 
     65 SET 
     66 
     67   @1=4 , 
     68 
     69   @2='d' , 
     70 
     71   @3=2 , 
     72 
     73   @4='45' , 
     74 
     75 WHERE 
     76 
     77   @1=4 ; 
     78 
     79 UPDATE test.student 
     80 
     81 SET 
     82 
     83   @1=5 , 
     84 
     85   @2='e' , 
     86 
     87   @33=3 , 
     88 
     89   @4='76' , 
     90 
     91 WHERE 
     92 
     93   @1=5 ; 
     94 
     95 UPDATE test.student 
     96 
     97 SET 
     98 
     99   @1=6 , 
    100 
    101   @2='f' , 
    102 
    103   @33=3 , 
    104 
    105   @4='89' , 
    106 
    107 WHERE 
    108 
    109   @1=6 ; 
    110 
    111 UPDATE test.student 
    112 
    113 SET 
    114 
    115   @1=7 , 
    116 
    117   @2='g' , 
    118 
    119   @3=4 , 
    120 
    121   @4='43' , 
    122 
    123 WHERE 
    124 
    125   @1=7 ; 
    126 
    127 UPDATE test.student 
    128 
    129 SET 
    130 
    131   @1=8 , 
    132 
    133   @2='h' , 
    134 
    135   @3=4 , 
    136 
    137   @4='90' , 
    138 
    139 WHERE 
    140 
    141   @1=8 ; 
    142 
    143 [root@M1 opt]# 

    再把@1/@2/@3/@4对应的表字段是id,name,class,score,替换掉

     1 [root@M1 opt]# sed -i 's/@1/id/g;s/@2/name/g;s/@3/class/g;s/@4/score/g' recover.sql 
     2 
     3 [root@M1 opt]# sed -i -r 's/(score=.*),/1/g' recover.sql  
     4 [root@M1 opt]# 
     5 [root@M1 opt]# cat recover.sql 
     6 UPDATE test.student
     7 SET
     8   id=1 ,
     9   name='a' ,
    10   class=1 ,
    11   score='56' 
    12 WHERE
    13   id=1 ;
    14 UPDATE test.student
    15 SET
    16   id=2 ,
    17   name='b' ,
    18   class=1 ,
    19   score='61' 
    20 WHERE
    21   id=2 ;
    22 UPDATE test.student
    23 SET
    24   id=3 ,
    25   name='c' ,
    26   class=2 ,
    27   score='78' 
    28 WHERE
    29   id=3 ;
    30 UPDATE test.student
    31 SET
    32   id=4 ,
    33   name='d' ,
    34   class=2 ,
    35   score='45' 
    36 WHERE
    37   id=4 ;
    38 UPDATE test.student
    39 SET
    40   id=5 ,
    41   name='e' ,
    42   class=3 ,
    43   score='76' 
    44 WHERE
    45   id=5 ;
    46 UPDATE test.student
    47 SET
    48   id=6 ,
    49   name='f' ,
    50   class=3 ,
    51   score='89' 
    52 WHERE
    53   id=6 ;
    54 UPDATE test.student
    55 SET
    56   id=7 ,
    57   name='g' ,
    58   class=4 ,
    59   score='43' 
    60 WHERE
    61   id=7 ;
    62 UPDATE test.student
    63 SET
    64   id=8 ,
    65   name='h' ,
    66   class=4 ,
    67   score='90' 
    68 WHERE
    69   id=8 ;
    70 [root@M1 opt]# 

    OK。最激动人心的一幕到来了,我们进行恢复:

      1 mysql> select * from student; 
      2 
      3 +----+------+-------+---------+ 
      4 
      5 | id | name | class | score   | 
      6 
      7 +----+------+-------+---------+ 
      8 
      9 |  1 | a    |     1 | failure |  
     10 
     11 |  2 | b    |     1 | failure |  
     12 
     13 |  3 | c    |     2 | failure |  
     14 
     15 |  4 | d    |     2 | failure |  
     16 
     17 |  5 | e    |     3 | failure |  
     18 
     19 |  6 | f    |     3 | failure |  
     20 
     21 |  7 | g    |     4 | failure |  
     22 
     23 |  8 | h    |     4 | failure |  
     24 
     25 +----+------+-------+---------+ 
     26 
     27 8 rows in set (0.02 sec) 
     28 
     29  
     30 
     31 mysql> source /opt/recover.sql 
     32 
     33 Query OK, 1 row affected (0.11 sec) 
     34 
     35 Rows matched: 1  Changed: 1  Warnings: 0 
     36 
     37  
     38 
     39 Query OK, 1 row affected (0.95 sec) 
     40 
     41 Rows matched: 1  Changed: 1  Warnings: 0 
     42 
     43  
     44 
     45 Query OK, 1 row affected (0.16 sec) 
     46 
     47 Rows matched: 1  Changed: 1  Warnings: 0 
     48 
     49  
     50 
     51 Query OK, 1 row affected (0.03 sec) 
     52 
     53 Rows matched: 1  Changed: 1  Warnings: 0 
     54 
     55  
     56 
     57 Query OK, 1 row affected (0.80 sec) 
     58 
     59 Rows matched: 1  Changed: 1  Warnings: 0 
     60 
     61  
     62 
     63 Query OK, 1 row affected (0.08 sec) 
     64 
     65 Rows matched: 1  Changed: 1  Warnings: 0 
     66 
     67  
     68 
     69 Query OK, 1 row affected (0.09 sec) 
     70 
     71 Rows matched: 1  Changed: 1  Warnings: 0 
     72 
     73  
     74 
     75 Query OK, 1 row affected (0.07 sec) 
     76 
     77 Rows matched: 1  Changed: 1  Warnings: 0 
     78 
     79  
     80 
     81 mysql> select * from student;  
     82 
     83 +----+------+-------+-------+ 
     84 
     85 | id | name | class | score | 
     86 
     87 +----+------+-------+-------+ 
     88 
     89 |  1 | a    |     1 | 56    |  
     90 
     91 |  2 | b    |     1 | 61    |  
     92 
     93 |  3 | c    |     2 | 78    |  
     94 
     95 |  4 | d    |     2 | 45    |  
     96 
     97 |  5 | e    |     3 | 76    |  
     98 
     99 |  6 | f    |     3 | 89    |  
    100 
    101 |  7 | g    |     4 | 43    |  
    102 
    103 |  8 | h    |     4 | 90    |  
    104 
    105 +----+------+-------+-------+ 
    106 
    107 8 rows in set (0.02 sec) 
    1 mysql>  

    出处http://hcymysql.blog.51cto.com/5223301/1070148

  • 相关阅读:
    PAT 甲级 1126 Eulerian Path (25 分)
    PAT 甲级 1126 Eulerian Path (25 分)
    PAT 甲级 1125 Chain the Ropes (25 分)
    PAT 甲级 1125 Chain the Ropes (25 分)
    PAT 甲级 1124 Raffle for Weibo Followers (20 分)
    PAT 甲级 1124 Raffle for Weibo Followers (20 分)
    PAT 甲级 1131 Subway Map (30 分)
    PAT 甲级 1131 Subway Map (30 分)
    AcWing 906. 区间分组 区间贪心
    AcWing 907. 区间覆盖 区间贪心
  • 原文地址:https://www.cnblogs.com/exclusive-ada/p/4215178.html
Copyright © 2011-2022 走看看