默认选ext4即可,但数据库、虚拟机镜像或大文件顺序读写等场景xfs更稳;web服务+中小mysql用ext4配noatime,data=ordered;postgresql/kvm/nfs后端优先试xfs并加大日志区。

ext4 还是 XFS?看 workload 类型再决定
默认选 ext4 没问题,但如果你跑数据库、虚拟机镜像或大文件顺序读写(比如视频转码),XFS 通常更稳。它对单个大文件的元数据操作更快,且不随目录项增多而明显变慢;ext4 在小文件高并发创建/删除时可能遇到 ext4_mb_generate_buddy:741: group 1023, block 8388608 类似警告——本质是块分配器压力大,不是崩溃,但会影响吞吐。
- Web 服务 + 中小数据库(MySQL 单实例):用
ext4,配noatime,data=ordered - PostgreSQL / KVM 镜像存储 / NFS 后端:优先试
XFS,mkfs 时加-l size=128m(日志区够大,避免日志满导致挂起) - 频繁
rm -rf大量小文件?XFS的xfs_repair -L是最后手段,但ext4的e2fsck -f更易预测行为
swap 分区要不要关?取决于内存压力模式
不是“有内存就关 swap”,而是看有没有突发性内存申请。kubernetes 节点或 Java 应用常因 GC 暂停期间触发大量匿名页分配,此时没 swap 容易直接 OOM kill;但纯计算型服务(如 ffmpeg 批处理)内存使用平滑,关掉 swap 反而减少内核 page reclaim 开销。
-
swappiness=1是折中选择:允许交换,但只在内存真正吃紧时才触发 - 用
zram替代磁盘 swap?仅当 SSD 寿命敏感且 CPU 有余量时考虑,压缩解压本身占 CPU,zram的disksize设太小会导致频繁压缩失败 - 检查是否真用到 swap:
cat /proc/swaps看大小,vmstat 1观察si/so列是否持续非零
挂载参数里 noatime 和 relatime 差在哪?
noatime 彻底禁用访问时间更新,对所有读操作都跳过 inode 修改;relatime(默认)只在 mtime/ctime 更新时同步 atime,或上次 atime 超过 24 小时才更新——既保兼容又减 IO。除非你运行依赖精确 atime 的备份工具(如某些 rsync 增量逻辑),否则别碰 strictatime。
-
noatime对数据库 WAL 日志目录无效:因为每次写都是O_SYNC或fsync(),atime 不会更新 -
relatime在容器场景下可能被覆盖:docker 默认用sharedmount propagation,宿主机改挂载参数未必生效,得进容器查findmnt / - 临时测试效果:
mount -o remount,noatime /home,再用stat /home/testfile对比 atime 变化
tmpfs 大小设多少才安全?别只看 free -h
tmpfs 占用的是可回收内存(page cache + slab),不是固定分配。设 size=2g 只是上限,实际用量看内容;但若应用疯狂往 /dev/shm 写临时文件又不删,可能把可用内存耗尽,触发 OOM。更危险的是:某些语言(如 Go 1.21+)默认用 /dev/shm 做 memfd,一旦满会导致 fork/exec 失败,报错 fork: Cannot allocate memory,而非直观的 “no space left on device”。
- 监控真实占用:
df -h /dev/shm看已用,但更要盯cat /proc/meminfo | grep Shmem——这是内核统计的 tmpfs 总用量 - 容器内限制:
docker run --shm-size=512m,别依赖宿主机默认值 - 关键路径别放 tmpfs:比如 PostgreSQL 的
pg_stat_tmp目录若挂 tmpfs,重启后丢失统计信息,影响 autovacuum 判断
文件系统不是配完就完的事,最麻烦的是混合负载——比如同一块盘既存数据库 WAL 又跑 CI 构建缓存,这时候 ionice 和 blkio.weight 的调控比选什么 fs 更关键。