MySQL資料災難挽救之Delete\Update

龍山游龍發表於2021-11-08

場景:工作人員誤操作對其整表進行了更新,以及部分資料的誤刪除。

思路:利用mysqlbinlog命令檢視誤操作的binlog檔案,利用MyFlash閃回工具對MySQL 中的 DML 操作進行回滾,恢復到誤操作之前。

說明:要確保mysql開啟了binlog日誌功能,且binlog模式必須為row,binlog_row_image = full。且該場景恢復僅適用於MySQL5.6和5.7版本,不支援MySQL8.0版本。

一、手動快速安裝MyFlash

1.1 解壓ZIP包

shell> mkdir /MyFlash
shell> cd /MyFlash
shell> wget 
shell> unzip master.zip

1.2 編譯安裝MyFlash

shell> yum install gcc glib2-devel -y
shell> cd /MyFlash/MyFlash-master
shell> gcc -w  `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c  -o binary/flashback
shell> ls
binary  binlog_output_base.flashback  build.sh  doc  License.md  README.md  source  testbinlog

二、手動模擬測試資料

2.1 建立50000測試資料

mysql> create database test;
mysql> use test
mysql> CREATE TABLE `test` (
  `test_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`test_id`),
  KEY `idx_test_last_name` (`last_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> DELIMITER //
mysql> CREATE PROCEDURE mytest()
    -> begin
    -> declare sqltext varchar(4000);
    -> declare i bigint;
    -> set i=1;
    -> while i<=10000 do
    -> insert into test(first_name, last_name) values('zhang', 'san');
    -> insert into test(first_name, last_name) values('zhan', 'san');
    -> insert into test(first_name, last_name) values('zha', 'san');
    -> insert into test(first_name, last_name) values('zh', 'san');
    -> insert into test(first_name, last_name) values('z', 'san');
    -> set i = i+1 ;
    -> end while;
    -> commit;
    -> end
    -> //
mysql> DELIMITER ;
mysql> call myproc();
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|    50000 |
+----------

三、手動執行誤操作

3.1 update誤更新資料

mysql> update test.test set test_id=test_id+10000 where test_id>40000;
Query OK, 10000 rows affected (0.21 sec)
Rows matched: 10000  Changed: 10000  Warnings: 0

3.2 delete誤刪除資料

mysql> delete from test where test_id<10000;
Query OK, 9999 rows affected (0.06 sec)
 
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|    40001 |
+----------+

四、手動恢復資料

4.1 手動切換二進位制日誌

期望回滾 update 和 delete 操作。先 flush binlog,切換 binlog 檔案。

mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

4.2 解析binlog日誌

檢視二進位制日誌裡記錄的誤操作的開始和結束時間

shell> mysqlbinlog -vv /data/mysql-bin.000017 > test.txt

4.3 利用MyFlash工具生成誤操作回滾語句

利用MyFlash工具指定資料庫名,表名,開始和結束時間,回滾的sql 型別

shell> cd /MyFlash/MyFlash-master
shell> ./binary/flashback --databaseNames="test" --tableNames="test" --start-datetime="2021-11-04 14:37:58" --stop-datetime="2021-11-05 11:50:58" --sqlTypes="UPDATE,DELETE" --binlogFileNames=/data/mysql-bin.000017 --outBinlogFileNameBase=/root/test.sql

4.4 檢查反向解析後的 binlog 檔案

shell> mysqlbinlog -vv /root/test.sql.flashback

4.5 執行誤操作回滾

將反向解析的 binlog 檔案語句回放到資料庫中。如果資料庫開啟了gitd模式,則需要新增 --skip-gtids 選項來執行回滾語句

shell> mysqlbinlog --skip-gtids /root/test.sql.flashback | mysql -uroot -pAbcd321# -S /data/mysql.sock

4.6 檢查恢復資料

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|    50000 |
+----------+

至此 恢復成功


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30310891/viewspace-2841033/,如需轉載,請註明出處,否則將追究法律責任。

相關文章