1. 程式人生 > >mysql 恢復刪除資料

mysql 恢復刪除資料

    在資料庫日常維護中,開發人員是最讓人頭痛的,很多時候都會由於SQL語句寫的有問題導致伺服器出問題,導致資源耗盡。最危險的操作就是在做DML操作的時候忘加where條件,導致全表更新,這是作為運維或者DBA的我們改如何處理呢?下面我分別針對update和delete操作忘加where條件導致全表更新的處理方法。

一. update 忘加where條件誤操作恢復資料(binglog格式必須是ROW)

1.建立測試用的資料表

複製程式碼

mysql> create table t1 (
    -> id int unsigned not null auto_increment,
    
-> name char(20) not null,    -> sex enum('f','m') not null default 'm',    -> address varchar(30) not null,    -> primary key(id)    -> ); Query OK, 0 rows affected (0.31 sec)
mysql
>

複製程式碼

2.插入測試資料

複製程式碼

mysql> insert into t1 (name,sex,address)values('daiiy','m','guangzhou');
Query OK, 
1 row affected (0.01 sec) mysql> insert into t1 (name,sex,address)values('tom','f','shanghai');   Query OK, 1 row affected (0.00 sec) mysql> insert into t1 (name,sex,address)values('liany','m','beijing'); Query OK, 1 row affected (0.00 sec) mysql> insert into t1 (name,sex,address)values('lilu'
,'m','zhuhai');   Query OK, 1 row affected (0.05 sec) mysql>

複製程式碼

3.現在需要將id等於2的使用者的地址改為zhuhai,update時沒有新增where條件

複製程式碼

mysql> select * from t1;+----+-------+-----+-----------+| id | name  | sex | address   |+----+-------+-----+-----------+|  1 | daiiy | m   | guangzhou ||  2 | tom   | f   | shanghai  ||  3 | liany | m   | beijing   ||  4 | lilu  | m   | zhuhai    |+----+-------+-----+-----------+4 rows in set (0.01 sec)

mysql> update t1 set address='zhuhai';
Query OK, 3 rows affected (0.09 sec)
Rows matched: 4  Changed: 3  Warnings: 0mysql> select * from t1;              +----+-------+-----+---------+| id | name  | sex | address |+----+-------+-----+---------+|  1 | daiiy | m   | zhuhai  ||  2 | tom   | f   | zhuhai  ||  3 | liany | m   | zhuhai  ||  4 | lilu  | m   | zhuhai  |+----+-------+-----+---------+4 rows in set (0.00 sec)

mysql> 

複製程式碼

4.開始恢復,在線上的話,應該比較複雜,要先進行鎖表,以免資料再次被汙染。(鎖表,檢視正在寫哪個二進位制日誌)

複製程式碼

mysql> lock tables t1 read ;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;+------------------+----------+--------------+------------------+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000024 |     1852 |              |                  |+------------------+----------+--------------+------------------+1 row in set (0.00 sec)

mysql> 

複製程式碼

5.分析二進位制日誌,並且在其中找到相關記錄,在更新時是address='zhuhai',我們可以在日誌中過濾出來。

[[email protected] mysql]# mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS mysql-bin.000024 | grep -B 15 'zhuhai'

複製程式碼

# at 1629# at 1679#140305 10:52:24 server id 1  end_log_pos 1679  Table_map: `db01`.`t1` mapped to number 38#140305 10:52:24 server id 1  end_log_pos 1825  Update_rows: table id 38 flags: STMT_END_F
### UPDATE db01.t1
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */###   @2='daiiy' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='guangzhou' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */###   @2='daiiy' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='zhuhai' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### UPDATE db01.t1
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */###   @2='tom' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='shanghai' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### SET
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */###   @2='tom' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='zhuhai' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### UPDATE db01.t1
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */###   @2='liany' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='beijing' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### SET
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */###   @2='liany' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='zhuhai' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */

複製程式碼

可以看見裡面記錄了每一行的變化,這也是binglog格式要一定是row才行的原因。其中@1,@2,@3,@4,分別對應表中id,name,sex,address欄位。相信大家看到這裡有點明白了吧,對,沒錯,你猜到了,我們將相關記錄轉換為sql語句,重新匯入資料庫。

6.處理分析處理的二進位制日誌

複製程式碼

[[email protected] mysql]# mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS mysql-bin.000024 | sed -n '/# at 1679/,/COMMIT/p' > t1.txt  
[[email protected] mysql]# cat t1.txt 
# at 1679#140305 10:52:24 server id 1  end_log_pos 1679  Table_map: `db01`.`t1` mapped to number 38#140305 10:52:24 server id 1  end_log_pos 1825  Update_rows: table id 38 flags: STMT_END_F
### UPDATE db01.t1
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */###   @2='daiiy' /* STRING(60) meta=65084 nullable=0 is_null=0 */###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */###   @4='guangzhou' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */###   @2=