1. 从一次启动调试说起:三种文件系统为什么会同时出现
说个我最近的经历。一台嵌入式的设备,存储用的是NVMe硬盘,分区表是GPT,其中一个分区格式化成NTFS,里面塞了一个squashfs格式的根文件系统镜像。引导用的U-Boot,启动参数里要通过bootargs把root指向这个镜像。折腾了一下午,最后发现坑全在文件系统之间的“沟通”上——U-Boot要能从NTFS分区里读出内核和initramfs,内核要能通过loop设备挂载squashfs镜像,而镜像内部可能还有一层只读文件系统的讲究。
这套组合听起来杂,但实际上代表了三种完全不同的设计哲学:EROFS是专门为只读场景从零设计的,NTFS是微软带着历史包袱一路升级上来的,XFS则是老牌64位日志文件系统里“稳”字的代名词。把这三个放一起聊,不是搞什么文件系统大乱斗,而是因为越来越多的实际项目里,它们确实会同时出现,而且各自负责的环节完全不同。
这篇文章就把我在这类组合场景里摸出来的经验展开讲讲。适合谁看?嵌入式开发、系统运维、还有那些在Linux和Windows/macOS之间反复横跳的桌面用户。看完你至少能搞明白三件事:EROFS和squashfs到底怎么选;NTFS在Linux内核里的读写为什么一直是个敏感话题;以及XFS的“高吞吐”到底是用什么代价换来的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. EROFS:只读场景下比 squashfs 更值得关注的选择
2.1 EROFS的定位与核心优势
先聊EROFS。这个名字是Enhanced Read-Only File System的缩写,华为2018年开源,Linux内核5.4版本合入主线。它诞生的背景很明确:Android系统里那个/system分区是只读的,传统上用ext4只读挂载,但ext4本身不是为只读设计的,元数据开销、碎片问题、挂载时间都不理想。EROFS就是冲着“只读场景下的极致性能”去的。
它有几个很实在的特点:
- 块内去重与尾部打包:小文件在传统文件系统里会浪费大量尾部空间,EROFS会把多个小文件的尾部合并到一个物理块里,减少空间浪费。
- 多策略压缩:支持固定大小压缩和逐块压缩,压缩算法可叠加,比如LZ4负责速度,LZMA负责极限压缩比。
- 挂载即用:不需要
fsck,也不需要日志,因为它是只读的,不存在崩溃恢复的问题,挂载开销极小。
拿它和squashfs比,squashfs是老牌只读文件系统,LiveCD、Docker镜像、嵌入式固件里到处都是它的身影。但squashfs有个问题是它依赖内核的mtd或loop设备,而且小文件的随机读取性能一直一般。EROFS在随机读场景下,尤其是大量小文件的顺序遍历,性能明显比squashfs好,压缩率也不输。
2.2 EROFS的实际部署方式
我自己在实际项目里,通常用两种方式把EROFS用起来:
方式一:直接作为系统分区
bash复制mkfs.erofs -zlz4hc /dev/sda1 ./rootfs/
mount -t erofs /dev/sda1 /mnt
这里的-zlz4hc表示用LZ4HC算法压缩,压缩率高且解压速度快。如果你的存储比较紧张,可以换-zlzma,压缩率更高,但解压会慢一些。
方式二:EROFS镜像作为启动镜像
bash复制mkfs.erofs rootfs.erofs ./rootfs/
然后在bootargs里这样指定:
code复制root=/dev/ram0 rw
或者配合initramfs,在启动脚本里做loop挂载:
bash复制mount -t erofs -o loop rootfs.erofs /sysroot
2.3 为什么说EROFS被低估了
很多人觉得EROFS是Android专属,其实不然。它对嵌入式Linux、容器镜像、只读根文件系统场景都适用。相比squashfs,EROFS的挂载速度更快,随机读更稳,还不依赖mtd设备。如果你的存储设备支持随机读但带宽一般,EROFS往往比squashfs更适合。
这里有个细节要提醒:EROFS不支持写操作,这是设计使然。所以如果你的场景里根文件系统需要某些运行时写入(比如/var、/tmp),得用overlayfs或者tmpfs把这些目录单独叠上去。这一点在用EROFS做rootfs时特别重要,否则你会在启动后遇到各种“read-only file system”的报错,然后一脸懵。
3. grub 和 bootargs 里把 rootfs 指向 NTFS 盘下的 squashfs:我踩过的坑
3.1 这个需求是从哪来的
先把这个场景说清楚。有些设备出厂是Windows镜像,硬盘分区是NTFS,你不想重新分区(可能因为引导方式受限,或者要保留Windows恢复分区),只想在某个NTFS分区里塞一个Linux根文件系统镜像,然后从它启动。这个需求听着小众,但真遇到了也挺折腾。
启动链路大概是这样的:
- BIOS/UEFI加载GRUB或U-Boot。
- Bootloader从NTFS分区读取内核(vmlinuz)和initramfs。
- 内核启动,initramfs里的脚本负责挂载NTFS分区,找到squashfs镜像,loop挂载它,然后switch_root。
每一步都有各自的坑。
3.2 Bootloader读NTFS:GRUB的ntfs模块
GRUB本身支持NTFS读取,这是最关键的。确认你的GRUB有ntfs模块:
bash复制grub-mkstandalone --format=x86_64-efi --modules="part_gpt ntfs squashfs loopback" -o grub.efi /boot/grub/grub.cfg
这里的loopback模块也一定要有,因为如果你的squashfs镜像本身也在NTFS分区里,GRUB可以直接用loopback挂载它,顺便把内核和initramfs都从镜像里读出来。
grub.cfg里这样写:
code复制set root=(hd0,gpt2)
loopback loop /images/live.squashfs
linux (loop)/boot/vmlinuz root=/dev/disk/by-label/ROOT ro
initrd (loop)/boot/initrd.img
注意,loopback loop这个命令会在GRUB环境里创建一个虚拟设备(loop),它指向的其实是那个squashfs镜像。内核和initramfs都从这个虚拟设备里读。这个功能很实用,GRUB的squashfs驱动支持只读读取,不需要你提前解压镜像。
但这里有个坑:GRUB的NTFS驱动只读,而且不支持NTFS压缩文件。如果你的内核或镜像文件在NTFS分区里是被压缩的(Windows默认会压缩某些文件),GRUB会直接报错。处理办法就一个:把内核和initramfs复制到NTFS分区时,确保文件不压缩。用Windows的话,右键文件属性,把“压缩内容以便节省磁盘空间”的勾去掉。
3.3 initramfs里的NTFS支持:这是最容易翻车的地方
GRUB把内核加载起来后,接力棒交给内核和initramfs。有些发行版的initramfs默认不带NTFS驱动,你需要自己加。
以Debian/Ubuntu的initramfs-tools为例:
bash复制echo "ntfs3" >> /etc/initramfs-tools/modules
echo "squashfs" >> /etc/initramfs-tools/modules
update-initramfs -u
内核5.15开始有ntfs3驱动,这是目前Linux内核里对NTFS支持最完整的内核态驱动,读写都支持。注意别用老的ntfs驱动,那个模块读写能力都非常差,官方都把它标成过时了。
如果你的发行版内核比较老,只能用ntfs-3g(用户态FUSE)。那initramfs里必须有/usr/bin/ntfs-3g和对应的libntfs-3g.so,并且启动脚本要能用它挂载NTFS分区。这个比ntfs3驱动麻烦得多,建议直接升级内核。
3.4 bootargs的正确姿势
拿U-Boot为例,bootargs是U-Boot传给内核的参数。假设你的NTFS分区在/dev/nvme0n1p2,squashfs镜像在里面,bootargs可以这样配:
code复制setenv bootargs "root=/dev/nvme0n1p2 ro rootfstype=ntfs3 rootflags=loop=/images/root.squashfs"
但这里有一个很隐蔽的问题:内核的根文件系统挂载逻辑不直接支持“挂载NTFS分区后,再loop挂载里面的镜像”这种两级操作。rootflags=loop=参数要求root指向的块设备必须是真实块设备,而且内核要先挂载这个设备,再去loop挂载里面的文件。但NTFS3驱动能不能在initramfs阶段之前处理这个,取决于你的内核配置。
更可靠的做法是:initramfs里做两级挂载。在initramfs的init脚本里手动执行:
bash复制mkdir -p /newroot
mount -t ntfs3 /dev/nvme0n1p2 /mnt/ntfs
mount -t squashfs -o loop /mnt/ntfs/images/root.squashfs /newroot
exec switch_root /newroot /sbin/init
这样链路清晰,每一步都能看到报错,也方便排查。bootargs里只需要:
code复制setenv bootargs "rdinit=/rootfs-init.sh"
然后把你写好的init脚本放进initramfs里。
3.5 我踩过的几个具体坑
- GRUB的
insmod ntfs只支持到NTFS 3.1的基本读取,如果Windows开启了BitLocker加密,那就别想了,GRUB读不出加密分区,直接放弃这条路。 - NTFS分区如果是动态磁盘(LDM),GRUB认不出。Windows默认基础磁盘没问题,但有些厂商出厂会有恢复分区,可能不是基础磁盘,这个注意提前看存储拓扑。
- initramfs里把
ntfs3编译成模块,而不是内建,会导致init脚本挂载NTFS失败,因为模块在/lib/modules目录下,而那个目录本身就在你要挂载的rootfs里,形成依赖循环。解决方式很简单:把ntfs3编译进内核(CONFIG_NTFS3_FS=y),或者确认你的initramfs里包含了对应模块。 switch_root之前需要umount掉initramfs的/proc、/sys、/dev,否则新rootfs挂载后会有各种奇怪问题。这个不是NTFS特有的,但很多人会忘。
4. NTFS 在 Linux 和 macOS 下的读写困局:不是不想支持,是历史包袱太重
4.1 为什么NTFS的写支持一直是个敏感话题
搜索引擎里常出现“mac无法写入ntfs硬盘”“ntfs为什么要安全工具”这类问题。要回答这个,得先理解NTFS这个文件系统的复杂度。
NTFS从Windows NT 3.1时代(1993年)开始用,它不是一个简单的文件系统。它有:
- 主文件表(MFT):整个文件系统的核心索引,所有文件和目录的元数据都记录在MFT里。
- 日志($LogFile):用于事务回滚,保证系统崩溃后文件系统的一致性。
- USN Journal:记录所有文件变更,用于索引服务和备份工具。
- ADS(Alternate Data Streams):文件可以携带多个数据流,Windows用来存Zone.Identifier之类的元信息。
- 稀疏文件、压缩、加密(EFS):这些都是Windows独有的特性,Linux和macOS都没法百分百兼容。
麻烦就出在这。你要写一个文件,不只是把数据写到磁盘那么简单,你还得维护MFT、日志、USN journal,否则Windows下次开机可能直接报磁盘错误,甚至要求运行chkdsk。
Linux内核的ntfs驱动(老的那个)只读且能力有限,但它是内核自带的,很多人以为mount一下就能用。ntfs-3g是用户态FUSE,通过libntfs-3g实现完整读写,但它是用户态,性能比不上内核态,而且对日志和元数据的处理也并非100%兼容所有NTFS版本。内核5.15引入的ntfs3是Paragon贡献的,性能接近Windows原生驱动,是目前Linux下最好的选择。
4.2 Linux下到底怎么安全读写NTFS
结论先行:能用内核的ntfs3就尽量用ntfs3,用不了再考虑ntfs-3g。
挂载方式:
bash复制# 内核ntfs3驱动
mount -t ntfs3 /dev/sdb1 /mnt/windows
# 用户态ntfs-3g
mount -t ntfs-3g /dev/sdb1 /mnt/windows
如果要保证Windows下次启动不会出问题,有几个关键点:
- 卸载时一定要umount,不能直接拔盘。NTFS的日志机制依赖正常卸载来更新
$LogFile,直接断电会导致日志缺失,Windows启动时chkdsk是免不了的。 - 挂载时加
norecover参数可以跳过日志恢复,但这是有风险的,最好别用。 - 避免在NTFS分区上跑数据库或虚拟机镜像,这些写入太频繁,而且对文件锁、数据同步要求极高,NTFS在非Windows平台上的实现没法保证这种级别的可靠性。
其实“ntfs为什么要安全工具”这个问题,答案就在日志机制上。NTFS的写操作是事务性的,先写日志,再写数据。如果在日志没完全落盘时断电,理论上下次挂载时要回放日志才能恢复一致状态。Linux的ntfs3和ntfs-3g都有自己的日志处理逻辑,但实现和Windows原生驱动还是有细微差异。安全工具(或者叫安全卸载工具)本质上是帮你确保日志状态正确、干净卸载,而不是什么玄学。
4.3 macOS读写NTFS的免费方案
macOS原生对NTFS只读,这个很多人吐槽过。原因是微软没有授权苹果使用NTFS读写技术,苹果为了避免专利风险,只做了只读支持。
免费的方案有两条路:
方案一:内核扩展驱动
比如早期的ntfs-3g for Mac就是FUSE方案,需要安装macFUSE然后装ntfs-3g。装上之后:
bash复制sudo mkdir -p /Volumes/NTFS
sudo /usr/local/bin/ntfs-3g /dev/disk2s1 /Volumes/NTFS -olocal -oallow_other -oauto_xattr
不过macOS的SIP(System Integrity Protection)会限制内核扩展的安装,新版本macOS里FUSE方案越来越难搞,系统升级一次可能就失效一次。
方案二:用户态文件系统(FUSE)的现代实现
现在更多人用的是mounty这类工具,它本质上是调用macFUSE加载ntfs-3g。免费、图形化界面,装完自动挂载。但它的缺点和FUSE方案一样,受系统更新影响大,性能也没法和原生比。
我的建议是:如果你只是偶尔读一下NTFS移动硬盘,用macOS原生只读就够,没必要折腾。如果你经常要在Windows和macOS之间传文件,最省心的方案是把移动硬盘格式化成exFAT,这是微软和苹果都官方支持读写的格式,没有NTFS那些历史包袱。
4.4 一个真实案例:NTFS移动硬盘在mac上“消失”了
有个朋友拿NTFS移动硬盘插到MacBook上,磁盘工具能看到盘,但Finder里死活不显示。他以为是硬盘坏了,拿回来Windows上一查,一切正常。
这个现象的原因:macOS对NTFS分区是只读挂载的,但如果分区里有Windows的“快速启动”残留的休眠文件(hiberfil.sys),或者NTFS日志不是干净状态,macOS有时会拒绝自动挂载。这不是什么玄学,是macOS在保护分区一致性。
处理办法:
- Windows里正常关机(不要用快速启动),让NTFS日志干净。
- 插回Mac,看系统日志:
bash复制log show --last 5m | grep -i ntfs
- 如果确实没自动挂载,手动mount试试,一般能挂上。
这个案例说明,NTFS在跨平台场景里的很多问题不是“驱动不好”,而是Windows自己的快速启动和休眠机制会让NTFS分区处于非干净状态。理解这个原理,排查问题就有方向了。
5. XFS:高吞吐背后的取舍,以及被吐槽多年也不改的两个点
5.1 XFS的设计哲学
XFS最初是SGI为IRIX系统开发的64位日志文件系统,2001年移植到Linux。它的核心设计目标是高扩展性和高吞吐量,支持超大文件(最大8EiB),元数据操作通过B+树索引,写性能在顺序大文件场景下非常优秀。
这也是为什么RHEL/CentOS 7之后把XFS设为默认文件系统,因为它更适合企业级的大文件存储、虚拟化镜像和高性能计算场景。
它的几个值得说的特性:
- 延迟分配(Delayed Allocation):写入数据时先不分配物理块,而是缓存在内存里,凑够一定量再一次性分配。这样能减少磁盘碎片,提高写入吞吐。
- 动态inode分配:不像ext4那样格式化时固定inode数量,XFS的inode是动态分配的,所以即使你存了大量小文件,也不会因为inode耗尽而报错(当然前提是磁盘空间够)。
- 写时分配(Speculative Preallocation):文件写入时会在末尾预分配一小段空间,避免频繁追加时反复查找空闲块。
5.2 XFS被吐槽的两个点,我也觉得该吐槽
第一,删除大量小文件的速度很慢。
这是个真实的痛点。你往XFS里写入一万张缩略图什么的,删除时你会发现进度条走得跟树懒一样慢。原因在于XFS的inode是动态分配的,删除文件时不仅要释放数据块,还要回收inode,而inode分配和回收都是B+树操作,大量小文件的删除会变成大量随机I/O。
我实测过:ext4删除十万个小文件,大概几秒;XFS删除同样数量,耗时可能是几倍甚至更多。所以,如果你的目录结构会有海量小文件频繁创建和删除,XFS不是好选择,考虑ext4或f2fs(闪存设备)更靠谱。
第二,XFS不能在线收缩。
这一点是设计层面决定的。XFS格式化时会把空间划分为多个AG(Allocation Group),每个AG内部管理自己的空闲空间。收缩文件系统需要跨AG移动数据,这在线做几乎是灾难,所以XFS的设计者干脆不支持在线收缩。
这意味着:做规划时一定要留足余量。一旦分区空间不够,你的选择只有:加新盘、迁移数据重建分区、或者用xfsdump/xfsrestore把数据导出来重新分区再导回去。没有第三条路。
5.3 什么情况下我会选XFS,什么情况下弃用
选XFS的场景:
- 大文件为主:视频监控存储、数据备份、虚拟化镜像文件(raw/qcow2)。
- 顺序读写为主:日志集中存储、数据库的WAL日志(如果数据库本身对fsync要求很高,XFS的延迟分配可能带来意外延迟,需要注意)。
- 分区规划完成后基本不再调整:没有缩容需求。
弃用XFS的场景:
- 大量小文件的频繁增删:比如编译缓存、代码仓库、邮件存储。
- 需要在线扩容缩容:尤其是容器环境里,存储做动态分配。
- 对延迟极度敏感但设计无法保证的随机读场景:虽然XFS随机读不差,但ext4在有些测试里还是略占优。
5.4 XFS在企业存储组合里的角色
XFS在系统里的角色,其实跟EROFS和NTFS完全不冲突。一个典型的服务器场景是:
/根分区:XFS(RHEL默认)/home或/data:XFS- 备份镜像:XFS归档后用squshfs压缩,节省空间
- 跨平台数据交换盘:NTFS移动硬盘
有意思的地方在于,这三种文件系统各管一摊,互不干扰,但它们背后的维护工具链却可以串起来用。比如,你可以用xfsdump备份一个XFS分区的数据,然后把备份镜像做成squashfs/EROFS放在NTFS分区里用于折腾,或者反过来,把Windows下的数据打包成一个XFS镜像在虚拟机里使用。
5.5 几个XFS的实操小技巧
查看文件系统信息:
bash复制xfs_info /dev/sda1
在不重新挂载的情况下查看AG信息:
bash复制xfs_db -c "agf 0" -c "p" /dev/sda1
用xfs_repair时要小心:XFS的修复工具不像ext4的fsck那么温和,如果文件系统损坏不是日志级别的,xfs_repair -L(清空日志修复)可能会丢失未刷盘的数据。务必先做镜像备份再修:
bash复制xfs_repair -n /dev/sda1 # 先dry-run看看问题范围
xfs_repair -L /dev/sda1 # 确认后再真正修复
设置挂载参数优化性能:
bash复制mount -t xfs -o noatime,allocsize=64m,logbsize=32k /dev/sda1 /data
allocsize预分配大小很重要,如果应用是顺序写入大文件,这个参数能显著提升吞吐。logbsize是日志缓冲区大小,日志I/O频繁的场景可以提高。
6. 三者在同一台设备上的协作思路
6.1 一个典型的混合存储方案
很多人觉得把NTFS、squashfs/EROFS、XFS混在一起用是没事找事,但在某些场景里,这套组合反而是最优解。
我举个例子:一台工业控制设备,出厂时预装Windows,但实际运行的是定制Linux系统。硬盘分区如下:
| 分区 | 格式 | 内容 |
|---|---|---|
| /dev/sda1 | EFI | 引导文件 |
| /dev/sda2 | NTFS | 用户数据、Windows系统备份 |
| /dev/sda3 | NTFS | Linux根文件系统镜像(EROFS或squashfs) |
| /dev/sda4 | XFS | Linux运行时的写存储(/var、/data) |
启动时:BIOS → GRUB(从NTFS分区读内核)→ 内核挂载NTFS分区 → loop挂载EROFS镜像作为rootfs → 将XFS分区作为可写overlay层。
这个方案的逻辑是:
- EROFS只读镜像保证系统完整性,就算用户乱删乱改,重启即修复。
- NTFS保留了Windows兼容性,维护人员可以用Windows工具备份分区。
- XFS提供了高性能的写存储,所有运行时写入都在这个分区。
这个方案听起来复杂,但实际用起来很稳。
6.2 EROFS + overlayfs + XFS 的组合配置
如果你决定用EROFS做只读根文件系统,XFS做可写层,配置其实是这样的:
bash复制# 假设/dev/sda3是EROFS镜像,/dev/sda4是XFS
mkdir -p /mnt/ro /mnt/rw /mnt/merged
mount -t erofs /dev/sda3 /mnt/ro
mount -t xfs /dev/sda4 /mnt/rw
mount -t overlay overlay -o lowerdir=/mnt/ro,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work /mnt/merged
overlayfs是Linux内核自带的联合文件系统,它把只读层和可写层合并成一个视图。对上层应用来说,看到的是一个普通的可写文件系统,实际上写操作全部落在XFS的upperdir里。
这个组合的好处是:
- 系统升级:只需替换EROFS镜像,不动XFS分区。
- 系统修复:删除upperdir数据,即恢复出厂状态。
- 写性能:overlayfs的写开销很小,XFS的高吞吐优势能直接体现。
6.3 坑:overlayfs和XFS的页缓存问题
overlayfs + XFS的组合有一个坑,那就是页缓存(page cache)的回收问题。当上层的写密集场景触发大量page cache,而底层EROFS的只读数据也要占用page cache时,内存压力会比较大。尤其是EROFS的压缩块数据,解压后会缓存在页缓存里,如果机器内存不多,会发现频繁换页。
这个问题的缓解办法:
- 内核参数里调低
vfs_cache_pressure,让内核更倾向于保留inode缓存而不是回收。 - EROFS挂载时加上
compress_hints=all之类的参数,让压缩数据尽量在I/O路径上早压缩早释放。 - 如果内存真的很紧张,干脆把EROFS的压缩算法换成LZ4,解压速度快,缓存压力反而小,虽然压缩率低一点。
6.4 备份与恢复:三种文件系统的备份工具链
混合存储方案里,备份策略也要分开:
| 分区 | 备份方式 | 说明 |
|---|---|---|
| NTFS | 直接复制文件 | 或用ntfsclone做镜像备份 |
| EROFS | 直接保存镜像文件 | 因为本身是只读的,备份只需复制一份 |
| XFS | xfsdump |
在线备份,支持增量 |
XFS的在线备份我用得最多,因为运行时写入不能停:
bash复制xfsdump -l 0 -f /mnt/backup/data.dump /mnt/data
-l 0是全量备份,之后每天的增量备份:
bash复制xfsdump -l 1 -f /mnt/backup/data.dump1 /mnt/data
恢复时:
bash复制xfsrestore -f /mnt/backup/data.dump /mnt/data
这套链路在混合存储场景里非常顺手,因为NTFS分区里的系统镜像、EROFS分区里的只读系统、XFS分区里的运行数据,三者独立备份,恢复时互不影响。
7. 最后再分享几个血泪教训
关于这一整套文件系统的体会,最后再补充几个具体经验。
第一个教训:不要在NTFS分区上做overlayfs的upperdir。NTFS的元数据操作效率远不如XFS和ext4,而且日志机制带来的额外开销会让overlayfs的每次写操作都变慢。我一开始图省事,把upperdir直接放在NTFS分区上,结果做编译任务时写入速度惨不忍睹。后来挪到XFS分区,性能恢复正常。这其实也说明了,NTFS适合数据交换,不适合系统运行。
第二个教训:EROFS镜像生成工具链一定要熟。我一开始担心EROFS没法在运行时打包,后来发现它的工具链其实很成熟。在编译机上生成镜像再拷贝到目标设备,或者直接在目标设备上生成,都可以。
bash复制mkfs.erofs -zlz4hc -d2 rootfs.erofs ./rootfs/
生成后的镜像是单文件,放到NTFS分区里没有压力。复制镜像时注意用cp --sparse=always保持稀疏文件属性,避免把空洞也写进NTFS分区,浪费磁盘和写入时间。
第三个教训:XFS分区跑数据库要格外小心。XFS的延迟分配特性在数据库的fsync场景下,可能带来比ext4更明显的延迟抖动。如果你要跑PostgreSQL或MySQL,XFS不是不能用,但挂载参数要调整,关闭延迟分配,或者干脆用ext4。这个坑是真的要注意,我在一个监控服务上吃过亏,数据库写入延迟时不时飙到几百毫秒,排查到最后发现就是XFS的延迟分配和日志刷盘的相互作用导致的。
第四个教训:macOS上读取NTFS时,不要直接往盘里写文件,就算你装了ntfs-3g或mounty,也尽量不要在盘里直接修改现有文件。用户态驱动的日志回放和Windows原生驱动始终有差异,在盘里频繁修改文件,早晚会遇到一次“Windows提示你的磁盘需要修复”。文件拷出来,在本地改完再拷回去,这个习惯能让你远离这种麻烦。
这套“EROFS + NTFS + XFS”的混合组合,看起来像拼凑,但每一种都在它自己的位置上发挥着不可替代的作用。我把这些经验写下来,希望对那些正在折腾或者即将折腾这套方案的同行有帮助。
