909 字
5 分钟
误删文件找回

事件经过#

不小心把博客后端的数据库给删了,本来都绝望了,但是我测了一下api发现可以正常请求出来,说明他还在电脑内存里,辛亏用的是sqlite这种数据库,是mysql,postgresql就寄了。 然后就进还在运行的docker容器里找,最好不要在宿主机里找,进程太多,grep出来一大堆。如果docker-compose也被删了,就用docker ps先查容器id。进去容器内部的bash之后,如果有ps的话就ps+grep查数据库名, 如果没ps,就直接去/proc里,把这个路径下的所有文件全ls一遍,用grep筛选你要的。最好了解一下/proc的组织方式,我放到最后。

Terminal window
#进入容器里
docker exec -it 65917be1e702 bash
ls -l /proc/*/fd/* | grep db
#这个是个软连接,从pid11的fd文件句柄下的12号文件软连接到了原本数据库的位置,即使这个的inode已经被删掉了,他并没有被删除在磁盘扇区里。
lrwx------ 1 root root 64 Mar 14 12:34 /proc/11/fd/12 -> /flask_backend/instance/app.db (deleted)
#把他的软连接连接这的内存里的文件用cat读出来并输出到app.db里
root@65917be1e702:/flask_backend# cat /proc/11/fd/12 > /flask_backend/app.db
#在宿主机里把他从docker实例里重新读回宿主机里
docker cp 65917be1e702:/flask_backend/app.db ./app.db
  1. Delete 发生:文件名消失,Inode 引用计数 -1
  2. 进程握住:因为 Flask 还在运行,进程句柄对 Inode 的引用计数是 +1
  3. 结果:总计数 > 0,数据块在磁盘上被物理锁死,禁止重写。
  4. 抢救:你通过 cpcat 建立了一个新的文件名,指向了这个 Inode,引用计数再次 +1

proc#

/proc 目录不是真实存在于磁盘上的,它是一个“伪文件系统(Virtual File System)”。 它是 Linux 内核在大脑里划出的一块区域,实时映射着内核和进程的状态。

你可以把它理解为内核通过文件系统的形式,向你展示的一张**“动态全身扫描图”**。


1. 它是如何组织的?(目录结构)#

当你执行 ls /proc 时,你会看到两类东西:

A. 数字文件夹(PID 目录)#

每一个数字文件夹都代表一个当前正在运行的进程(Process)

  • /proc/[PID]/cmdline:启动这个进程的完整命令。
  • /proc/[PID]/cwd:进程的当前工作目录链接。
  • /proc/[PID]/exe:指向实际执行的二进制文件的链接。
  • /proc/[PID]/fd/:存放进程打开的所有文件句柄(File Descriptors)。
  • /proc/[PID]/status:进程的运行状态、内存占用、用户 ID 等。

B. 命名文件夹/文件(系统信息)#

这些不是进程,而是内核和系统的全局信息。

  • /proc/meminfo:系统的内存使用情况(free 命令就是读这里)。
  • /proc/cpuinfo:CPU 的型号、核心数、频率。
  • /proc/net/:整个系统的网络协议栈状态。
  • /proc/sys/(最强功能) 这里不仅能读,还能写。你可以通过修改这里的“文件”来实时调整内核参数(比如开启 IP 转发)。

2. 文件都在内存里吗?#

这里有一个细微但重要的区别:

  1. /proc 里的内容:确实只存在于内存中。当你关机时,这些东西全消失;当你开机时,内核重新生成。
  2. /proc/[PID]/fd 里的文件
  • 它们只是**“符号链接”**(类似快捷方式)。
  • 它们并不占用两倍内存,而是指向内核内部的一个 File Object
  • 只要这个链接还在,内核就知道:“嘿,这个进程还在用这块磁盘扇区,哪怕用户把文件名删了,我也得把数据留着。”
误删文件找回
https://blog.cannian.space/posts/2026-3-14-ops/
作者
Cannian
发布于
2026-03-14
许可协议
CC BY-NC-SA 4.0