• 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

  • 相关阅读:
    通过进程ID获取基地址
    怎样获得某个进程的内存基地址?
    Delphi来实现一个IP地址输入控件
    如何在Windows服务程序中添加U盘插拔的消息
    delphi Format格式化函数
    CRC8算法DELPHI源码
    实现控件的透明背景
    定制控件背景颜色与背景位图
    实现系统滚动条换肤功能
    Delphi 获取命令行输出的函数
  • 原文地址:https://www.cnblogs.com/exclusive-ada/p/4215178.html
Copyright © 2020-2023  润新知