国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

mysql中update誤操作 利用binlog日志 模擬oracle閃回性能

2024-07-24 12:34:35
字體:
來源:轉載
供稿:網友
  對于update誤操作,可以模擬oralce 的閃回功能,利用binlog日志,具體操作如下:
  mysql> select * from test1;
  +------+---------+--------+
  | dept | name    | salary |
  +------+---------+--------+
  | it   | gaopeng |    100 |
  | it   | yhb     |    100 |
  | it   | dzy     |    100 |
  | uu   | yl      |    100 |
  | uu   | yl1     |    200 |
  | uu   | yl3     |    300 |
  +------+---------+--------+
  6 rows in set (0.05 sec)
  mysql> update test1 set name='test';
  Query OK, 6 rows affected (0.06 sec)
  Rows matched: 6  Changed: 6  Warnings: 0
  mysql> select * from test1;
  +------+------+--------+
  | dept | name | salary |
  +------+------+--------+
  | it   | test |    100 |
  | it   | test |    100 |
  | it   | test |    100 |
  | uu   | test |    100 |
  | uu   | test |    200 |
  | uu   | test |    300 |
  +------+------+--------+
  6 rows in set (0.00 sec)
  mysql> exit
  [root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v -v db-bin.000016 |grep -B 15 'test'|more
  ps: grep -B 15 'test' 因為更改后的字段值為test,所以我們這里選test前15行和之后所有的數據.
 
  # at 384
  #150424 14:07:59 server id 199  end_log_pos 456 CRC32 0x7b4aabf1        Query   thread_id=2     exec_time=0     error_code=0
  SET TIMESTAMP=1429855679/*!*/;
  BEGIN
  /*!*/;
  # at 456
  #150424 14:07:59 server id 199  end_log_pos 510 CRC32 0x5f63d428        Table_map: `test`.`test1` mapped to number 74
  # at 510
  #150424 14:07:59 server id 199  end_log_pos 699 CRC32 0xf362ace6        Update_rows: table id 74 flags: STMT_END_F
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='gaopeng' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yhb' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='dzy' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl1' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=200 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=200 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=300 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
 
 
  這就是我們需要的日志,撈取這部分數據
  [root@localhost data]# mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v -v db-bin.000016 | sed -n '/# at 510/,/COMMIT/p'>/root/1.txt
  ps:sed -n '/#at 510/,/COMMIT/p'   表示從選取'# at 510'開始,到第一個commit結束的內容,然后導到1.txt文件.
  撈取之后的文件如下:
  [root@localhost ~]# cat 1.txt
  # at 510
  #150424 14:07:59 server id 199  end_log_pos 699 CRC32 0xf362ace6        Update_rows: table id 74 flags: STMT_END_F
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='gaopeng' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yhb' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='dzy' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='it' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=100 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl1' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=200 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=200 /* INT meta=0 nullable=1 is_null=0 */
  ### UPDATE `test`.`test1`
  ### WHERE
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='yl3' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=300 /* INT meta=0 nullable=1 is_null=0 */
  ### SET
  ###   @1='uu' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @2='test' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
  ###   @3=300 /* INT meta=0 nullable=1 is_null=0 */
  # at 699
  #150424 14:07:59 server id 199  end_log_pos 730 CRC32 0x83588cbb        Xid = 44
  COMMIT/*!*/;
  [root@localhost ~]#
 
  現在開始對撈取的這部分數據進行轉換,轉換成能執行的sql格式.其中會用到大量的sed命令,sed本人也不精通,我會解釋每個sed執行后達到的目的,具體關于sed命令參數等,請另行參考;
 
  [root@localhost ~]# sed '/WHERE/{:a;N;/SET/!ba;s//([^/n]*/)/n/(.*/)/n/(.*/)//3/n/2/n/1/}' 4.txt |sed 's/###//g;s////*.*/,/g' |sed -r '/WHERE/{:a;N;/@3/!ba;s/@2.*//g}' |sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g' | sed '/^$/d' >9.sql
  [root@localhost ~]#cat 9.sql
  UPDATE `test`.`test1`
    SET
      @1='it' ,
      @2='gaopeng' ,
      @3=100 ,
    WHERE
      @1='it' ;
     
    UPDATE `test`.`test1`
    SET
      @1='it' ,
      @2='yhb' ,
      @3=100 ,
    WHERE
      @1='it' ;
     
    UPDATE `test`.`test1`
    SET
      @1='it' ,
      @2='dzy' ,
      @3=100 ,
    WHERE
      @1='it' ;
     
    UPDATE `test`.`test1`
    SET
      @1='uu' ,
      @2='yl' ,
      @3=100 ,
    WHERE
      @1='uu' ;
     
    UPDATE `test`.`test1`
    SET
      @1='uu' ,
      @2='yl1' ,
      @3=200 ,
    WHERE
      @1='uu' ;
     
    UPDATE `test`.`test1`
    SET
      @1='uu' ,
      @2='yl3' ,
      @3=300 ,
    WHERE
      @1='uu' ;
     
  [root@localhost ~]# sed -i -r 's/(@3=.*),//1/g' 9.sql
  [root@localhost ~]# sed -i 's/@1/dept/g;s/@2/name/g;s/@3/salary/g' 9.sql
 
  對sed的各個命令逐步解釋:
  sed '/WHERE/{:a;N;/SET/!ba;s//([^/n]*/)/n/(.*/)/n/(.*/)//3/n/2/n/1/}' 4.txt |sed 's/###//g;s////*.*/,/g' |sed -r '/WHERE/{:a;N;/@3/!ba;s/@2.*//g}' |sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g' | sed '/^$/d'
 
  sed '/WHERE/{:a;N;/SET/!ba;s//([^/n]*/)/n/(.*/)/n/(.*/)//3/n/2/n/1/}' 4.txt
  這行表示把日志里的where換成set,把set換成where.因為在bin-log日志里面,where后面的是更改前的數據,set后面是update后的數據,現在我們要回滾到update前的數據所以要對where和set進行對換.
  |sed 's/###//g;s////*.*/,/g'
  這一個sed的目的是將binlog日志里面的###和/*...*/去掉.
  |sed -r '/WHERE/{:a;N;/@3/!ba;s/@2.*//g}'
  這一行是把非關鍵字段去掉.做為where條件,也可以只去掉只被update的字段,可以自由選擇,只要保證條件查詢出來的是唯一行就可以.
  |sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g'
  這一行表示在每條語句結尾加上';',mysql的結束符號是';',所以需要加上這個一個結束符.
  | sed '/^$/d'
  一行表示去除多余的,比較簡單.不多解釋.
  
  sed -i -r 's/(@3=.*),//1/g' 9.txt   將set最后一個字段(這里是@3)后面的','去掉.
  sed -i 's/@1/dept/g;s/@2/name/g;s/@3/salary/g' 9.txt  將@1,@2,@3 換成表中的字段名.
   
  [root@localhost ~]# more 9.txt
  UPDATE `test`.`test1`
    SET
      dept='it' ,
      name='gaopeng' ,
      salary=100
    WHERE
      dept='it' ;
     
    UPDATE `test`.`test1`
    SET
      dept='it' ,
      name='yhb' ,
      salary=100
    WHERE
      dept='it' ;
     
    UPDATE `test`.`test1`
    SET
      dept='it' ,
      name='dzy' ,
      salary=100
    WHERE
      dept='it' ;
     
    UPDATE `test`.`test1`
    SET
      dept='uu' ,
      name='yl' ,
      salary=100
    WHERE
      dept='uu' ;
     
    UPDATE `test`.`test1`
    SET
      dept='uu' ,
      name='yl1' ,
      salary=200
    WHERE
      dept='uu' ;
     
    UPDATE `test`.`test1`
    SET
      dept='uu' ,
      name='yl3' ,
      salary=300
    WHERE
      dept='uu' ;
      
  到此,需要回滾的sql撈取完畢,執行下改文件即可.這里不累述.
 
  ps:本次測試,其實是有問題的,還原數據的時候,導致數據沒辦法還原,這是因為我在測試的表里,沒有唯一值,所以,各位測試的時候,一定要找有唯一值的表進行測試,沒有唯一值,將導致還原的時候,數據無法還原到原來的模樣..

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 调兵山市| 芦山县| 普洱| 汶上县| 纳雍县| 北辰区| 天峨县| 衡水市| 灵石县| 托克托县| 句容市| 德清县| 甘南县| 含山县| 德令哈市| 清镇市| 康保县| 松滋市| 青海省| 恩平市| 北宁市| 肥东县| 连州市| 大方县| 新营市| 佛坪县| 正宁县| 望城县| 巴青县| 锡林郭勒盟| 彭州市| 博罗县| 石台县| 那坡县| 泰顺县| 新郑市| 泾源县| 观塘区| 昌平区| 礼泉县| 卢氏县|