搜到这篇文章的同学,先恭喜下,你可以准备三十六计之上上计了——跑路。

很多人都有理由问你怎么就能删库了,没有备份嘛。。。确实不应该,但偶有发生,就是没备份或者备份的数据太久了,真的就是脑子一抽抽就给删了。如果你的服务还没停掉或许还有一线生机,否则真的只能跑路了。

废话不多说,进入正题。这里介绍的是针对MySQL5.6之后的版本,之前是否支持不清楚,我实测的版本是5.7。

一、删除的文件有相应的进程还在运行中,文件就还在磁盘中为释放,使用 lsof 命令会看到有相关进程信息

[root@localhost gadb]# lsof | grep aas_user
mysqld    2489               mysql   43uW     REG              253,0    131072  101400693 /var/lib/mysql/gadb/aas_user.ibd (deleted)
mysqld    2489 2605          mysql   43uW     REG              253,0    131072  101400693 /var/lib/mysql/gadb/aas_user.ibd (deleted)
mysqld    2489 2617          mysql   43uW     REG              253,0    131072  101400693 /var/lib/mysql/gadb/aas_user.ibd (deleted)

前面的2489 就是当前MySQL服务的进程PID,切换键进入对应进程ID目录 

[root@localhost proc]# cd /proc/2489/fd
[root@localhost fd]# ll
total 0
lrwx------. 1 mysql mysql 64 Apr 10 10:18 7 -> /tmp/ibzowklK (deleted)
lrwx------. 1 mysql mysql 64 Apr 10 10:18 8 -> /tmp/ibTwn0T5 (deleted)
lrwx------. 1 mysql mysql 64 Apr 10 10:18 9 -> /var/lib/mysql/ib_logfile1
[root@localhost fd]# ll | grep aas_user
lrwx------. 1 mysql mysql 64 Apr 10 10:18 43 -> /var/lib/mysql/gadb/aas_user.ibd (deleted)

ll查看会有很多信息,命令行工具标红的就是删除未释放的,找到误删的文件,复制恢复即可,建议按照删除前的目录结构恢复

[root@localhost fd]# cp 43 /var/lib/mysql/gadb/aas_user.ibd
[root@localhost fd]#

如果只是删除了单个idb文件,到此就恢复了。如果删除的是目录,还得继续。

二、使用idb文件恢复数据。如果删除的是整个目录,那frm表结构文件是无法恢复的,需要自行创建表结构,另外表结构一定要和要误删的数据表结构一致,包括字段顺序,否则有可能会恢复乱码,甚至无法恢复。有的说进入十六进制界面直接编辑idb的tablespace_id的方法试了不好使,可能是哪里没搞明白。

新建一个备份恢复数据库,将数据库表结构导入或创建好,然后针对每个表执行以下操作:

1)执行SQL:ALTER TABLE product DISCARD TABLESPACE;

2)复制替换IDB文件,并修改权限:chown mysql.mysql   <table_name>.idb

3)执行SQL:ALTER TABLE product IMPORT TABLESPACE;

注:如果执行第三步报错,就是说明表结构不一致。如果执行成功,但是select  * 的时候报错:Error 2013 Lost connection to MySQL server during query ‘table’ at ... rows,那就是数据恢复有问题,可能是列错位导致字段类型不匹配,也需要重新调整表结构再恢复。另外恢复数据过程需要接触表的外键约束,否则无法重置表空间,需要删除各外键约束

如果表太多,自己写脚本。删除有风险,操作需谨慎,备份、备份、一定要备份!!!