MySQL数据灾难挽救之Delete\Update

来源:这里教程网 时间:2026-03-01 16:07:06 作者:

场景:工作人员误操作对其整表进行了更新,以及部分数据的误删除。思路:利用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 |
+----------+

至此 恢复成功

相关推荐