XFS
XFS 是 Silicon Graphics, Inc. 创建的高性能日志文件系统。由于其基于分配组的设计,XFS 在并行 IO 方面尤其出色。当跨越多个存储设备时,这使得 IO 线程、文件系统带宽、文件和文件系统大小具有极高的可扩展性。
准备工作
对于 XFS 用户空间实用程序,安装 xfsprogs 软件包。它包含管理 XFS 文件系统所需的工具。
创建
要在设备上创建新文件系统,请使用
# mkfs.xfs device
示例输出
meta-data=/dev/device isize=256 agcount=4, agsize=3277258 blks = sectsz=512 attr=2 data = bsize=4096 blocks=13109032, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal log bsize=4096 blocks=6400, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
- 可以选择使用
-L label
选项为文件系统分配标签。 - 在包含现有文件系统的块设备上使用 mkfs.xfs 时,添加
-f
选项以覆盖该文件系统。[3]。此操作将销毁先前文件系统中包含的所有数据。
校验和
xfsprogs 3.2.0 引入了一种新的磁盘格式 (v5),其中包括名为 自描述元数据的元数据校验和方案。它基于 CRC32,可提供额外的保护以防止元数据损坏(例如,意外断电时)。当使用 xfsprogs 3.2.3 或更高版本时,校验和默认启用,但可以使用 -m crc=0
开关在调用 mkfs.xfs(8) 时禁用(对于在旧内核上进行读写挂载是必要的)
# mkfs.xfs -m crc=0 /dev/target_partition
从 Linux Kernel 3.15 开始,XFS v5 磁盘格式被认为是生产工作负载稳定的。
空闲 inode btree
从 Linux 3.16 开始,XFS 添加了一个 btree,用于跟踪空闲 inode。它等效于现有的 inode 分配 btree,不同之处在于空闲 inode btree 跟踪至少有一个空闲 inode 的 inode 块。其目的是改进 inode 分配的空闲 inode 集群的查找。它可以提高老化的文件系统(即,在您已向文件系统添加和删除数百万个文件后的几个月或几年后)的性能。使用此功能不会影响整体文件系统可靠性级别或恢复能力。
此功能依赖于新的 v5 磁盘格式,该格式从 Linux Kernel 3.15 开始被认为是生产工作负载稳定的。它不会更改现有的磁盘结构,而是添加一个新的结构,该结构必须与 inode 分配 btree 保持一致;因此,旧内核将只能以只读方式挂载具有空闲 inode btree 功能的文件系统。
当使用 xfsprogs 3.2.3 或更高版本时,此功能默认启用。如果您需要旧内核的可写文件系统,则可以在格式化 XFS 分区时使用 finobt=0
开关禁用它。您将需要 crc=0
一起使用
# mkfs.xfs -m crc=0,finobt=0 /dev/target_partition
或简写(因为 finobt
依赖于 crc
)
# mkfs.xfs -m crc=0 /dev/target_partition
反向映射 btree
反向映射 btree 核心
- 是存储空间使用情况的二级索引,有效地提供了主空间使用情况元数据的冗余副本。这会给文件系统操作增加一些开销,但将其包含在文件系统中可以使交叉引用非常快速。它是在线修复文件系统的基本功能,因为我们可以从辅助副本重建损坏的主元数据。
- 该功能在 Linux 4.16 中从 EXPERIMENTAL 状态毕业,并已准备好用于生产环境。但是,在线文件系统检查和修复(到目前为止)是此功能的唯一用例,因此它将至少在在线检查毕业到生产就绪状态之前保持为可选功能。
- 反向映射 btree 将文件系统块映射到文件系统块的所有者。大多数映射将指向 inode 编号和偏移量,尽管也会有指向文件系统元数据的映射。此二级元数据可用于验证主元数据或精确定位磁盘错误发生时丢失了哪些数据。
从 xfsprogs 6.5.0 开始,对于新文件系统,此功能默认启用。
大时间戳
从 Linux 5.10 开始,XFS 支持使用重构的“时间戳和 inode 编码函数来将时间戳作为 64 位纳秒计数器处理,并使用位移来增加有效大小。现在,这允许 XFS 运行远远超出 2038 年问题,直到 2486 年。启用 bigtime 创建新的 XFS 文件系统允许时间戳范围从 1901 年 12 月到 2486 年 7 月,而不是 1901 年 12 月到 2038 年 1 月。”该功能还将允许配额计时器到期时间从 1970 年 1 月到 2486 年 7 月,而不是 1970 年 1 月到 2106 年 2 月。
从 xfsprogs 5.15 开始,对于新文件系统,大时间戳默认启用。
升级
使用 xfs_info(8) 验证现有文件系统是否启用了 bigtime
# xfs_info / | grep bigtime ... bigtime=0 ...
使用 xfsprogs 5.11 及更高版本,您可以使用 xfs_admin(8) 升级现有的(未挂载的)文件系统
# xfs_admin -O bigtime=1 device
或使用 xfs_repair(8)
# xfs_repair -c bigtime=1 device
在那里,您可能还想启用 inobtcount
(另一个新的默认值)。
性能
来自 XFS FAQ
- 已经使用的默认值首先针对最佳性能进行了优化。 mkfs.xfs 将检测到单磁盘和 MD/DM RAID 设置之间的差异,并更改其使用的默认值以适当配置文件系统。
- 在大多数情况下,您需要为
mkfs.xfs
考虑的唯一事情是为硬件 RAID 设备指定条带单元和宽度。
(参见 #条带大小和宽度)
largeio
、swalloc
、增加的 logbsize
和 allocsize
值等,可能会提高性能。以下文章可能提供有关这些标志的更多详细信息
- 对于挂载选项,唯一会显着改变元数据性能的是
logbsize
挂载选项。增加logbsize
会减少给定工作负载的日志 IO 数量。这种元数据性能提升的权衡是,如果在主动进行修改时系统崩溃,则恢复后可能会“丢失”更多操作。
- 从内核 3.2.12 开始,默认的 i/o 调度程序 CFQ 将会抵消 XFS 中的大部分并行化。
因此,为了获得最佳性能,在大多数情况下,您只需遵循 #创建 即可。
条带大小和宽度
如果此文件系统将位于条带化 RAID 上,则可以通过向 mkfs.xfs(8) 命令指定条带大小来显着提高速度。
XFS 有时可以检测到软件 RAID 下的几何结构,但如果您重塑它或您正在使用硬件 RAID,请参阅 如何计算正确的 sunit,swidth 值以获得最佳性能。
访问时间
在某些文件系统上,您可以通过将 noatime
挂载选项添加到 /etc/fstab
文件来提高性能。对于 XFS 文件系统,“默认的 atime 行为是 relatime
,与 noatime 相比几乎没有开销,但仍然保持合理的 atime 值。所有 Linux 文件系统现在都使用它作为默认值(自 2.6.30 左右),但 XFS 自 2006 年以来就使用了类似 relatime 的行为,因此出于性能原因,实际上没有人需要 ever 在 XFS 上使用 noatime。”[7]
有关此主题的更多信息,请参阅 Fstab#atime 选项。
Discard
尽管 XFS 自内核 4.7[8][9][10] 以来支持异步 discard,xfs(5) 仍然建议“您使用 fstrim 应用程序来 discard 未使用的块,而不是 discard 挂载选项,因为此选项的性能影响非常严重。”
请参阅 固态硬盘#定期 TRIM。
碎片整理
尽管 XFS 基于 extent 的性质及其使用的延迟分配策略显着提高了文件系统对碎片问题的抵抗力,但 XFS 提供了一个文件系统碎片整理实用程序(xfs_fsr,是 XFS 文件系统重组器的缩写),可以对已挂载和活动 XFS 文件系统上的文件进行碎片整理。定期查看 XFS 碎片可能会很有用。
xfs_fsr(8) 改进了已挂载文件系统的组织。重组算法一次对一个文件进行操作,压缩或以其他方式改进文件 extent(文件数据的连续块)的布局。
检查碎片级别
要查看您的文件系统当前有多少碎片
# xfs_db -c frag -r /dev/partition
执行碎片整理
要开始碎片整理,请使用 xfs_fsr(8) 命令
# xfs_fsr /dev/partition
数据去重
reflink 功能自内核版本 4.9 起可用,并且自 mkfs.xfs
版本 5.1.0 起默认启用,它允许创建文件的快速 reflink 副本,以及事后去重,方式与 btrfs 相同
Reflink 副本
Reflink 副本最初不使用额外的空间
$ cp --reflink bigfile1 bigfile2
直到编辑任一文件并且发生写时复制。这对于创建(大型)文件的快照非常有用。
数据去重
可以使用 duperemove 或 hardlink(1) 等工具从 util-linux 对现有文件系统进行去重。
外部 XFS 日志
例如,在 SSD 上使用外部日志(元数据日志)可能有助于提高性能 [11]。有关 logdev
参数的详细信息,请参阅 mkfs.xfs(8)。
要在创建 XFS 文件系统时保留指定大小的外部日志,请将 -l logdev=device,size=size
选项指定给 mkfs.xfs
命令。如果您省略 size
参数,则会使用基于文件系统大小的日志大小。要挂载 XFS 文件系统以便它使用外部日志,请将 -o logdev=device
选项指定给 mount 命令。
同步间隔
XFS 有一个专用的 sysctl 变量,用于设置 回写间隔,默认值为 3000。
/etc/sysctl.d/20-xfs-sync-interval.conf
fs.xfs.xfssyncd_centisecs = 10000
管理
调整大小
可以使用 xfs_growfs(8) 在线调整 XFS 的大小
# xfs_growfs -D size /path/to/mnt/point
如果省略 -D size
,则文件系统会自动扩展到最大可能的大小,即分区的大小。
在线元数据检查 (scrub)
xfs_scrub
请求内核 scrub XFS 文件系统中的所有元数据对象。扫描元数据记录以查找明显错误的值,然后与其他元数据交叉引用。目标是通过检查各个元数据记录与文件系统中其他元数据的一致性,建立对整体文件系统一致性的合理信心。如果存在完整的冗余数据结构,则可以从其他元数据重建损坏的元数据。
启用/启动 xfs_scrub_all.timer
以定期检查所有 XFS 文件系统的在线元数据。
修复
来自 检查和修复 XFS 文件系统 (重点是我们的)
- 如果您无法挂载 XFS 文件系统,可以使用
xfs_repair -n
命令检查其一致性。通常,您只会在您认为存在问题的未挂载文件系统的设备文件上运行此命令。xfs_repair -n
命令显示输出,指示如果需要完成修复操作,则会对文件系统进行的更改,但不会直接修改文件系统。 - 如果您可以挂载文件系统并且没有合适的备份,则可以使用 xfsdump 命令备份现有文件系统数据。但是,请注意,如果文件系统的元数据已损坏,则该命令可能会失败。
- 您可以使用 xfs_repair 命令尝试修复由其设备文件指定的 XFS 文件系统。该命令重放日志以修复可能由于文件系统未干净卸载而导致的不一致性。除非文件系统存在不一致性,否则您通常不需要使用以下命令,因为每次挂载 XFS 文件系统时都会重放日志。
# xfs_repair device
- 如果日志已损坏,您可以通过指定
-L
选项给 xfs_repair 来重置日志。
- 如果您无法挂载文件系统或没有合适的备份,则运行 xfs_repair 是唯一可行的选择,除非您有使用 xfs_db 命令的经验。
- xfs_db 提供了一组内部命令,使您可以手动调试和修复 XFS 文件系统。这些命令使您能够对文件系统执行扫描,并导航和显示其数据结构。如果您指定
-x
选项以启用专家模式,则可以修改数据结构。
# xfs_db [-x] device
- 有关更多信息,请参阅 xfs_db(8) 和 xfs_repair(8),以及 xfs_db 中的 help 命令。
另请参阅 哪些因素影响 xfs_repair 的内存使用量? 和 XFS 修复。
数据恢复
即使以只读方式挂载 mount -o ro
,如果 XFS 文件系统的日志未干净卸载,也会重放日志。
在某些情况下,应该以只读方式挂载损坏的存储设备上的受损 XFS 文件系统,以便可以从中复制文件,希望不会造成进一步的损坏,但由于它未干净卸载并且损坏到无法重放日志的程度,因此无法挂载。此外,请考虑重放日志意味着写入受损的文件系统,这本身可能不是一个好主意。
要挂载 XFS 文件系统而不以任何方式写入它且不重放日志,请使用 mount -o ro,norecovery
。
取消删除
xfs_undelete-gitAUR 可以在(在某些条件下)未挂载或只读挂载的 XFS 文件系统上恢复已删除的文件。有关更多信息,请参阅 https://github.com/ianka/xfs_undelete。
故障排除
根文件系统配额
XFS 配额挂载选项(uquota
、gquota
、prjquota
等)在重新挂载文件系统期间失败。要为根文件系统启用配额,必须将挂载选项作为 内核参数 rootflags=
传递给 initramfs。随后,不应将其列在根 (/
) 文件系统的 /etc/fstab
中的挂载选项中。
如果用户 "nobody" 无法访问挂载点,xfs_scrub_all 将失败
运行 xfs_scrub_all
时,它将为每个已挂载的 XFS 文件系统启动 xfs_scrub@.service
。该服务以用户 nobody
身份运行,因此如果 nobody
无法导航到该目录,它将失败并显示错误
xfs_scrub@mountpoint.service: Changing to the requested working directory failed: Permission denied xfs_scrub@mountpoint.service: Failed at step CHDIR spawning /usr/bin/xfs_scrub: Permission denied xfs_scrub@mountpoint.service: Main process exited, code=exited, status=200/CHDIR
要允许服务运行,请更改挂载点的 权限,以便用户 nobody
具有执行权限。
基于 systemd 的 initramfs 中 fsck.xfs 失败
当使用没有 base
hook 的 mkinitcpio 生成的基于 systemd 的 initramfs 时,您将在 日志 中看到以下消息
systemd-fsck[288]: fsck: /usr/bin/fsck.xfs: execute failed: No such file or directory systemd-fsck[286]: fsck failed with exit status 8. systemd-fsck[286]: Ignoring error.
这是因为 fsck.xfs(8) 是一个 shell 脚本,需要 /bin/sh
才能执行。 /usr/bin/sh
由 base
hook 提供,因此解决方案是将其添加到 /etc/mkinitcpio.conf
中的 HOOKS 数组的前面。例如
HOOKS=(base systemd ... )
参见
- XFS wiki (存档
- XFS FAQ
- 通过减少日志开销来提高元数据性能
- XFS 维基百科条目
- XFS 用户指南[死链 2024-03-03 ⓘ] XFS 用户指南不再存在,但有一个指向 git 仓库的链接