我们最近在研究灾备,也就是说系统挂了,怎么办,库被删了怎么办。之前有被挟持过,问我们要0.000几个比特币,差不多几千还是几万块钱来着。不过是测试环境,推倒重建就好了。这次让出一个方案,说是生产库要是被删了,要如何处理。
我们的数据库是MySql8.0
的,也就基于这个版本进行尝试
准备
首先,库被删了之后,有以下方案可以恢复丢失的数据:
mysqlbinlog
命令来解析 Binlog。mysql-utilities
、pt-table-sync
等。这些工具可以更快速地进行数据对比,找出误删除的数据并进行恢复。ROLLBACK
命令可以撤销整个事务。备份我们是一天一备,事务回滚当前这种情况不适用,第三方工具还没研究,所以这里细细说下Binlog恢复数据
。
操作步骤
首先呢,我们建一个测试库,并新建一个测试表
CREATE TABLE `user` (
`user_id` int NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) DEFAULT NULL,
`sex` int DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert 两条数据
insert into user(user_name,sex) VALUES ('张三',1),('李四',0);
好了,我们的表现在是这样的:
现在演示,删除表的数据:
delete from user;
这时候,可以看到表里的数据已经没了
怎么办怎么办,跑路吗?别急别急,接下来才是正文:
现在,打开mysql应用的服务器,找到对应的binlog日志
每个里边都有可能有哈,我刚才执行的在binlog.000005
文件里边。
这里有值得注意的点是,可以执行flush logs;
进行日志的刷新,也就是让新的日志进入到新的日志文件里边,就不影响我们现在将要恢复的日志文件了。
接下来使用命令查看这个日志文件
mysqlbinlog binlog.000005
执行后展示如下:
看到没有,我框出来的,不就是我们刚才执行的sql吗?
但是这里有一点需要注意的,我开始研究的时候,binlog是不打印这个sql语句的。
需要执行:
set binlog_format=statement;
才会有,也就是说设置binlog的格式为statement
才可以,但是这个并不影响我们接下来的操作。
若是已经设置了binlog_format=statement
,那么我们可以找到对应的语句,重新执行一下就好,但是,若是没开呢。
我去把binlog_format改成默认的,set binlog_format=MIXED;
再来一遍。我们查看binlog日志如下:
上边的是insert的日志,下边的是delete的日志,大概的分辨方法就是,起始的地方会有个BEGIN
,结束的地方会有个COMMIT/*!*/;
然后我们要恢复的是我们上边insert的数据,找到前边和后边的编号起始位置是7553,结束位置是7522
mysqlbinlog --start-position=7319 --stop-position=7553 --database=demo binlog.000005 | mysql -uroot -p
至此我们可爱的数据就回来了。注意这里的数字是要包含所有的内容也就是,BEGIN
的数字取BEGIN
上边的,COMMIT
的数字取COMMIT
下边的。这样才可以成功。
还有一种方案,就是,在数据库连接工具中进行查询
执行
show binlog events in 'binlog.000005';
能看到如下结果
可以看到选中的三行就是我们需要的日志记录。取最前边的数字和最后边的数字执行上边的命令就行。
至此,数据就恢复啦。若是binlog日志很多很庞大的话,呢就只能一条一条找了,可以把
日志输出到文件里边mysqlbinlog binlog.000005 >binlog05.log
,这样就可以在本地慢慢查找了。
总的来说恢复的思路是,找到对应的插入sql,然后一条条执行。
总结
总结一下,我们需要关注以下几点:
mysqldump
或其他备份工具创建数据库备份。mysqlbinlog
命令查看误删数据时的 Binlog 文件。在输出中找到误删操作对应的 Binlog 事件,通常是 DELETE 语句。mysqlbinlog
或将 Binlog 文件导入到 MySQL 中,逐步执行误删操作的逆操作。这里我的数据库是8.0.36
的,系统是Ubuntu 22.04
的,好啦,完结撒花。