对表误删或执行缺少条件的修改 SQL 导致修改了表内其他数据时,我们需要想办法将数据恢复回来。
先创建两个测试表 table_1
CREATE TABLE `table_1` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
首先要确保开启了BINLOG日志
-- 查看日志状态
show variables like '%log_bin%';
之前没有开启 Binlog 日志的话下面的方法就不能继续操作了,开启日志的方法网上有很多,修改一下配置文件并重启 MYSQL 服务。
模拟删除
正常情况下,我们需要从线上正在使用的日志中查找信息,要考虑的因素会很多。
为了方便测试,这里重启了一个新的日志,后面的所有操作都会记录到新的日志文件中。
flush logs
-- 插入table1一些数据
insert into table_1(name) values ('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('10')
-- 模拟删除表信息table1
delete from table_1 where id >5;
--然后修改table1的内容
update table_1 set name= Concat(name,'1') ;
修复步骤
我们需要删除的信息,并保留删除之后修改过的信息
-- 查看日志内容
show master status;
show binlog events in 'binlog.000023';
从上面的查询语句可以查询 binlog.000023 中记录的所有操作。
如图,我们在 993 的位置执行了删除表的操作,我们要把数据还原到这个位置之前
每一个事务从 Gtid 开始,Xid 结束。
有的时候,我们不确定这个位置在什么地方,但是我们有时间范围,可以根据时间范围缩小所有区间,这里需要用到 binlog 命令
以下是 Windows CMD 的命令实例:
mysqlbinlog.exe F:\Mysql\mysql-8.0.27-winx64\data\binlog.000021 --start-datetime="2022-11-17 13:00:00" --stop-datetime="2022-11-17 14:00:00"
控制台打印出来的结果和SQL查询出来的结果大致上是一样的。
找到我们要还原的位置之后,执行还原命令。
以下是 Windows CMD 的命令实例:
mysqlbinlog.exe F:\Mysql\mysql-8.0.27-winx64\data\binlog.000023 --stop-position=993 --database=dgcat | F:\Mysql\mysql-8.0.27-winx64\bin\mysql -uroot -p*****
执行后发现报错:
反馈 table_1表中已经有了主键 1 ,不能插入。是因为我们只指定了数据恢复的结束位置,而当前日志又包含了 table_1 的所有行插入记录,当恢复表时,他会重新插入这些行,导致和表内已存在的信息主键冲突。
因为我的 binlog 日志记录了 table_1 的所有操作记录。所以这里我选择将 table_1 清空,用日志恢复所有数据。
truncate table table_1
正常情况下,我们最好能确认下来数据恢复的开始位置。
再次执行恢复命令后,表内信息如下:
现在已经恢复了我们删除之前的状态,但是我们在删除之后还做了修改操作,我们还需要把修改操作也还原一下:
相当于跳过 delete 操作,1100 位置即是我们修改操作的开始位置,直至 1478 整个操作结束。
mysqlbinlog.exe F:\Mysql\mysql-8.0.27-winx64\data\binlog.000023 --start-position=1100 --stop-position=1478 --database=dgcat | F:\Mysql\mysql-8.0.27-winx64\bin\mysql -uroot -pzdm3713261995!!!
执行结束后我们在查询表内信息 ,删除的数据恢复了,而且我们修改过的记录也在。