成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

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

前提:binlog模式為row,隔離模式為read-committed
對(duì)于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' 因?yàn)楦暮蟮淖侄沃禐閠est,所以我們這里選test前15行和之后所有的數(shù)據(jù).

# 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 */


這就是我們需要的日志,撈取這部分?jǐn)?shù)據(jù)
[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'開(kāi)始,到第一個(gè)commit結(jié)束的內(nèi)容,然后導(dǎo)到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 ~]#


現(xiàn)在開(kāi)始對(duì)撈取的這部分?jǐn)?shù)據(jù)進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換成能執(zhí)行的sql格式.其中會(huì)用到大量的sed命令,sed本人也不精通,我會(huì)解釋每個(gè)sed執(zhí)行后達(dá)到的目的,具體關(guān)于sed命令參數(shù)等,請(qǐng)另行參考;


[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


對(duì)sed的各個(gè)命令逐步解釋:
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.因?yàn)樵赽in-log日志里面,where后面的是更改前的數(shù)據(jù),set后面是update后的數(shù)據(jù),現(xiàn)在我們要回滾到update前的數(shù)據(jù)所以要對(duì)where和set進(jìn)行對(duì)換.
|sed 's/###//g;s/\/\*.*/,/g'
這一個(gè)sed的目的是將binlog日志里面的###和/*...*/去掉.
|sed -r '/WHERE/{:a;N;/@3/!ba;s/@2.*//g}'
這一行是把非關(guān)鍵字段去掉.做為where條件,也可以只去掉只被update的字段,可以自由選擇,只要保證條件查詢出來(lái)的是唯一行就可以.
|sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g'
這一行表示在每條語(yǔ)句結(jié)尾加上';',mysql的結(jié)束符號(hào)是';',所以需要加上這個(gè)一個(gè)結(jié)束符.
| sed '/^$/d'
一行表示去除多余的,比較簡(jiǎn)單.不多解釋.


sed -i -r 's/(@3=.*),/\1/g' 9.txt   將set最后一個(gè)字段(這里是@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撈取完畢,執(zhí)行下改文件即可.這里不累述.

ps:本次測(cè)試,其實(shí)是有問(wèn)題的,還原數(shù)據(jù)的時(shí)候,導(dǎo)致數(shù)據(jù)沒(méi)辦法還原,這是因?yàn)槲以跍y(cè)試的表里,沒(méi)有唯一值,所以,各位測(cè)試的時(shí)候,一定要找有唯一值的表進(jìn)行測(cè)試,沒(méi)有唯一值,將導(dǎo)致還原的時(shí)候,數(shù)據(jù)無(wú)法還原到原來(lái)的模樣..

本文題目:mysql中update誤操作,利用binlog日志,模擬oracle閃回功能.
網(wǎng)站URL:http://jinyejixie.com/article28/iisccp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、微信小程序、全網(wǎng)營(yíng)銷推廣面包屑導(dǎo)航、響應(yīng)式網(wǎng)站Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
邵阳市| 互助| 无为县| 保德县| 城固县| 合阳县| 木兰县| 清徐县| 乐东| 金沙县| 赤水市| 简阳市| 连城县| 黄山市| 堆龙德庆县| 手游| 民勤县| 商城县| 道孚县| 崇明县| 呈贡县| 务川| 吉林省| 进贤县| 眉山市| 贡山| 平遥县| 沽源县| 海阳市| 水城县| 彩票| 平凉市| 成安县| 泰宁县| 新建县| 建宁县| 闵行区| 中卫市| 普宁市| 宝丰县| 石柱|