mysql 恢復刪除資料
阿新 • • 發佈:2019-01-10
在資料庫日常維護中,開發人員是最讓人頭痛的,很多時候都會由於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=