Mysql误删数据,恢复数据方法

422 阅读5分钟

正常开发环境下,操作Mysql一般是使用Navicat工具 在navicat中操作容易点击错误,误删数据,或者表格,这个时候如何进行数据恢复?

恢复数据有两种办法
第一种
通过备份进行恢复
navicat可以对表格操作,将表格转储为sql文件,通过这个方法备份比较好恢复,恢复的时候在navicat中运行sql文件就可以了,sql文件会携带表格结构和数据

第二种
没有进行备份的情况下,通过binlog二进制日志文件恢复,本篇文章也主要讲的是如何通过binlog恢复数据,binlog文件能做到的也是极为有限
原理
binlog文件记录的是mysql服务启动后,每一次操作记录,里面包含了数据,而数据恢复的原理就是再次执行一遍binlog中记录的方法进而重新插入数据
示例
首先查看binlog日志是否开启,在mysql输入以下命令进行查看,可以在navicat里新建查询查看

show variables like 'log_%';

查询结果 image.png
ON表示开启了binlog日志服务 下面两个路径表示binlog文件在哪个目录下,这里就表示日志文件在/var/lib/mysql这个目录下,也可以使用以下命令查看目录

show variables like '%datadir%'

image.png
如果binlog日志没开启,那就真的难恢复丢失的数据了,一般都是默认开启的 binlog日志开启方法:修改mysqlmy.cnf配置文件,一般默认是在 /etc/my.cnf 路径下

#开启binlog日志
log_bin=ON
#binlog日志的基本文件名
log_bin_basename=/var/lib/mysql/mysql-bin
#binlog文件的索引文件,管理所有binlog文件
log_bin_index=/var/lib/mysql/mysql-bin.index

查看文件
image.png
binlog文件命名是从000001开始,每重启一次mysql服务就会新创建一个binlog文件,时间就是服务开启的时间, 还有一个时间是上次服务的停止时间
图中的意思就是,原本我有两个binlog文件假设这个时候11文件不存在,09和10,09的时间是上次服务结束的时间,10是本次服务的开始时间
重启服务后,10记录的就是这次服务的结束时间,新的binlog文件11记录的就是开始时间。方便等下演示,这里我是重启了一次服务,因此多了11这个文件 (真想要恢复丢失数据就不要重启服务,表格也不要删除和增加字段,删除了再加回原来的样子也不行,我这里只是演示才重启)
有些情况下重启会生成两个binlog文件文件,其原理一样

查看文件里的内容
使用以下命令:

mysqlbinlog -v ./binlog.000011

由于我是刚刚重启了,因此这里并没有记录其他信息,因为还没对mysql进行操作

在mysql中新建表test1,并随意插入一点数据,用于测试 image.png 这个时候查看binlog文件,会发现里面有记录了
image.png
细细查看,关注几个重要信息,刚刚的操作记录,第一个小红框记录的是创建表语句执行前记录点(at 236) 以及 时间 231121 15:30:21 ,这里时间应该很好理解,就是2023-11-21 15:30:21
下面小红框就是创建表语句执行后的记录点以及时间。往下翻能看见插入数据的记录
image.png

image.png

image.png

截断表
image.png
这里也能看到记录
image.png
重点来了,恢复数据
执行命令,重新运行记录中的语句,执行到插入前,就能恢复数据,必须是重头来过,这里刚刚记录的 记录点以及时间就至关重要,如果想恢复111 222 333那些数据,就需要用到插入这条数据前的记录点或者时间
image.png
image.png 执行命令

mysqlbinlog --start-position=588 --stop-position=1402 --database=test ./binlog.000011 | mysql -u root -p 

这里执行的结束点是截断操作前的点
命令说明:
--start-position=xxx 开始
--stop-position=xxx 结束
--start-datetime="yyyy-MM-dd HH:mm:ss" 开始时间
--stop-datetime="yyyy-MM-dd HH:mm:ss" 结束时间
--database= 数据库名
./binlog.000011 binlog文件
mysql -u root -p 用户密码
image.png 刷新数据库,发现数据恢复了 image.png
(我这里是执行了两次,所以有两份数据)

通过时间点恢复

 mysqlbinlog --start-datetime="2023-11-21 15:30:37" --stop-datetime="2023-11-21 15:46:40" --database=test ./binlog.000011 | mysql -u root -p

image.png
这里的时间不一定要精确到这个文件记录的时间,意思是说,能确定在大概某个时间删除的,往前写一分钟左右,就可以了,开始时间也不必很精确,但是开启时间不能比binlog文件的创建时间早

删除表恢复演示
image.png image.png
服务重启时间
image.png
命令采用的开始时间点就不能比14:25早,不可以24分,可以用26分,结束时间点选截断前就可以了

mysqlbinlog --start-datetime="2023-11-21 14:26:00" --stop-datetime="2023-11-21 15:45:00" --database=test ./binlog.000011 | mysql -u root -p

这里选的开始时间,是在创建表之前的时间,因此才能恢复删除的表
navicat,关闭数据库再打开,就能看到恢复的表了
image.png

binlog弊端
若是表在误删之后进行了结构上的修改,那么binlog也无法恢复数据!!且这个不会报错!!
一旦字段又新增或删除就不行
譬如:这个表新增了d、e字段,再删除d、e改回来,中间也是算有新增删除字段的操作,这个使用binlog也无法恢复数据!!!因为结构有变动

恢复方法到此就结束了
以上过程若有不对,欢迎指出😀😀