Linux文件系统管理核心实战
Linux 文件系统基本管理深度剖析:设备识别、挂载排障与空间利用
引言
在 Linux 操作系统中,“一切皆文件”的理念不仅体现在常规数据上,更延伸到了硬件设备与存储介质。文件系统是操作系统管理存储设备上数据的“图书馆管理员”,它决定了数据如何被组织、存放和检索。对于运维人员而言,掌握文件系统的底层工作原理与核心管理工具,是日常排查磁盘空间爆满、文件丢失及挂载失败等生产故障的必备能力。
本文将基于课堂实战,深入讲解文件系统层面的设备识别、容量监控、挂载卸载原理、持久化配置,以及针对不同空间瓶颈的综合排障策略。
一、 识别文件系统与设备
1. 深入理解块设备与命名规则
在 Linux 中,所有硬件存储设备均以块设备文件的形式存在于 /dev 目录下。这里的“块”意味着数据以固定大小的块为单位进行读写。不同的硬件接口(SCSI/SATA、NVMe、虚拟化 VirtIO)对应着不同的设备命名前缀:
- SATA/SAS/USB(SCSI 子系统):
/dev/sda、/dev/sdb… - NVMe 固态硬盘:
/dev/nvme0n1、/dev/nvme1n1… - 虚拟机 VirtIO 磁盘:
/dev/vda、/dev/vdb… - SD/MMC 存储卡:
/dev/mmcblk0…
这些设备文件并不是真实的文件,而是设备节点。分区后,设备名会增加数字后缀:/dev/sda1(第一块硬盘的第一个分区),/dev/nvme0n1p1(NVMe 磁盘的第一个分区)。
2. lsblk 命令:获取块设备拓扑结构
lsblk 以树状结构清晰展示磁盘、分区、逻辑卷之间的层级关系,是查看设备架构的首选。
[root@server-xianyu ~ 18:47:26]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 199G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
└─centos-home 253:2 0 145.1G 0 lvm /home
sr0 11:0 1 4.4G 0 rom
字段深度解读:
- NAME:设备名称。
- MAJ:MIN:主设备号和次设备号。主设备号
8代表 SCSI 磁盘驱动,253代表 Device Mapper(LVM)。内核通过这些数字精确识别驱动程序。 - RM:可移除标记(
1代表可移动设备,如 U 盘或光驱,0为固定硬盘)。 - RO:只读标记。若为
1,则该设备只能读取(如光驱)。 - SIZE:容量大小。
- TYPE:类型(
disk磁盘、part分区、lvm逻辑卷、rom只读存储)。 - MOUNTPOINT:当前挂载的目录,空表示未挂载。
3. df 命令:监控文件系统空间使用率
df 是排查磁盘空间是否“爆满”的第一道防线。推荐配合 -h(易读单位)和 -T(显示文件系统类型)使用。
# 结合使用 -h(1024进制)和 -T
[root@server-xianyu ~ 18:47:30]# df -hT
文件系统 类型 容量 已用 可用 已用% 挂载点
devtmpfs devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs tmpfs 2.0G 13M 2.0G 1% /run
tmpfs tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 50G 4.9G 46G 10% /
/dev/mapper/centos-home xfs 146G 465M 145G 1% /home
/dev/sda1 xfs 1014M 174M 841M 18% /boot
tmpfs tmpfs 394M 8.0K 394M 1% /run/user/42
tmpfs tmpfs 394M 0 394M 0% /run/user/1000
-hvs-H:-h采用 1024 进制(1G=1024M),-H采用 1000 进制(1G=1000M),硬盘厂商常用 1000 进制,所以df -H显示的容量数字会比-h略大。- 如何确定某个目录落在哪个分区?:直接执行
df /tmp,系统会输出/tmp所在挂载点的对应信息。
4. du 命令:精准定位
如果发现根分区已使用 90%,需要立刻查出是哪个目录占用了空间,此时 du 登场。
# 查看 /boot 目录总占用
[root@server-xianyu ~ 18:52:09]# du -sh /boot
141M /boot
实战排查技巧(层层递进法):
在笔记案例中,为了找到消耗 4GB 空间的“罪魁祸首”,使用了组合拳:
# 1. 看根目录下谁最大
[root@server-xianyu ~ 18:55:50]# du -sk /* 2>/dev/null | sort -rn | head -n 5
8031628 /usr
1084276 /var
442608 /home
144312 /boot
43224 /etc
# 输出发现 /usr 最大(8031628 KB)
# 2. 深入 /usr
[root@server-xianyu ~ 18:55:55]# du -sk /usr/* 2>/dev/null | sort -rn | head -n 5
5638052 /usr/share
1214028 /usr/lib64
877648 /usr/lib
147552 /usr/bin
73856 /usr/libexec
# 输出发现 /usr/share 最大(5638052 KB)
# 3. 深入 /usr/share
[root@server-xianyu ~ 18:56:50]# du -sk /usr/share/* 2>/dev/null | sort -rn | head -n 5
4284696 /usr/share/doc
451260 /usr/share/locale
213252 /usr/share/help
122840 /usr/share/fonts
83908 /usr/share/icons
# 输出发现 /usr/share/doc 最大(4284696 KB)
# 4. 深入 /usr/share/doc
[root@server-xianyu ~ 18:57:21]# du -sk /usr/share/doc/* 2>/dev/null | sort -rn | head -n 5
4194316 /usr/share/doc/dhclient-4.2.5
4376 /usr/share/doc/gcc-4.8.5
1216 /usr/share/doc/postfix-2.10.1
1192 /usr/share/doc/python-kitchen-1.1.1
1060 /usr/share/doc/pam-1.1.8
# 最终定位到大文件:/usr/share/doc/dhclient-4.2.5/bigfile-4G(4194304 KB)
[root@server-xianyu ~ 18:57:51]# du -sk /usr/share/doc/dhclient-4.2.5/* 2>/dev/null | sort -rn | head -n 5
4194304 /usr/share/doc/dhclient-4.2.5/bigfile-4G
4 /usr/share/doc/dhclient-4.2.5/README.dhclient.d
4 /usr/share/doc/dhclient-4.2.5/dhclient.conf.example
4 /usr/share/doc/dhclient-4.2.5/dhclient6.conf.example
这种**“逐层剥离”**的策略,完美诠释了 Linux 的 KISS 原则(Keep It Simple, Stupid):把大任务拆解成小工具的组合,能极其高效地完成复杂排障。
二、 文件系统的挂载与卸载机制
要让文件系统的数据在 Linux 目录树中可见,必须先执行挂载(Mount)操作,即将其附加到一个称之为挂载点的空目录上。
1. 标准挂载 (mount 命令)
# 虚拟机添加一块硬盘sdb
[root@server-xianyu ~ 19:04:07]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 199G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
└─centos-home 253:2 0 145.1G 0 lvm /home
sdb 8:16 0 100G 0 disk
sr0 11:0 1 4.4G 0 rom
# 格式化文件系统
[root@server-xianyu ~ 19:04:14]# mkfs.xfs /dev/sdb
meta-data=/dev/sdb isize=512 agcount=4, agsize=6553600 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=26214400, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=12800, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
# 创建挂载点(必须是空目录)
[root@server-xianyu ~ 19:06:17]# mkdir /date
# 获取设备唯一标识(推荐使用 UUID 挂载,避免设备名变动)
[root@server-xianyu ~ 19:09:01]# blkid /dev/sdb
/dev/sdb: UUID="46526d63-5c6c-4e34-b33c-35cccbdee0fd" TYPE="xfs"
# 挂载
[root@server-xianyu ~ 19:12:01]# mount /dev/sdb /data
# 或者用 UUID:
[root@server-xianyu ~ 19:12:32]# mount UUID='46526d63-5c6c-4e34-b33c-35cccbdee0fd' /data
[root@server-xianyu ~ 19:13:02]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 199G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
└─centos-home 253:2 0 145.1G 0 lvm /home
sdb 8:16 0 100G 0 disk /data
sr0 11:0 1 4.4G 0 rom
底层补充:mount 命令实质是调用系统调用 mount(),将设备文件(/dev/sdb)与特定节点(/data)进行绑定。挂载后,mount 命令不加任何参数可以查看当前所有挂载点的详细状态,括号里会显示挂载选项(如 rw 可读写、relatime 相对更新时间、seclabel SELinux 安全标签等)。
2. 文件系统卸载 (umount 命令)
[root@server-xianyu ~ 19:15:21]# umount /data
# 或者 umount /dev/sdb
[root@server-xianyu ~ 19:16:39]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 199G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
└─centos-home 253:2 0 145.1G 0 lvm /home
sdb 8:16 0 100G 0 disk
sr0 11:0 1 4.4G 0 rom
注意:umount 后面必须跟挂载点或设备名其中之一,且必须保证当前工作目录不在挂载点内部。
3. 经典高频故障:“target is busy” 的排障方法
如果当前终端目录停留在 /data 目录下,卸载时会提示 target is busy。这是运维中极其高频的错误。
故障原因:有进程正在访问该目录内的文件(比如你正在 /data 里执行 ls 或者 tail -f)。此时需要定位进程并将其“赶走”。
-
方法一:使用
lsof(List Open Files)lsof /data会列出当前所有正在访问该目录或文件的进程。[root@server-xianyu ~ 19:17:45]# cd /data [root@server-xianyu data 19:17:48]# touch file-{1..3} [root@server-xianyu data 19:18:14]# ls file-1 file-2 file-3 [root@server-xianyu data 19:18:16]# umount /dev/sdb umount: /data:目标忙。 (有些情况下通过 lsof(8) 或 fuser(1) 可以 找到有关使用该设备的进程的有用信息) [root@server-xianyu data 19:18:33]# lsof /data COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 1872 root cwd DIR 8,16 48 64 /data lsof 2147 root cwd DIR 8,16 48 64 /data lsof 2148 root cwd DIR 8,16 48 64 /data输出解析:
COMMAND是bash,PID是 1508,FD=cwd表示当前工作目录就在/data。关闭该bash窗口或执行cd /离开该目录即可解决。 -
方法二:使用
fuser(识别并杀死进程)fuser -m /data不仅能识别,还支持快速清理。# 查看占用进程 [root@server-xianyu data 19:19:27]# fuser -m /data /data: 1872c # 末尾的 'c' 表示当前目录。如果确认该进程可以安全终止,可以执行
fuser -km /data发送SIGKILL信号直接杀掉占用进程,然后再执行umount /data。
三、 文件系统的持久化挂载(/etc/fstab)
手动挂载的分区在服务器重启后会失效,因此我们需要将其写入系统挂载配置文件 /etc/fstab,确保开机自动挂载。
/etc/fstab 六字段深度解析
该文件每一行代表一个挂载项,使用空格或制表符分隔成 6 个字段:
- 设备文件(Device):推荐使用
UUID(blkid可查),因为设备名/dev/sdb1可能会因为插拔或重启顺序改变而导致挂载失败。 - 挂载点(Mount point):须为系统上真实存在的空目录(如
/data01)。 - 文件系统类型(File system type):如
xfs、ext4、iso9660等。 - 挂载选项(Mount options):常用
defaults套件(包含rw、suid、dev、exec、auto、nouser、async)。 - Dump 备份标记:通常设为
0。若设为1,则dump命令会备份该文件系统。 - Fsck 检查顺序:
0:表示不检查。XFS 文件系统必须设为 0,因为 XFS 有自己的日志机制,不支持传统的fsck。1:表示优先检查(通常仅根分区/设置 1)。2:表示按顺序检查(用于其他 ext4 文件系统)。
配置实例与测试:
[root@centos7 ~]# blkid /dev/sdb1
/dev/sdb1: UUID="f5c35f10-0274-45af-b044-73694989fe01" TYPE="xfs"
# 向 /etc/fstab 追加条目(注意不要写错符号,必须空格分隔)
UUID="f5c35f10-0274-45af-b044-73694989fe01" /data01 xfs defaults 0 0
# 执行挂载测试(重要!):不重启,直接尝试挂载 fstab 中的所有条目
[root@centos7 ~]# mount -a
# 验证
[root@centos7 ~]# df -h /data01
四、 查找系统中的文件
1. locate:基于数据库的极速查找
locate 依托于系统定期维护的 mlocate 数据库(系统默认每天更新一次)。它的特点是查找速度极快,甚至可以做到毫秒级返回。但刚安装的软件包,如果不先手动执行 updatedb 刷新数据库,会查找不到。
-i:忽略大小写。-c:仅统计匹配数量。-r:使用正则表达式查找。
2. find:实时遍历的全能搜索
find 直接在文件系统目录树中实时遍历,虽然速度比 locate 慢,但能力最强,支持极其复杂的条件组合。
(1)按文件名(-name)与忽略大小写(-iname)
find /etc/ -name '*passwd*'
(2)按文件类型(-type)-type d 目录,-type f 普通文件,-type l 软链接。
(3)按文件所有者(-user / -uid)与属组(-group / -gid)
find / -user laoma
# 找无主文件(系统垃圾)
find / -nouser
(4)按文件权限(-perm)—— 三种模式解析(极易混淆)
- 精确匹配:
-perm 764,查找权限完全等于rwxrw-r--的文件。 - 最小匹配:
-perm -764,查找权限至少包含 ugo 对应位(u至少为7,g至少为6,o至少为4)的文件(比如 777 也能被匹配)。 - 任意匹配:
-perm /764,查找 ugo 其中任意一个满足对应最小位(u至少7,或g至少6,或o至少4)的文件。 - 实战巧用:
find / -perm -4000可快速找出所有带 SUID 权限(可能提权的程序)的文件,是安全排查常用手段。
(5)按文件大小(-size)与修改时间(-mmin / -mtime)
find -size +10M # 大于 10M
find -size -10k # 小于 10k
find -mmin -10 # 10分钟内修改过的
find -mtime +30 # 30天前修改过的
(6)逻辑关系与动作(-a、-o、!、-exec)
# 查找无主 或 无组的文件
find / -nouser -o -nogroup
# 找到文件后直接删除
find / -name "PASSWD" -delete
# 找到文件并复制到指定目录({} 代表找到的文件路径)
mkdir findfiles
find / -inum 67160130 -exec cp -a {} ./findfiles \;
(注:-exec 后的 \; 表示每条匹配执行一次命令,效率较低;但如果用 + 代替 \;,则将结果打包一次执行,效率大幅提升。)
五、 文件系统空间不足综合排障案例
在实际生产环境中,空间不足并不是单纯的“删个文件就行”,下面三种情况极其容易让人踩坑。
情况1:大量的大文件占据空间
现象:df -h 显示分区已 100%。
排查:使用 find /myapp-1/ -size +100M 快速定位超 100M 的文件。
处理:确认非业务文件后,直接 rm -f 删除。
情况2(经典陷阱):删除文件后,空间并没有释放
现象:明明执行 rm -f 删除了 2GB 的日志文件,但 df -h 显示磁盘依然是 100% 占用。
根因:该文件被某个进程(如 tail -f)一直打开着。在 Linux 内核中,删除目录项(硬链接)并不代表释放磁盘空间,只有 “文件的打开句柄(File Handle)被关闭”(即持有该文件的进程彻底退出),文件占用的磁盘块才会被系统真正回收。
排查与解决:
# 找出所有已删除但仍被打开的文件(标记为 (deleted))
[root@centos7 ~]# lsof | grep delete | grep /myapp-1
tail 1654 root 3r REG 8,17 2061565952 444 /myapp-1/etc/bigfile (deleted)
# 定位到进程 PID 为 1654,杀掉它
[root@centos7 ~]# kill 1654
# 再次查看 df,空间立即释放!
防范建议:运维清大文件前,习惯先执行 > /path/to/bigfile 清空文件内容,再 rm 删除,则可避免占用风险。
情况3(易被忽视的瓶颈):大量小文件耗尽 inode
现象:df -h 显示磁盘还有 900M 剩余空间,但 touch 创建新文件时报错 设备上没有空间。
原因:文件系统占满的不是数据块,而是索引节点(inode)。每个文件(无论大小 1KB 还是 1GB)都需要占用一个 inode 来记录文件的元数据(权限、位置、时间等)。当创建了海量小文件(比如 65,000 个空文件),inode 表会被彻底撑爆。
排查与解决:
# -i 参数查看 inode 使用情况
[root@centos7 ~]# df -hi /myapp-2
文件系统 Inodes IUsed IFree IUse% Mounted on
/dev/sdb2 64K 64K 0 100% /myapp-2
此时空间虽多,但无法继续创建文件。需将小文件合并(如 tar 打包、cat 拼接),或备份后删除这些小文件,释放 inode。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)