搜到这篇文章的同学,先恭喜下,你可以准备三十六计之上上计了——跑路。
很多人都有理由问你怎么就能删库了,没有备份嘛。。。确实不应该,但偶有发生,就是没备份或者备份的数据太久了,真的就是脑子一抽抽就给删了。如果你的服务还没停掉或许还有一线生机,否则真的只能跑路了。
废话不多说,进入正题。这里介绍的是针对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,那就是数据恢复有问题,可能是列错位导致字段类型不匹配,也需要重新调整表结构再恢复。另外恢复数据过程需要接触表的外键约束,否则无法重置表空间,需要删除各外键约束
如果表太多,自己写脚本。删除有风险,操作需谨慎,备份、备份、一定要备份!!!