宝塔误删数据库如何恢复?一次恢复mysql数据的实践

问题场景

昨天有热心网友找我,疑似是误操作删了库。

同时在导入宝塔的备份时,发现用户表也出现了异常,原有5800多用户,导入完只剩下490用户了

解决方案

通用思路

通常情况下,我们遇到这种情况有两种思路:

  • 是否有快照备份?是否有数据库sql文件备份?
  • 是否有BINLOG日志?

观察数据表排查问题

首先,我们先需要进入数据库查看用户表的情况,我们发现sms_common_user表从380个用户开始,就直接到5096用户了,因此数据应该是在这中间出现丢失的

图片[1]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

方案一:SQL文件恢复方法

这时,我们按照上面的解决方案方法一:

如果有快照备份那当然最好了,直接回滚就好了。

要是有快照热心网友还会找我?

图片[2]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

用户没有做快照策略,因此之前都是宝塔手动备份的SQL文件。

这时,我们需要去查看宝塔的备份

在宝塔的数据库>备份>下载最新的备份文件

图片[3]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

下载后解压缩发现是SQL文件,我们可以用记事本或者emeditor打开

可以看到插入用户表里是分两段进行插入的

图片[4]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

放到记事本里仔细打开看了下

图片[5]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

这381之后的用户明明都有啊,怎么会导入备份写不进去呢?这时,我想到之前autosign那个项目,就出现过用宝塔导入导不进去的情况,后来还是要用命令行导入的

手动导入SQL方法

手动导入sql文件的大致步骤:

  • 输入下面命令然后输入mysql的root密码
mysql -u root -p
  • 然后选择进入你要操作的数据库,譬如fancypig
use fancypig
  • 导入数据库sql文件pig.sql(请确保你运行第一个命令的时候,所在目录有pig.sql文件)
source pig.sql

按照上面的步骤我重新导入了一次数据库,结果发现还是不行……

图片[6]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

这就有点尴尬了,数据明明有,怎么导不进去呢,我决定进到phpmyadmin后台,手动输下SQL命令看看

我这里导入sms_common_user直接从381用户开始,看看能不能导进去

图片[7]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

结果发现报错了

图片[8]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

报错内容为

#1062 - Duplicate entry '?' for key 'sms_common_user.username'

上面报错的含义是指sms_common_user表下的username是唯一的键,也就代表着不允许有重复,那么问题来了,用户名为什么会重复?这个就要结合程序来分析了,这张表大多都是微信登录的用户,微信用户有的时候会出现emoji表情等符号,可能是在备份过程中这些特殊符号不识别,就被转成了?,因此,我们在恢复的时候就出现了导入失败的情况。如何打破上面的这种僵局呢?我们需要去索引里看下设置

图片[9]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

我们把UNIQUE改成INDEX就行了,就不要求用户名唯一了,这样就可以顺利导入了!

图片[10]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

改完之后,大约用了不到一分钟数据就全部导入成功了,用户恢复到5868个了

图片[11]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

方案二:BINLOG日志恢复

不过,这种方法,其实我一开始也想到了,这里也简单做个分享,其实如果你之前关注过行业的新闻,早在2017年就有gitlab著名的删库事件《Gitlab 从删库到恢复:丢失 6 小时生产数据,操作员应该被开除?》

当然,这都不重要,重要的是他们是如何恢复的?其实这里恢复很大程度上是借助BINLOG日志的

我们用的宝塔面板的/www/server/data路径下

mysql-bin开头的文件就是日志文件

图片[12]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

这里教大家简单的命令将日志导出到sql文件

宝塔的mysqlbinlog工具位置是/www/server/mysql/bin/mysqlbinlog

这时,我们要将mysql-bin.000006文件导出到/www/bak.sql

这里记得要先到/www路径下新建个空的bak.sql然后再执行下面的命令

/www/server/mysql/bin/mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000006 > /www/bak.sql

就这样,我们把mysql-bin.000005mysql-bin.000006mysql-bin.000007依次进行了恢复bak.sqlbak1.sqlbak2.sql,然后将其下载到本地

图片[13]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

这些文件几乎都是上百兆了,因此我们这时就不能用记事本打开了,就要像我开头说的用emeditor

工具里有个筛选功能还是不错的,在筛选的时候其他无关的内容就不会显示

然后,里面全部操作记录都可以看到

图片[14]-宝塔误删数据库如何恢复?一次恢复mysql数据的实践-FancyPig's blog

之后我们把和用户相关的数据导入sql数据库就行了(不过,我们的这个案例里核心问题不是数据丢失,而是数据因为表中字段的唯一性,导致无法导入表中)

© 版权声明
THE END
喜欢就支持一下吧
点赞1赞赏 分享
评论 共2条

请登录后发表评论