如何恢复在进程一直占用某个文件的时被删除的文件,并保持正常写入?
- 0次
- 2021-06-11 19:48:29
- idczone
场景假设:
进程 pid:1000
文件路径:/foo/bar.txt
被 1000 进程占用的文件描述符:6
当 1000 进程还占用着 /foo/bar.txt 的时候,执行 rm /foo/bar.txt -f,文件被“假删除了”(其实还在写数据),通过 losf |grep deleted|grep 1000|grep "/foo/bar.txt"可以看到被删除的文件(显示 deleted ),这时可以通过找到该进程的文件描述符文件夹里写入的文件名找到描述符,比如定位到了是 6 号文件描述符是被删除的文件的文件描述符,然后可以通过这条命令看到其实进程还在向该文件写数据:tail -F /proc/1000/fd/6 。
然后看了一些教程,直接把 fd 拷贝回被删除的文件,cp /proc/1000/fd/6 /foo/bar.txt ,但是这样的话被删除文件在被创建那一刻后就不再新写入数据了,换句话说复原的文件的数据只保留了我执行 大带宽服务器cp /proc/1000/fd/6 /foo/bar.txt 那一刻前的 /proc/1000/fd/6 的数据,而不会写入新数据,但是查看 fd 写入情况 tail -F /proc/1000/fd/6 是正常有新数据写入的。
我的问题就是怎么能在恢复被删除的文件的同时保证新数据正常写入?也就操作后不丢数据。
感觉上没有办法,删除了就是删除了,从 fd 复制出来的也是新文件了,原进程读取的还是原文件,这了是原进程 fd 能复制出已删除文件原原因,
至于 tail 能看到新文件,那只是因为 fd 里是软链接,新的 tail 进程解析软链接得到了新文件,
原进程要读新文件应该只能关闭 fd 重新读了,
谢谢您,我还有个疑问,就是源文件被删除了之后,fd 里面看到的软链文件内容是写到哪里了?
这个应该是打开没有完全关闭的文件并不会真的从磁盘删除,只是文件系统不能检索了,也就是删除了名称,实在不行你可以用 tail 啥的再次打开这个文件描述符占着,然后关闭你写文件这个进程,然后用 tail 打开的文件描述符复制文件到新文件,然后再启动刚才那个进程就行吧
原地址吧,毕竟文件删除只是删除文件头,不影响文件本身的数据,原进程拿着原 fd 继续操作的话,动的也还是原来数据所在位置,
这很容易验证,给 bar.txt 创建一个硬链接,然后删除 bar.txt ,fd 目录里的软链接解析出来的也是 deleted,但原进程继续写入内容的话,就能看到这个硬链接内容变化了,
感觉可以这样 先 tail 文件描述符重定向到 file1,然后把 fd 拷贝到 file2,重启业务,然后再合并一下 file1 与 file2 (可能需要人工,且假定文件只追加新的内容不修改之前写入的)
ln -L /proc/1000/fd/6 /foo/bar.txt
这个逻辑连接没有太看懂啥意思呀