Mysql-经典实战案例(2)—数据误删如何恢复?
背景:
在数据库运维和开发过程中,误删数据堪称技术人最"心惊肉跳"的操作之一。一条不慎执行的DELETE语句,可能瞬间让重要数据消失无踪。传统的数据恢复往往依赖备份回滚,不仅操作复杂,还可能面临备份不及时的尴尬。为此,美团技术团队开源的MyFlash闪回工具应运而生——这款基于MySQL binlog解析的轻量级工具,无需全量备份即可通过逆向操作生成回滚SQL,为数据安全提供了灵活可靠的"后悔药"。本文将手把手带您实践MyFlash的部署与应用,让您掌握这项关键时刻能挽救危机的硬核技能。
通过使用myflash 工具恢复误删数据
myflash工具下载
https://github.com/Meituan-Dianping/MyFlash
一、安装
(务必要做!!否则回退会失败)
yum install -y gcc glib2 glib2-develunzip MyFlash-master.zipcd MyFlash-mastergcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
确认安装
cd /MyFlash-master/binary./flashback -h
二、环境准备(误删行数据)
创建测试数据
create table emp(id INT(11),name VARCHAR(25));insert into emp values(1,'a')
insert into emp values(1,'b')
误删数据
delete from emp where id = 1;commit;
此时表内已无数据
mysql> select * from emp;
Empty set (0.00 sec)
三、恢复
查看当前binlog
mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------------------+
| log_bin | ON |
| log_bin_basename | /data/mysqldata/my3306/log/mysql-bin mysql> show master status;
+------------------+----------+--------------+------------------+---------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+---------------------------------------------+
| mysql-bin.000003 | 194 | | | 1d6df993-f5e0-11ed-aa30-005056b388fd:1-1130 |
+------------------+----------+--------------+------------------+---------------------------------------------+
1 row in set (0.00 sec)
解析binlog
确认要恢复的gtid为1d6df993-f5e0-11ed-aa30-005056b388fd:1131(在delete操作之前)
[root@qiuyang1 binary]# mysqlbinlog -v /data/mysqldata/my3306/log/mysql-bin.000003 | egrep -i 'GTID_NEXT|DELETE FROM `test`.`emp`'SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1131'/*!*/;
### DELETE FROM `test`.`emp`
### DELETE FROM `test`.`emp`
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
使用flashback工具 生产闪回binlog文件
工具目录:
填写对应的数据库名、表名、要恢复的gtid
./flashback --binlogFileNames=/data/mysqldata/my3306/log/mysql-bin.000003 --databaseNames=test --tableNames=emp --sqlTypes=delete --include-gtids='1d6df993-f5e0-11ed-aa30-005056b388fd:1131'
在当前目录会生成binlog_output_base.flashback文件
使用mysqlbinlog 生成sql文件
mysqlbinlog --skip-gtids binlog_output_base.flashback >flash.sql
进入mysql数据库,应用该sql文件
mysql -uroot -psource flash.sql
验证
数据已回复
mysql> select * from emp;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 1 | b |
+------+------+
2 rows in set (0.00 sec)
四、环境准备(误删表)
创建测试数据
反复执行insert,最后构建出一张百万级别的表
CREATE TABLE test2(id INT PRIMARY KEY AUTO_INCREMENT);INSERT INTO test2() VALUES(),(),(),();INSERT INTO test2(id) SELECT id+(SELECT COUNT(*) FROM test2) FROM test2;mysql> select count(*) from test2;
+----------+
| count(*) |
+----------+
| 2097152 |
误删表
模拟场景:由于where条件的输入失误,导致整表被删
delete from test2 where 1=1;mysql> select count(*) from test2;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.09 sec)
五、恢复
查看当前binlog
mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------------------+
| log_bin | ON |
| log_bin_basename | /data/mysqldata/my3306/log/mysql-bin mysql> show master status;
+------------------+----------+--------------+------------------+---------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+---------------------------------------------+
| mysql-bin.000003 | 194 | | | 1d6df993-f5e0-11ed-aa30-005056b388fd:1-1130 |
+------------------+----------+--------------+------------------+---------------------------------------------+
1 row in set (0.00 sec)
解析binlog
确认要恢复的gtid为1d6df993-f5e0-11ed-aa30-005056b388fd:1136(在delete操作之前)
由于删除的行数过大,命令后面加上|more 查看在执行delete之前的gtid
[root@qiuyang1 binary]# mysqlbinlog -v /data/mysqldata/my3306/log/mysql-bin.000003 | egrep -i 'GTID_NEXT|DELETE FROM `test`.`test2`' |more
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1131'/*!*/;
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1132'/*!*/;
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1133'/*!*/;
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1134'/*!*/;
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1135'/*!*/;
SET @@SESSION.GTID_NEXT= '1d6df993-f5e0-11ed-aa30-005056b388fd:1136'/*!*/;
### DELETE FROM `test`.`test2`
### DELETE FROM `test`.`test2`
### DELETE FROM `test`.`test2`
### DELETE FROM `test`.`test2`
### DELETE FROM `test`.`test2`
### DELETE FROM `test`.`test2`
使用flashback工具 生产闪回binlog文件
工具目录:
填写对应的数据库名、表名、要恢复的gtid
./flashback --binlogFileNames=/data/mysqldata/my3306/log/mysql-bin.000003 --databaseNames=test --tableNames=test2 --sqlTypes=delete --include-gtids='1d6df993-f5e0-11ed-aa30-005056b388fd:1136'
在当前目录会生成binlog_output_base.flashback文件
使用mysqlbinlog 生成sql文件
mysqlbinlog --skip-gtids binlog_output_base.flashback >flash.sql
进入mysql数据库,应用该sql文件
mysql -uroot -psource flash.sql
验证
mysql> select count(*) from test2;
+----------+
| count(*) |
+----------+
| 2097152 |