【MYSQL】rm -rf mysql 之数据恢复

第一步 切记!!!切记!!!切记!!!!别着急着跑路

    维持现场状态,不能重启机子,也不行关闭运行中的mysql的进程,如果关闭就无法对数据进行恢复了;

这是因为:文件实际上是一个指向inode的链接, inode链接包含了文件的所有属性, 比如权限和所有者, 数据块地址(文件存储在磁盘的这些数据块中). 当你删除(rm)一个文件, 实际删除了指向inode的链接, 并没有删除inode的内容. 进程可能还在使用. 只有当inode的所有链接完全移去, 然后这些数据块将可以写入新的数据.

·    proc文件系统可以协助我们恢复数据. 每一个系统上的进程在/proc都有一个目录和自己的名字, 里面包含了一个fd(文件描述符)子目录(进程需要打开文件的所有链接). 如果从文件系统中删除一个文件, 此处还有一个inode的引用:

第二步 获取删除文件的PID

1.第一种方法 lsof

(参考https://blog.csdn.net/zonghua521/article/details/78200239

当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。

在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。

大多数与 lsof 相关的信息都存储于以进程的 PID 命名的目录中,即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。

lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。

例子1、

进程在运行中,接下来我就把/var/log/messages这个文件删掉

shell> rm /var/log/messages

删掉之后,我再来看看这个进程的变化

shell> lsof |grep /var/log/messages

rsyslogd   1737      root    1w      REG       8,2   5716123     652638 /var/log/messages (deleted)

大家看到有变化了吧, 对比两个之后发现多了(deleted)。要找到这个文件在哪还要看看这个

2.第二种方法 ps -aux|grep XXX (本人使用)

    在理解了方法1的原理之后,其实最终目的是获取PID,因此可以转换思路。

    因为知道被删除的是mysql的所有文件,所以可以直接使用 ps -aux|grep mysql 查看还在使用中的进程ID

3.第三种方法使用extundelete

(参考)https://blog.csdn.net/zxc_user/article/details/82025475

这种方式只能对文件系统为ext3 或者 ext4 类型的进行恢复,不然无法进行恢复

(注意:本人数据库服务器使用的是SSD,在恢复过程中都失败了,推测只能恢复机械硬盘的数据,且需要多挂载一块盘,因此本人放弃该方法,使用第二种,固在此不介绍,可自行百度)

第三步将数据写出到备份文件夹中

     使用命令进入到以进程的PID命名的目录中

     cd /proc/(第二步获取的PID)/fd

     此时能看到被rm 删除掉的文件状态为deleted

     找出需要恢复的文件编号

     例如截图中的2

     cat 2 >/recover/pts/1 该语句的作用是把还在内存中文件重新写到某个地方

     当我将/mysql/data/下的数据库文件全部备份出来的时候,深深的松了一口气,此时我们离数据完全恢复还有40%的工作要做。

从服务器上把备份好的.ibd文件导出至本地,并在自己的测试环境中进行mysql数据的恢复

第四步数据恢复

1、在测试环境中建立和线上一样的数据库、表结构

2、删除/mysql/data/数据库/相关表的.ibd文件

     alter table {database}.{table} discard tablespace;

3、复制备份的.ibd至该数据库文件夹下

      cp /recover/* /mysql/data/{database名称}/

     若有mysql使用的用户权限的话 需要赋权

      chown -R {用户}. /mysql/data/

4、进入mysql中,进行数据导入

     alter table {database}.{table} import tablespace;

    此时需要注意的是,每一条语句只能执行一次,即执行一句就要退出mysql,再次进入mysql执行第二句,以此类推

最后查询表就能看到数据都恢复完毕啦,将此时恢复好的数据库导出成sql文件,在线上执行恢复

数据无价,三思而后行!!多一份知识的传递  少一个跑路的程序员。。。。。

发布了1 篇原创文章 · 获赞 7 · 访问量 259

猜你喜欢

转载自blog.csdn.net/mo18850223090/article/details/105646561