跳转至内容

XFS

来自 ArchWiki

XFS 是一种高性能日志文件系统,由 Silicon Graphics, Inc. 创建。XFS 因其基于分配组(Allocation Group)的设计,在并行 IO 方面表现尤为出色。这使得文件系统在跨越多个存储设备时,能够实现 IO 线程、文件系统带宽、文件及文件系统大小的极致扩展性。

准备工作

要获取 XFS 用户空间工具,请安装 xfsprogs 软件包。它包含了管理 XFS 文件系统所需的工具。

创建

要在 device 上创建新文件系统,请使用

# mkfs.xfs device

通常情况下,默认选项对于一般用途而言是最优的。[1][2]

示例输出:

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]此操作将销毁先前文件系统中的所有数据
注意 “XFS 文件系统创建后,其大小无法减小。但仍可以使用 xfs_growfs 命令进行扩大。”[4] 详见 #调整大小

校验和

xfsprogs 3.2.0 引入了一种新的磁盘格式 (v5),其中包括一种称为 自描述元数据 (Self-Describing Metadata) 的元数据校验和方案。基于 CRC32,它提供了针对元数据损坏(例如意外断电)的额外保护。在使用 xfsprogs 3.2.3 或更高版本时,校验和是默认启用的;但若需要在旧内核上进行读写挂载,可通过在调用 mkfs.xfs(8) 时使用 -m crc=0 开关来禁用它。

# mkfs.xfs -m crc=0 /dev/target_partition
注意 禁用元数据 CRC 还会导致禁用以下功能支持:#空闲 inode B+树#反向映射 B+树#大时间戳,以及“引用计数 B+树”(详见 mkfs.xfs(8) § OPTIONS)。

XFS v5 磁盘格式从 Linux 内核 3.15 开始被认为可用于生产环境。

注意BtrfsZFS 不同,CRC32 校验和仅适用于元数据,而不适用于实际数据。

空闲 inode B+树

从 Linux 3.16 开始,XFS 增加了一棵用于追踪空闲 inode 的 B+树。它与现有的 inode 分配 B+树等效,区别在于空闲 inode B+树追踪的是至少包含一个空闲 inode 的 inode 块。其目的是改善 inode 分配时查找空闲 inode 集群的效率。它能提升老旧文件系统(即在使用数月或数年后,向文件系统添加并删除了数百万个文件)的性能。使用此功能不会影响文件系统的整体可靠性级别或恢复能力。

此功能依赖于 v5 磁盘格式,该格式从 Linux 内核 3.15 开始被认为可用于生产环境。它不会改变现有的磁盘结构,而是添加了一个必须与 inode 分配 B+树保持一致的新结构;因此,旧内核只能以只读方式挂载开启了空闲 inode B+树功能的文件系统。

在使用 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

反向映射 B+树

反向映射 B+树 的核心本质

是存储空间使用的二级索引,它有效地提供了主要空间使用元数据的冗余副本。这会增加文件系统操作的一些开销,但将其包含在文件系统中使得交叉引用变得非常快。对于在线修复文件系统而言,它是必不可少的功能,因为我们可以从二级副本重建损坏的主要元数据。
该功能在 Linux 4.16 中从实验性状态毕业,已达到生产就绪水平。然而,在线文件系统检查和修复目前是该功能的唯一用途,因此除非在线检查功能毕业达到生产就绪水平,否则它将保持可选状态。

摘自 mkfs.xfs(8) § OPTIONS

反向映射 B+树将文件系统块映射到该文件系统块的所有者。大多数映射将指向 inode 编号和偏移量,尽管也会有指向文件系统元数据的映射。这种二级元数据可用于验证主要元数据,或在磁盘错误发生时精准定位丢失的数据。

更多信息请参阅 [5][6]

自 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 起,大时间戳对新文件系统默认启用。

升级

本文章或章节需要扩充。

原因:将其设为顶级部分,并描述哪些新默认设置可以在现有文件系统上启用。(请在 Talk:XFS 中讨论)

使用 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 设备指定条带单元(stripe unit)和宽度(width)。

(详见 #条带大小和宽度

提示RAID 设备上使用 XFS 文件系统时,通过使用 largeioswalloc,以及增大 logbsizeallocsize 值,可能实现性能提升。以下文章可能提供了关于这些标志的更多详细信息
对于挂载选项,唯一能显著改变元数据性能的是 logbsize 挂载选项。增加 logbsize 可以减少给定工作负载下的日志 IO 次数。这种元数据性能提升的代价是,如果系统在进行修改时崩溃,恢复后可能会有更多操作“丢失”。
提示 有关所有可用挂载选项的详细信息,请参阅 xfs(5)
截至内核 3.2.12,默认的 I/O 调度程序 CFQ 会破坏 XFS 的大部分并行化能力。
注意 Arch 在检测到 SATA 或 NVMe SSD 时,配置为不使用 I/O 调度程序;可以通过读取 /sys/block/nvme*n*/queue/scheduler 的内容进行确认。

因此,为了获得最佳性能,大多数情况下您只需遵循 #创建 部分即可。

条带大小和宽度

如果该文件系统将位于条带化 RAID 上,通过向 mkfs.xfs(8) 命令指定条带大小,可以获得显著的速度提升。

XFS 有时可以检测到软件 RAID 下的几何结构,但如果您进行了重塑(reshape)或正在使用硬件 RAID,请参阅 如何计算正确的 sunit 和 swidth 值以获得最佳性能

访问时间

在某些文件系统上,可以通过向 /etc/fstab 文件添加 noatime 挂载选项来提升性能。对于 XFS 文件系统,“默认的 atime 行为是 relatime,与 noatime 相比几乎没有开销,但仍能保持合理的 atime 值。现在所有 Linux 文件系统(自 2.6.30 左右起)默认都使用此行为,而 XFS 自 2006 年起就一直使用类似 relatime 的行为,所以没人真正需要为了性能在 XFS 上使用 noatime。”[7]

有关此主题的更多信息,请参阅 Fstab#atime 选项

Discard(丢弃)

尽管 XFS 自内核 4.7 [8] [9] [10] 起支持异步 discard,但 xfs(5) 仍然建议“您使用 fstrim 应用程序来丢弃未使用的块,而不是使用 discard 挂载选项,因为此选项的性能影响非常严重。”

请参阅 固态硬盘#周期性 TRIM

碎片整理

尽管 XFS 基于区段(extent)的特性及其使用的延迟分配策略显著提高了文件系统对碎片问题的抵抗力,但 XFS 仍提供了一个文件系统碎片整理工具(xfs_fsr,即 XFS 文件系统重组器的缩写),可以对已挂载且处于活动状态的 XFS 文件系统中的文件进行碎片整理。定期查看 XFS 碎片情况非常有用。

xfs_fsr(8) 改善了已挂载文件系统的组织结构。重组算法一次操作一个文件,压缩或以其他方式改进文件区段(连续的文件数据块)的布局。

检查碎片级别

要查看您的文件系统当前有多少碎片

# 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 副本最初不占用额外空间

$ cp --reflink bigfile1 bigfile2

直到其中任何一个文件被编辑,发生写时复制(copy-on-write)为止。这对于创建(大)文件的快照非常有用。

去重

现有文件系统可以使用类似 duperemoveutil-linux 中的 hardlink(1) 等工具进行去重。

外部 XFS 日志

例如在 SSD 上使用外部日志(元数据日志)可能有助于提升性能 [11]。有关 logdev 参数的详细信息,请参阅 mkfs.xfs(8)

注意 使用闪存可能会加速驱动器的磨损。请参阅 性能提升#减少磁盘读写 了解 SSD 磨损的详细信息。

要在创建 XFS 文件系统时预留具有指定大小的外部日志,请向 mkfs.xfs 命令指定 -l logdev=device,size=size 选项。如果您省略 size 参数,将使用基于文件系统大小的默认日志大小。要挂载 XFS 文件系统以使其使用外部日志,请向 mount 命令指定 -o logdev=device 选项。

同步间隔

XFS 有一个专门的 sysctl 变量用于设置 回写间隔,默认值为 3000。

警告 虽然较大的值可能会提高性能,但它们也会增加因停电导致数据丢失的严重程度。
/etc/sysctl.d/20-xfs-sync-interval.conf
fs.xfs.xfssyncd_centisecs = 10000

管理

调整大小

XFS 可以使用 xfs_growfs(8) 在线调整大小。

# xfs_growfs -D size /path/to/mnt/point

如果省略 -D size,文件系统将自动增长到最大可能大小,即分区的大小。

注意 xfs 对缩减的支持非常有限,正如 xfs_growfs(8) 中所述:“只有一个分配组(AG)的文件系统无法进一步缩小,并且文件系统不能缩小到仅剩 1 个 AG 的程度。”

在线元数据检查 (scrub)

警告 该程序是实验性的,这意味着它的行为和接口可能会随时更改。请参阅 xfs_scrub(8)

xfs_scrub 要求内核清理 XFS 文件系统中的所有元数据对象。扫描元数据记录以查找明显错误的值,然后对照其他元数据进行交叉引用。目标是通过检查单个元数据记录相对于文件系统中其他元数据的一致性,从而建立对整体文件系统一致性的合理信任。如果存在完好无损的冗余数据结构,损坏的元数据可以从其他元数据中重建。

启用/启动 xfs_scrub_all.timer 以定期在线检查所有 XFS 文件系统的元数据。

注意 您可能需要 编辑 xfs_scrub_all.timer:计时器在每周日凌晨 3:10 运行,如果错过了上次启动时间(例如由于系统断电),它将 立即触发

修复

注意 xfs_repair(8) 默认不会在引导时运行。要在引导时修复 XFS 文件系统,请设置 fsck.mode=force 内核参数,这会指示 fsck.xfs(8) 运行 xfs_repair

请参阅 检查和修复 XFS 文件系统哪些因素影响 xfs_repair 的内存使用? 以及 XFS 修复

数据救援

即使使用 mount -o ro 只读挂载,如果 XFS 文件系统未被正常卸载,其日志仍将被重放(replayed)。

在某些情况下,损坏存储设备上的受损 XFS 文件系统应以只读方式挂载,以便尽可能在不造成进一步损坏的情况下复制出文件,但由于它未被正常卸载且损坏程度导致日志无法重放,因此无法挂载。此外,考虑到重放日志意味着向受损的文件系统写入数据,这本身可能不是一个好主意。

要以不进行任何写入且不重放日志的方式挂载 XFS 文件系统,请使用 mount -o ro,norecovery

取消删除

xfs_undelete-gitAUR 可以在未挂载或只读挂载的 XFS 文件系统上(在特定条件下)恢复已删除的文件。更多信息请参阅 https://github.com/ianka/xfs_undelete

故障排除

根文件系统配额

XFS 配额挂载选项(uquotagquotaprjquota 等)在文件系统重新挂载期间会失败。要启用根文件系统配额,必须通过 内核参数 rootflags= 将挂载选项传递给 initramfs。随后,它不应列在根 (/) 文件系统的 /etc/fstab 挂载选项中。

注意 XFS 配额与标准 Linux 磁盘配额 之间存在一些差异,值得阅读这篇文章:https://inai.de/linux/adm_quota

若用户 "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 失败

当使用 mkinitcpio 生成的、不含 base 钩子的 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/shbase 钩子提供,因此解决方法是在 /etc/mkinitcpio.conf 的 HOOKS 数组开头添加它。例如:

HOOKS=(base systemd ... )

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.