当前位置:首页>Linux>Linux 文件系统(一)

Linux 文件系统(一)

  • 2026-08-18 23:11:23
Linux 文件系统(一)

从目录到磁盘数据

一、为什么要理解 Linux 文件系统

日常开发和运维中,我们经常会遇到这些问题:

  • Linux 文件最终存放在哪里?
  • /etc
    /varusrhome 分别有什么作用?
  • 文件名、inode 和文件数据之间是什么关系?
  • 为什么删除了大文件,磁盘空间却没有释放?
  • 为什么 df 显示磁盘已满,du 却找不到大文件?
  • 一个 Java 程序执行 FileInputStream.read() 时,数据经历了哪些层次?
  • 文件系统、分区、磁盘、挂载点之间到底是什么关系?

这些问题表面上属于不同领域,底层都指向同一套核心机制:

Linux 将文件访问抽象成统一接口,再通过 VFS、具体文件系统、页缓存、块设备和设备驱动,最终完成对物理存储介质的读写。

本文将沿着一条文件访问链路,从用户看到的目录和文件,一直讲到底层磁盘数据。

二、建立整体认知

Linux 文件系统不是一个单独的软件模块,而是一套分层协作机制。

一个应用读取文件时,大致会经历以下过程:

应用程序 open() / read() / write()系统调用接口VFS 虚拟文件系统页缓存 Page Cache具体文件系统ext4 / XFS / Btrfs / NFS块设备层设备驱动NVMe / SATA / SCSI / VirtIO物理存储介质SSD / HDD / 云盘

需要注意,这张图是为了帮助理解而进行的简化。

在真实 Linux 内核中,读写流程并不总是严格按照单一顺序执行。例如:

  • 普通文件读取可能直接命中页缓存,不访问磁盘;
  • O_DIRECT
     可以绕过页缓存;
  • tmpfs
     数据主要存放在内存和交换空间中;
  • procfs
    sysfs 中的内容由内核动态生成,并不存放在磁盘;
  • NFS、CIFS 等网络文件系统的数据来自远程服务器。

因此,Linux 中的“文件”是一种统一抽象,但文件背后的数据来源可能完全不同。

三、Linux 文件系统的六个核心层次

3.1 应用层:用户看到的文件世界

应用程序通常通过路径访问文件,例如:

cat /etc/hosts

Java 程序中可能是:

try (FileInputStreaminput=newFileInputStream("/etc/hosts")) {byte[] buffer = newbyte[4096];intlength= input.read(buffer);}

在应用层,程序只关心:

  • 文件路径;
  • 文件是否存在;
  • 是否有权限;
  • 能否读取或写入;
  • 读取了多少字节。

应用程序通常不需要知道:

  • 文件位于哪块磁盘;
  • 使用 ext4、XFS 还是 Btrfs;
  • 文件数据分布在哪些磁盘块;
  • 底层是 SATA SSD、NVMe SSD 还是云盘。

这种隔离正是操作系统抽象的价值。

3.2 系统调用层:用户态进入内核态

应用程序不能直接访问磁盘硬件,也不能直接操作内核中的文件系统对象。

它必须通过系统调用进入内核。

常见文件系统调用包括:

系统调用
作用
openat()
打开或创建文件
read()
读取文件内容
write()
写入文件内容
close()
关闭文件描述符
stat()
获取文件元数据
unlink()
删除一个目录项
mkdir()
创建目录
rename()
重命名或移动文件
fsync()
将文件修改同步到底层存储
mmap()
将文件映射到进程地址空间

虽然我们经常说 open(),但现代 Linux 中,很多库函数最终会使用 openat() 或相关变体。

例如:

strace -e trace=openat,read,close cat /etc/hosts

可能看到类似输出:

openat(AT_FDCWD, "/etc/hosts", O_RDONLY) = 3read(3, "127.0.0.1 localhost\n...", 131072) = 221close(3) = 0

其中:

3

就是内核返回给进程的文件描述符。

3.3 VFS:统一所有文件系统的抽象层

VFS 全称 Virtual File System,即虚拟文件系统。

它位于系统调用和具体文件系统之间,为上层提供统一接口。

无论文件位于:

  • ext4;
  • XFS;
  • Btrfs;
  • tmpfs;
  • NFS;
  • procfs;
  • sysfs;

应用程序都可以使用类似的方式访问:

open();read();write();close();

VFS 的主要作用包括:

  1. 提供统一的文件操作接口;
  2. 管理路径解析;
  3. 管理挂载关系;
  4. 管理打开文件状态;
  5. 将通用操作分派给具体文件系统实现。

例如,应用程序调用:

read(fd, buffer, size);

VFS 会根据这个文件对应的文件系统类型,将读取操作交给:

  • ext4 的读取实现;
  • XFS 的读取实现;
  • NFS 的读取实现;
  • procfs 的动态读取实现。

应用程序不需要知道这些差异。

3.4 具体文件系统:决定数据如何组织

VFS 只是统一接口,真正负责组织文件和数据的是具体文件系统。

常见 Linux 文件系统包括:

文件系统
主要特点
常见场景
ext4
成熟稳定、兼容性好、运维工具完善
Ubuntu、通用服务器
XFS
大文件和并发 I/O 表现较好,扩容能力强
企业服务器、数据库、大数据
Btrfs
快照、子卷、校验、压缩、写时复制
桌面系统、容器、快照管理
tmpfs
主要使用内存,速度快,重启后通常丢失
/run
、临时数据
NFS
通过网络访问远程文件
文件共享、集群环境
procfs
动态展示进程和内核状态
/proc
sysfs
展示设备和内核对象信息
/sys

具体文件系统负责:

  • inode 分配;
  • 目录结构管理;
  • 数据块或 extent 分配;
  • 空闲空间管理;
  • 日志记录;
  • 崩溃恢复;
  • 权限和扩展属性;
  • 文件大小和时间戳维护。

不同文件系统实现不同,但都通过 VFS 向上提供统一能力。

3.5 页缓存:内存中的文件数据缓存

普通文件 I/O 通常不会每次都直接访问磁盘。

Linux 会使用 Page Cache,也就是页缓存,缓存文件内容。

读取文件时:

应用程序VFS├──页缓存中存在数据──►直接返回└──页缓存中不存在数据读取磁盘数据放入页缓存返回应用程序

写文件时,普通 write() 通常先把数据写入页缓存。

此时:

  • write()
     返回成功;
  • 数据已经进入内核内存;
  • 数据不一定已经写入磁盘。

内核会在合适的时机将脏页写回磁盘。

这也是为什么:

outputStream.write(data);

执行成功,并不一定意味着数据已经安全落盘。

需要更强持久性保证时,应考虑:

fsync(fd);

或者在 Java 中使用:

fileDescriptor.sync();

数据库通常会通过 fsync()fdatasync() 或直接 I/O 控制数据持久性。

Page Cache 不等于块设备缓存

需要区分几个概念:

  • Page Cache:缓存文件内容;
  • Buffer Head:传统块元数据和块映射机制;
  • 磁盘控制器缓存:硬件控制器中的缓存;
  • SSD 内部缓存:存储设备自身的缓存。

这些缓存位于不同层次,不能简单混为一谈。

3.6 块设备和物理存储

具体文件系统最终需要将逻辑文件数据转换成底层存储请求。

Linux 将磁盘、分区、逻辑卷等抽象为块设备,例如:

/dev/sda/dev/sda1/dev/nvme0n1/dev/nvme0n1p1/dev/mapper/ubuntu--vg-ubuntu--lv

块设备支持按块随机访问。

文件系统通常使用 4 KiB 等大小的文件系统块管理数据,但具体大小取决于格式化参数和文件系统实现。

存储设备底层还存在扇区概念:

  • 逻辑扇区常见为 512 B 或 4 KiB;
  • 物理扇区可能是 4 KiB;
  • 文件系统块通常是 4 KiB;
  • 内存页在常见 x86-64 系统上通常也是 4 KiB。

这些值经常相同,但它们属于不同层次,不能认为必然一致。

四、Linux 目录树和磁盘不是一回事

4.1 Linux 只有一棵目录树

Linux 使用单根目录树:

/├── etc├── home├── usr├── var├── dev├── proc├── run└── data

所有目录都从 / 开始。

这与 Windows 的盘符模型不同:

C:\D:\E:\

Linux 不要求每块磁盘对应一个独立根目录。

一块磁盘、一个分区或一个网络文件系统,可以挂载到目录树中的任意目录。

例如:

mount /dev/sdb1 /data

含义是:

将 /dev/sdb1 上的文件系统接入 /data 这个目录节点。

从此以后访问:

/data

就是在访问 /dev/sdb1 上的文件系统。

4.2 路径不直接等于磁盘位置

例如:

/var/lib/mysql/ibdata1

这个路径并不能直接说明数据位于哪块物理磁盘。

它可能位于:

/dev/nvme0n1p2

也可能位于:

/dev/mapper/ubuntu--vg-data

还可能位于:

  • RAID 阵列;
  • LVM 逻辑卷;
  • iSCSI 设备;
  • 云厂商虚拟磁盘;
  • 网络存储。

可以使用:

findmnt -T /var/lib/mysql/ibdata1

查看某个路径实际属于哪个挂载点。

示例:

TARGET SOURCE                    FSTYPE OPTIONS/      /dev/mapper/ubuntu-root   ext4   rw,relatime

五、Linux 核心目录解析

Linux 目录布局通常遵循 Filesystem Hierarchy Standard 的基本原则,但不同发行版可能存在差异。

5.1 /:根目录

/ 是整棵目录树的起点。

系统启动后,根文件系统首先被挂载,其他文件系统再挂载到根目录树中的不同位置。

查看根目录所在文件系统:

findmnt /

5.2 /etc:系统配置

/etc 主要存放系统级配置文件。

常见内容:

/etc/passwd/etc/group/etc/hosts/etc/fstab/etc/ssh/sshd_config/etc/nginx/nginx.conf/etc/systemd/system/

特点:

  • 主要是配置;
  • 通常是文本文件;
  • 不适合存放大量业务数据;
  • 系统迁移时往往需要重点备份。

例如:

cat /etc/fstab

可以查看系统启动时的文件系统挂载配置。

5.3 /var:持续变化的数据

var 表示 variable。

这里通常存放系统运行过程中不断变化的数据。

常见目录:

目录
作用
/var/log
系统和应用日志
/var/lib
服务持久化状态数据
/var/cache
应用缓存
/var/spool
邮件、打印、定时任务等队列
/var/tmp
较长期的临时文件

例如:

/var/lib/mysql/var/lib/docker/var/log/nginx/var/log/journal

线上磁盘空间异常时,/var 往往是重点排查区域。

5.4 /home:普通用户家目录

普通用户通常拥有自己的家目录:

/home/alice/home/developer/home/ditt

用户登录后,环境变量:

echo"$HOME"

通常会指向对应目录。

用户级配置文件也经常存放在这里:

~/.bashrc~/.ssh/~/.config/~/.local/

5.5 /root:root 用户家目录

root 用户的家目录一般是:

/root

而不是:

/home/root

这样设计可以使 root 的家目录不依赖 /home 是否独立挂载。

5.6 /usr:程序和共享资源

/usr 是 Linux 系统中体量最大的目录之一。

常见子目录:

目录
内容
/usr/bin
常用用户命令
/usr/sbin
系统管理命令
/usr/lib
程序库
/usr/share
架构无关的共享数据
/usr/local
本地手工安装的软件

现代 Linux 发行版通常采用 usr merge。

这意味着:

/bin  -> /usr/bin/sbin -> /usr/sbin/lib  -> /usr/lib

因此,/bin 和 /usr/bin 在很多现代系统中已经不是两个真正独立的目录。

可以执行:

ls -ld /bin /sbin /lib

查看它们是否为符号链接。

5.7 /tmp:临时文件

/tmp 用于保存短期临时数据。

特点:

  • 所有用户通常可写;
  • 使用 sticky bit 防止用户删除其他人的文件;
  • 内容可能在重启或定期清理时被删除;
  • 不应存放重要持久化数据。

查看权限:

ls -ld /tmp

常见输出:

drwxrwxrwt

最后一个 t 表示 sticky bit。

5.8 /dev:设备文件

Linux 将设备抽象为文件。

例如:

/dev/sda/dev/nvme0n1/dev/null/dev/zero/dev/random/dev/tty

这些通常不是普通磁盘文件,而是设备节点。

查看类型:

ls -l /dev/null /dev/nvme0n1

设备文件主要分为:

  • 字符设备;
  • 块设备。

其中磁盘和分区通常属于块设备。

5.9 /proc:内核和进程信息

/proc 是虚拟文件系统。

它不是普通磁盘目录,其中内容主要由内核动态生成。

例如:

/proc/cpuinfo/proc/meminfo/proc/loadavg/proc/<pid>/status/proc/<pid>/fd/

查看内存信息:

cat /proc/meminfo

查看进程打开的文件描述符:

ls -l /proc/<pid>/fd

/proc 中看到的内容通常不占用根文件系统的数据空间。

5.10 /sys:设备和内核对象

/sys 同样是虚拟文件系统。

它主要展示:

  • 设备;
  • 驱动;
  • 总线;
  • 内核对象;
  • 块设备参数。

例如:

/sys/block//sys/class/net//sys/devices/

查看块设备队列参数:

ls /sys/block/nvme0n1/queue/

5.11 /run:运行时状态

/run 保存系统启动后的运行时状态。

常见内容:

/run/systemd//run/lock//run/user//run/docker.pid

/run 通常挂载为 tmpfs,因此内容主要存在于内存中,重启后会消失。

六、VFS 的四个核心对象

理解 Linux 文件系统,最关键的是理解以下四个对象:

superblockinodedentryfile

它们分别解决不同问题。

6.1 superblock:描述整个文件系统

超级块代表一个已经挂载的文件系统实例。

它通常包含:

  • 文件系统类型;
  • 文件系统块大小;
  • 总空间和空闲空间信息;
  • inode 统计;
  • 挂载状态;
  • 文件系统操作函数;
  • 文件系统特有信息。

可以把它理解为:

整个文件系统的总体管理对象。

对于 ext4 文件系统,磁盘中也存在持久化超级块结构。

查看 ext4 超级块信息:

sudo tune2fs -l /dev/sda1

或者:

sudo dumpe2fs -h /dev/sda1

操作前应确认设备名称,避免对错误设备执行命令。

6.2 inode:描述文件本身

inode 是文件的核心元数据对象。

inode 通常保存:

  • 文件类型;
  • 权限;
  • 所有者 UID;
  • 所属组 GID;
  • 文件大小;
  • 硬链接计数;
  • 访问时间;
  • 修改时间;
  • inode 状态变更时间;
  • 数据块或 extent 映射;
  • 扩展属性;
  • ACL 等信息。

inode 通常不保存普通文件名。

文件名保存在目录数据中。

查看文件 inode:

ls -li /etc/hosts

示例:

131105 -rw-r--r-- 1 root root 221 Jul 20 10:30 /etc/hosts

最左侧数字:

131105

就是 inode 号。

查看详细元数据:

stat /etc/hosts

6.3 dentry:文件名到 inode 的映射

dentry 全称 directory entry,即目录项。

目录中的一个名称,例如:

hosts

会对应到某个 inode。

可以简化理解为:

文件名 inode

例如目录:

/etc

内部保存类似关系:

hosts       inode 131105passwd      inode 131212group       inode 131213

路径解析:

/etc/nginx/nginx.conf

并不是一次性直接找到文件,而是逐层查找:

/└── etc└── nginx└── nginx.conf

内核需要依次解析每一级目录项。

为了提高路径查找效率,Linux 会维护 dentry cache。

这也是大量文件操作性能与目录结构密切相关的原因之一。

6.4 file:一次打开文件的状态

当进程打开一个文件时,内核会创建或关联一个 struct file 对象。

这个对象代表:

某个进程对某个文件的一次打开实例。

它通常包含:

  • 当前读写偏移量;
  • 打开方式;
  • 状态标志;
  • 对应 inode;
  • 文件操作函数;
  • 访问模式。

例如:

int fd = open("/tmp/test.log", O_RDONLY);

内核返回的 fd 只是一个整数索引。

进程内部关系可以简化为:

文件描述符 fd进程文件描述符表打开文件对象 struct fileinode文件数据

同一个文件可以被多个进程同时打开。

这些进程可能:

  • 指向同一个 inode;
  • 拥有不同的 file 对象;
  • 拥有不同的文件偏移量;
  • 使用不同的打开标志。

七、文件名、inode 和数据的真实关系

一个普通文件可以抽象成三部分:

文件名目录项 dentryinode数据块或 extent

例如:

/var/log/myapp/app.log

其中:

  • app.log
     是目录中的名称;
  • 目录项将 app.log 映射到 inode;
  • inode 保存文件属性和数据位置;
  • 数据块保存真正的日志内容。

因此:

文件名不是文件本体,inode 也不是文件内容,数据块才保存文件数据。

八、硬链接和符号链接

8.1 硬链接

硬链接的本质是:

多个目录项指向同一个 inode。

实验:

echo"hello" > source.txtln source.txt hard-link.txtls -li source.txt hard-link.txt

输出可能是:

105001 -rw-r--r-- 2 user user 6 Jul 27 10:00 hard-link.txt105001 -rw-r--r-- 2 user user 6 Jul 27 10:00 source.txt

可以看到:

  • inode 号相同;
  • 硬链接计数为 2;
  • 两个文件名对应同一份数据。

删除其中一个:

rm source.txtcat hard-link.txt

数据仍然可以访问。

只有当:

硬链接计数为 0并且没有进程继续打开该文件

文件占用的存储空间才可以被真正回收。

硬链接的限制

通常情况下:

  • 不能跨文件系统;
  • 普通用户不能给目录创建硬链接;
  • 不能直接区分哪个是“原文件”。

因为从 inode 角度看,多个名称地位相同。

8.2 符号链接

符号链接本身是一个独立文件,它保存的是目标路径。

创建符号链接:

ln -s source.txt soft-link.txt

查看:

ls -li source.txt soft-link.txt

两个文件的 inode 通常不同。

符号链接保存的内容类似:

source.txt

如果删除源文件:

rm source.txtcat soft-link.txt

符号链接将失效。

符号链接特点

  • 可以跨文件系统;
  • 可以指向目录;
  • 可以指向不存在的目标;
  • 目标删除后会成为悬空链接。

九、删除文件时,系统到底做了什么

执行:

rm app.log

并不意味着立即将文件内容全部写成零。

典型过程是:

  1. 删除目录中的文件名映射;
  2. inode 的硬链接计数减 1;
  3. 如果链接计数变为 0,文件不再能通过路径访问;
  4. 如果仍有进程持有打开文件对象,inode 和数据块继续保留;
  5. 当最后一个打开引用释放后,文件系统才回收 inode 和数据空间;
  6. 被回收的数据块随后可以被其他文件重新使用。

因此,删除文件需要同时区分两个条件:

硬链接数量打开文件引用数量

只有两者都归零,空间才会真正释放。

9.1 为什么删除文件后还能恢复

文件删除后,文件系统一般只是将相关空间标记为可重新使用。

在新数据覆盖之前,旧数据可能仍然残留在存储介质中。

恢复成功率取决于:

  • 文件系统类型;
  • 删除后的写入量;
  • 是否使用 SSD;
  • SSD 是否执行 TRIM;
  • 是否发生日志覆盖;
  • 文件是否碎片化;
  • 恢复工具能力。

需要注意:

在现代 SSD、TRIM、写时复制文件系统和加密存储环境中,删除恢复并不一定可靠。

发现误删后,应立即:

  1. 停止向对应文件系统写入;
  2. 尽量卸载文件系统;
  3. 使用只读方式制作磁盘镜像;
  4. 在副本上执行恢复;
  5. 不要在原磁盘上安装恢复工具。

9.2 shred 并不适用于所有存储设备

传统机械硬盘上,多次覆写可能降低数据恢复概率。

但以下环境中,shred 不能保证完全擦除:

  • SSD;
  • 启用了磨损均衡的闪存设备;
  • 写时复制文件系统;
  • RAID;
  • 存储快照;
  • 云盘;
  • 日志型文件系统;
  • 压缩文件系统。

更可靠的敏感数据保护策略是:

  • 全盘加密;
  • 销毁加密密钥;
  • 使用设备安全擦除功能;
  • 使用存储厂商提供的安全删除机制。

十、挂载:把一个文件系统接入目录树

10.1 什么是挂载

假设存在一个分区:

/dev/sdb1

先创建挂载点:

sudomkdir -p /data

执行挂载:

sudo mount /dev/sdb1 /data

此后:

/data/file.txt

实际存储在 /dev/sdb1 上的文件系统中。

挂载的本质是:

将一个文件系统的根目录连接到当前目录树的某个目录节点。

10.2 挂载遮挡

假设 /data 原本有文件:

echo"old data" | sudotee /data/old.txt

然后将新文件系统挂载到 /data

sudo mount /dev/sdb1 /data

此时:

ls /data

看不到原来的 old.txt

但它没有被删除,只是被新挂载的文件系统遮挡了。

卸载:

sudo umount /data

原来的文件会重新出现。

这就是挂载遮挡。

10.3 挂载点不一定必须是空目录

技术上,非空目录也可以作为挂载点。

但是这样会遮挡原有内容,因此生产环境通常建议使用空目录作为挂载点,避免误判和空间浪费。

十一、从磁盘到文件:分区、文件系统和挂载点

这几个概念容易混淆:

磁盘分区文件系统挂载点

例如:

/dev/nvme0n1          磁盘└── /dev/nvme0n1p2    分区├── ext4      文件系统└── /         挂载点

完整过程可能是:

# 1. 查看磁盘lsblk# 2. 创建分区sudo fdisk /dev/sdb# 3. 创建文件系统sudo mkfs.ext4 /dev/sdb1# 4. 创建挂载点sudomkdir -p /data# 5. 挂载sudo mount /dev/sdb1 /data

生产环境中还可能增加 LVM:

物理磁盘分区或整盘LVM PVVolume GroupLogical Volumeext4 / XFS挂载点

十二、常用排查命令

12.1 df:查看文件系统空间

df -h

示例:

Filesystem      Size  Used Avail Use% Mounted on/dev/sda2        98G   76G   17G  82% //dev/sdb1       500G  120G  380G  25% /data

字段说明:

字段
含义
Filesystem
文件系统来源
Size
总容量
Used
已使用
Avail
普通用户可用空间
Use%
使用率
Mounted on
挂载点

查看指定路径所属文件系统:

df -h /var/log

查看文件系统类型:

df -hT

查看 inode 使用情况:

df -i

12.2 du:统计目录和文件占用

查看目录占用:

du -sh /var/log

查看一级子目录:

du -xh --max-depth=1 /var | sort -h

查找较大的目录:

sudodu -xah /var | sort -rh | head -30

参数说明:

  • -x
    :不跨文件系统;
  • -a
    :统计文件和目录;
  • -h
    :人类可读;
  • --max-depth=1
    :只查看一级。

需要注意:

du 根据当前可见目录项统计文件占用,而 df 根据文件系统整体空间统计。

因此两者结果可能不同。

12.3 lsblk:查看块设备结构

lsblk

更推荐:

lsblk -f

输出可能包括:

NAME        FSTYPE FSVER LABEL UUID                                 MOUNTPOINTSnvme0n1├─nvme0n1p1 vfat   FAT32       XXXX-XXXX                            /boot/efi└─nvme0n1p2 ext4   1.0         xxxx-xxxx-xxxx                      /sdb└─sdb1      xfs                yyyy-yyyy-yyyy                      /data

可以同时看到:

  • 磁盘;
  • 分区;
  • 文件系统;
  • UUID;
  • 挂载点。

12.4 findmnt:查看挂载关系

显示完整挂载树:

findmnt

查看路径所在文件系统:

findmnt -T /var/lib/mysql

查看指定挂载点:

findmnt /data

只输出来源设备:

findmnt -n -o SOURCE -T /data

查看文件系统类型:

findmnt -n -o FSTYPE -T /data

12.5 stat:查看文件元数据

stat app.log

重点字段:

SizeBlocksInodeLinksAccessModifyChangeBirth

其中:

  • Size
    :逻辑大小;
  • Blocks
    :实际分配的磁盘块数量;
  • Inode
    :inode 号;
  • Links
    :硬链接数量;
  • Modify
    :文件内容修改时间;
  • Change
    :inode 元数据变更时间;
  • Birth
    :创建时间,并非所有文件系统都支持。

注意:

ctime 是 change time,不是 create time。

12.6 lsof:查看进程打开的文件

查看已删除但仍然打开的文件:

sudo lsof +L1

也可以:

sudo lsof | grep '(deleted)'

推荐优先使用:

sudo lsof +L1

因为它直接筛选硬链接计数小于 1 的打开文件。

查看某个进程:

sudo lsof -p <PID>

查看指定目录下被打开的文件:

sudo lsof +D /var/log/myapp

对于大型目录,+D 可能较慢,应谨慎使用。

十三、为什么 df 很满,du 却不大

这是 Linux 运维中的经典问题。

13.1 已删除文件仍被进程占用

场景:

rm /var/log/myapp/app.log

但 Java 进程仍然保持该文件打开。

此时:

  • 文件名已经消失;
  • du
     无法通过目录遍历统计它;
  • 进程仍持有文件对象;
  • inode 和数据块没有释放;
  • df
     仍然显示空间被占用。

检查:

sudo lsof +L1

可能看到:

java  1823 app  12w REG 8,1 21474836480 0 123456 /var/log/myapp/app.log (deleted)

表示 Java 进程仍然占用一个约 20 GiB 的已删除文件。

13.2 挂载遮挡

如果某个非空目录被挂载新文件系统,原目录内容会被遮挡。

例如:

/data

原本在根分区中占用 100 GiB。

后来 /dev/sdb1 挂载到 /data,原内容不可见。

此时:

  • du /data
     统计的是新文件系统;
  • 原来的 100 GiB 仍占用根分区;
  • 常规目录遍历无法直接看到。

可以使用 bind mount 查看根文件系统原始目录。

假设 /data 位于根文件系统:

sudomkdir -p /mnt/root-viewsudo mount --bind / /mnt/root-viewsudodu -sh /mnt/root-view/data

这样可以绕过 /data 当前的挂载,查看根文件系统中的原始内容。

完成后卸载:

sudo umount /mnt/root-view

13.3 文件系统保留空间

ext4 默认可能为特权用户保留一部分空间。

这可以防止普通用户写满整个文件系统,确保系统服务和 root 仍有一定操作空间。

查看:

sudo tune2fs -l /dev/sda2 | grep -E 'Reserved block count|Block size'

因此:

  • df
     中的 Avail 不一定等于 Size - Used
  • root 和普通用户看到的可用空间可能不同。

13.4 inode 耗尽

有时磁盘容量还很多,但无法创建新文件。

检查:

df -i

如果看到:

IUse% 100%

说明 inode 已耗尽。

常见原因:

  • 海量小日志;
  • session 文件;
  • 缓存文件;
  • 邮件队列;
  • 容器 overlay 层;
  • 临时目录未清理。

此时即使还有几十 GiB 空间,也可能报错:

No space left on device

13.5 稀疏文件

稀疏文件的逻辑大小可能远大于实际占用空间。

创建一个 10 GiB 稀疏文件:

truncate -s 10G sparse.img

查看逻辑大小:

ls -lh sparse.img

可能显示:

10G

查看实际占用:

du -h sparse.img

可能只显示:

0

查看:

stat sparse.img

可以对比:

  • Size
  • Blocks

因此:

  • ls -lh
     显示逻辑大小;
  • du
     显示实际分配空间。

十四、实战案例:Java 日志写满磁盘

14.1 故障现象

线上 Java 服务出现异常:

java.io.IOException: No space left on device

监控显示根分区使用率达到 95%。

日志目录:

/var/log/myapp

14.2 第一步:确认是哪个文件系统满了

df -hT

重点确认:

  • 哪个挂载点使用率高;
  • 文件系统类型;
  • 是否是根分区;
  • /var/log/myapp
     是否位于独立分区。

查看目标目录:

findmnt -T /var/log/myapp

不要看到 /var/log/myapp 就直接假设它一定属于根分区。

14.3 第二步:检查 inode

df -i

如果块空间未满,但 inode 使用率 100%,应重点排查大量小文件。

查找文件数量较多的目录:

sudo find /var/log -xdev -type f | \awk -F/ '{    path="";    for (i=1; i<NF; i++) {        if ($i != "") {            path=path "/" $i;        }    }    count[path]++;}END {    for (dir in count) {        print count[dir], dir;    }}' | sort -nr | head

生产环境目录很大时,应控制查找范围,避免产生较高 I/O。

14.4 第三步:定位大目录

先看一级目录:

sudodu -xhd1 /var | sort -h

继续深入:

sudodu -xhd1 /var/log | sort -h

再查看应用日志:

sudodu -xhd1 /var/log/myapp | sort -h

查找大文件:

sudo find /var/log/myapp -xdev -type f \    -printf'%s %p\n' |sort -nr |head -20 |numfmt --field=1 --to=iec

14.5 第四步:检查已删除文件

如果:

df -h

显示使用了 90 GiB,而:

du -shx /

只能统计到 50 GiB,应立即检查:

sudo lsof +L1

针对 Java:

sudo lsof -p "$(pgrep -f 'myapp.jar' | head -1)" +L1

也可以查看进程文件描述符:

sudols -l /proc/<PID>/fd

可能看到:

12 -> /var/log/myapp/app.log (deleted)

14.6 如何安全释放已删除文件占用

方案一:让应用重新打开日志

最规范的方式是:

  • 通过日志框架滚动机制重新打开日志;
  • 向进程发送支持的 reopen 信号;
  • 重启应用。

对于 Java 应用,是否支持信号重新打开日志,取决于日志框架和运行方式。

如果没有明确支持,重启服务通常最可靠:

sudo systemctl restart myapp

重启前应确认:

  • 服务是否支持重启;
  • 是否有流量切换;
  • 是否会造成业务中断;
  • 是否存在未处理任务。

方案二:通过文件描述符清空

如果暂时不能重启,可以对打开的文件描述符执行截断。

先确认文件描述符:

sudols -l /proc/<PID>/fd

假设文件描述符为 12:

sudotruncate -s 0 /proc/<PID>/fd/12

或者:

sudo sh -c ': > /proc/<PID>/fd/12'

该操作风险较高,执行前必须确认:

  • PID 正确;
  • fd 正确;
  • 文件确实是目标日志;
  • 应用允许日志被截断;
  • 不会截断数据库文件或其他重要文件。

14.7 不应简单认为 rm 和 truncate 完全等价

对于正在持续写入的日志文件:

rm app.log

删除的是目录项。

进程仍可能继续写入旧 inode。

而:

truncate -s 0 app.log

会将当前文件长度截断为 0,通常不会改变 inode。

因此,清理正在写入的日志时,通常优先考虑:

truncate -s 0 app.log

但更正确的长期方案不是人工清空,而是配置日志滚动。

十五、使用 logrotate 管理 Java 日志

假设日志文件:

/var/log/myapp/app.log

可以创建:

/etc/logrotate.d/myapp

配置示例:

/var/log/myapp/app.log {    daily    rotate 14    size 100M    compress    delaycompress    missingok    notifempty    copytruncate}

字段含义:

配置
作用
daily
每天检查
rotate 14
保留 14 个历史文件
size 100M
文件超过 100 MiB 时滚动
compress
压缩历史日志
delaycompress
延迟一轮压缩
missingok
文件不存在时不报错
notifempty
空文件不滚动
copytruncate
复制后截断原文件

测试配置:

sudo logrotate -d /etc/logrotate.d/myapp

强制执行:

sudo logrotate -f /etc/logrotate.d/myapp

15.1 copytruncate 的风险

copytruncate 的流程是:

  1. 复制当前日志;
  2. 截断原日志。

复制和截断之间存在很短的时间窗口,可能丢失少量日志。

因此,更推荐的方案是:

  • 应用自身滚动日志;
  • 日志框架主动切换文件;
  • 使用 journald;
  • 应用收到信号后重新打开日志文件。

Java 常见日志框架,如 Logback、Log4j2,通常都支持按日期和大小滚动。

例如 Logback:

<appendername="ROLLING"class="ch.qos.logback.core.rolling.RollingFileAppender"><file>/var/log/myapp/app.log</file><rollingPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>            /var/log/myapp/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>14</maxHistory><totalSizeCap>5GB</totalSizeCap></rollingPolicy><encoder><pattern>            %d{yyyy-MM-dd HH:mm:ss.SSS}            %-5level            [%thread]            %logger{36}            - %msg%n</pattern></encoder></appender>

相比人工删除日志,应用层滚动通常更可靠。

十六、动手实验:理解删除文件为什么不释放空间

下面实验建议在测试环境执行。

16.1 创建测试文件

mkdir -p /tmp/fs-labcd /tmp/fs-labddif=/dev/zero of=test.log bs=1M count=100

查看空间:

ls -lh test.logdu -h test.log

16.2 使用进程持续打开文件

执行:

tail -f test.log

保持该终端不关闭。

在另一个终端中查看:

pgrep -f 'tail -f test.log'

16.3 删除文件

rm /tmp/fs-lab/test.log

此时:

ls -l /tmp/fs-lab

文件已经消失。

但执行:

sudo lsof +L1 | grep test.log

仍可能看到:

tail ... /tmp/fs-lab/test.log (deleted)

说明文件仍被进程打开。

16.4 释放文件

停止 tail

Ctrl+C

再次检查:

sudo lsof +L1 | grep test.log

记录消失,文件空间才真正释放。

这个实验完整展示了:

删除目录项立即释放文件数据

十七、动手实验:观察 inode 和硬链接

创建文件:

cd /tmpecho"Linux filesystem" > inode-test.txt

查看 inode:

ls -li inode-test.txt

创建硬链接:

ln inode-test.txt inode-test-hard.txt

再次查看:

ls -li inode-test.txt inode-test-hard.txt

可以观察到:

  • inode 号相同;
  • 链接数从 1 变为 2。

删除原名称:

rm inode-test.txt

读取硬链接:

cat inode-test-hard.txt

内容仍存在。

查看链接数:

stat inode-test-hard.txt

链接数变回 1。

十八、动手实验:观察页缓存影响

创建测试文件:

ddif=/dev/urandom of=/tmp/cache-test.bin \    bs=1M count=1024 status=progress

第一次读取:

timecat /tmp/cache-test.bin > /dev/null

第二次读取:

timecat /tmp/cache-test.bin > /dev/null

第二次通常更快,因为数据可能已经进入页缓存。

查看内存:

free -h

Linux 中较大的 buff/cache 不一定代表内存浪费。

页缓存可以在应用需要内存时被回收,它是提升文件 I/O 性能的重要机制。

十九、开发人员必须理解的几个细节

19.1 write() 成功不等于物理落盘

普通写入通常先进入页缓存。

因此:

write() 返回成功

通常只说明数据已经被内核接受,并不一定已经到达持久化介质。

对于数据库、账务、订单等关键数据,应正确使用:

  • fsync()
  • fdatasync()
  • 事务日志;
  • WAL;
  • 数据库持久化配置。

19.2 文件重命名通常比复制更轻量

同一文件系统内执行:

mv old.log new.log

通常主要修改目录项,不需要复制文件内容。

但跨文件系统执行:

mv /data1/file /data2/file

通常相当于:

  1. 复制文件;
  2. 删除源文件。

判断两个路径是否属于同一文件系统:

df -h /data1/file /data2

或:

findmnt -T /data1/filefindmnt -T /data2

19.3 原子重命名是常见安全写入手段

许多程序更新配置文件时,会先写临时文件:

config.tmp

写入完成后执行:

mv config.tmp config.json

在同一文件系统中,rename() 通常具有原子性。

这样可以避免读取方看到只写了一半的文件。

但要获得严格持久化保证,还需要考虑:

  • 临时文件 fsync()
  • 目标目录 fsync()
  • 文件系统和挂载选项;
  • 崩溃恢复语义。

19.4 打开文件后,路径可以消失

进程打开文件后,主要通过文件描述符访问打开文件对象。

即使文件随后被:

  • 重命名;
  • 删除;
  • 原路径替换;

进程仍可能继续访问原来的 inode。

这对以下场景十分重要:

  • 日志滚动;
  • 配置热更新;
  • 临时文件;
  • 软件升级;
  • 数据库文件维护。

二十、常见认知误区

误区一:目录就是磁盘

错误。

目录只是文件系统命名空间中的节点。

它可能属于:

  • 根文件系统;
  • 独立分区;
  • LVM;
  • tmpfs;
  • NFS;
  • 容器 overlay 文件系统。

误区二:文件名存储在 inode 中

错误。

普通情况下,文件名保存在目录数据中,inode 保存文件元数据和数据映射。

误区三:删除文件后,数据立即消失

错误。

删除通常先移除目录项。

如果还有硬链接或打开引用,文件数据不会释放。

即使空间已释放,底层数据也不一定立即物理擦除。

误区四:df 和 du 应该完全一致

错误。

两者统计角度不同:

  • df
    :文件系统整体块使用情况;
  • du
    :目录树中可见文件的实际占用。

已删除文件、挂载遮挡、保留块等情况都会导致差异。

误区五:内存中的缓存越少越好

错误。

Linux 会利用空闲内存作为页缓存,以提高文件访问性能。

页缓存通常可以在需要时回收。

误区六:rm 大日志一定能释放空间

错误。

如果进程仍然打开日志文件,空间不会释放。

应结合:

lsof +L1

检查。

二十一、磁盘问题标准排查流程

遇到“磁盘满”时,可以按照以下顺序排查。

第一步:确认块空间

df -hT

确认:

  • 哪个文件系统满;
  • 挂载点是什么;
  • 文件系统类型是什么。

第二步:确认 inode

df -i

排除 inode 耗尽。

第三步:确认路径所属文件系统

findmnt -T /var/log

避免排查错分区。

第四步:统计大目录

sudodu -xhd1 / | sort -h

逐层深入:

sudodu -xhd1 /var | sort -hsudodu -xhd1 /var/log | sort -h

第五步:查找大文件

sudo find /var -xdev -type f \    -size +1G \    -printf'%s %p\n' |sort -nr |numfmt --field=1 --to=iec

第六步:检查已删除文件

sudo lsof +L1

第七步:检查挂载遮挡

findmntlsblk -f

必要时通过 bind mount 查看被遮挡目录。

第八步:检查特殊目录

重点关注:

/var/log/var/lib/docker/var/lib/containerd/var/lib/mysql/tmp/var/tmp/home/root

容器环境还应检查:

docker system df

但不要在不理解影响的情况下直接执行:

docker system prune -a

因为它可能删除未使用镜像、构建缓存和其他资源。

二十二、总结:真正需要掌握的核心模型

Linux 文件系统可以归纳为三条主线。

1. 文件访问链路

应用程序系统调用VFS页缓存具体文件系统块设备存储设备

2. 文件对象关系

文件名目录项 dentryinode数据块或 extent

其中:

  • 文件名负责命名;
  • dentry 负责名称映射;
  • inode 保存元数据;
  • 数据块保存真正内容;
  • file
     对象保存一次打开状态;
  • 文件描述符是进程访问打开文件的索引。

3. 磁盘接入目录树

磁盘分区或逻辑卷文件系统挂载点Linux 目录树

当你真正理解以下五个概念后,大多数 Linux 文件系统问题都会变得清晰:

  1. VFS;
  2. inode;
  3. dentry;
  4. 文件描述符;
  5. 挂载

它们可以解释:

  • 为什么同一套 API 能操作 ext4、XFS 和 NFS;
  • 为什么文件名不是文件本身;
  • 为什么硬链接共享数据;
  • 为什么删除文件后空间没有释放;
  • 为什么 df 和 du 结果不同;
  • 为什么挂载会遮挡目录;
  • 为什么普通写入成功不等于数据已经持久化;
  • 为什么日志滚动和数据库落盘需要特别设计。

Linux 文件系统的关键,不是记住所有命令,而是建立一套稳定的心智模型:

路径负责定位,目录项负责映射,inode 负责描述,页缓存负责加速,文件系统负责组织,块设备负责传输,存储介质负责保存。

*上层(路径、Dentry、Inode)管“在哪、是什么”——负责命名与描述。*中层(Page Cache、文件系统)管“怎么快、怎么存”——负责组织与加速。*下层(块设备、存储介质)管“怎么传、怎么留”——负责搬运与持久化。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 23:46:07 HTTP/2.0 GET : https://f.mffb.com.cn/a/507188.html
  2. 运行时间 : 0.157076s [ 吞吐率:6.37req/s ] 内存消耗:4,707.27kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=00da197e09c95dd6ef0f1af415877222
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000398s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000547s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000280s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000259s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000476s ]
  6. SELECT * FROM `set` [ RunTime:0.000199s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000496s ]
  8. SELECT * FROM `article` WHERE `id` = 507188 LIMIT 1 [ RunTime:0.000460s ]
  9. UPDATE `article` SET `lasttime` = 1787327167 WHERE `id` = 507188 [ RunTime:0.004851s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000255s ]
  11. SELECT * FROM `article` WHERE `id` < 507188 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.017948s ]
  12. SELECT * FROM `article` WHERE `id` > 507188 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.010508s ]
  13. SELECT * FROM `article` WHERE `id` < 507188 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.015440s ]
  14. SELECT * FROM `article` WHERE `id` < 507188 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.033089s ]
  15. SELECT * FROM `article` WHERE `id` < 507188 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004795s ]
0.158499s