文件系统深入:inode、软硬链接与高效查找
文件系统深入:inode、软硬链接与高效查找
文件系统相关的故障往往最反直觉:df -h 明明有空间却写不进去、删了大文件空间却没变、文件名带特殊字符删不掉。这篇从 inode 机制讲起,把这类问题的原理和解决办法收在一起。
一、inode:文件系统里最被低估的概念
文件在磁盘上分两部分:inode(存放元数据:权限、属主、大小、指向数据块的指针)和数据块(真正的内容)。文件名只是 inode 的一个”门牌”。
1 | ls -i 文件名 # 查看 inode 号 |
经典故障:磁盘有空间但写不进去。df -h 还剩 20G,但建文件报 No space left on device——查 df -i,IUse% 100%,全是小文件把 inode 耗尽了。定位小文件最多的目录:
1 | find /data -type f | cut -d/ -f3 | sort | uniq -c | sort -nr | head -10 |
清理或归档这些小文件(通常是日志、缓存、临时文件)即可恢复。inode 或磁盘空间任意一个满,磁盘都无法写入。
二、软链接 vs 硬链接
1 | ln 源文件 硬链接 # 硬链接:共享同一个 inode |
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| inode | 相同 | 不同 |
| 删除源文件 | 链接依然有效 | 链接失效(红底白字) |
| 跨文件系统 | 不可以 | 可以 |
| 目录 | 不可以 | 可以 |
生产中最常用的其实是软链接三件事:
- 保持路径不变,解决磁盘不够:数据迁到大盘,软链回原路径,应用无感知;
- 代码上线:
current -> release-20230510,切换即回滚; - 去软件版本号:
/usr/local/mysql -> mysql-5.7.42。
三、find:高段位用法
1 | # 基本:名称/类型/深度 |
面试和生产都高频的经典题——删 7 天前的日志:
1 | find /var/log -type f -mtime +7 -exec rm -f {} \; |
文件名带空格、特殊字符时用 -print0 + xargs -0 安全处理:
1 | find . -name "*.log" -print0 | xargs -0 rm |
四、权限规范:三个”绝不做”
- 绝不做
chmod 777:任何场景都不给全权限,最小权限原则是底线(面试问到”为什么不用 777”就答这条); - 绝不拿
-R递归改系统目录:chmod -R/chown -R只准作用于业务目录,误改/etc、/bin会直接搞崩系统; - 服务文件权限匹配运行用户:nginx 文件归
nginx:nginx、mysql 文件归mysql:mysql,这是服务能正常读写的前提。
常规权限速查:644 配置文件、755 脚本/目录、600 敏感文件、750 业务私密目录。
1 | chown -R nginx:nginx /usr/local/nginx/html # 部署后必做:属主属组对齐 |
五、一次”空间不释放”排查实录
现象:删了几个 G 的大日志,df -h 空间一点没变。
排查:
lsof | grep deleted→ 找到被删除但仍被进程持有的文件,确认真凶是正在写日志的 java 进程;- 直接重启进程会导致应用短暂中断(不可取)——生产做法:
> /proc/<pid>/fd/<句柄号>清空句柄指向的内容,空间立即释放,应用无感知; - 事后把”日志按天切割 + logrotate 轮转 + 保留 7 天”写进规范,从根上避免大日志长期占用。
文件系统的坑大多是”原理没吃透 + 操作不规范”叠加出来的,把 inode、链接、权限这三块理解透,排障时基本能一眼定位。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LuminDream's Blogs!


