XFS

来自 ArchWiki

XFS 是 Silicon Graphics, Inc. 创建的高性能日志文件系统。由于其基于分配组的设计,XFS 在并行 IO 方面尤其出色。当跨越多个存储设备时,这使得 IO 线程、文件系统带宽、文件和文件系统大小具有极高的可扩展性。

准备工作

对于 XFS 用户空间实用程序,安装 xfsprogs 软件包。它包含管理 XFS 文件系统所需的工具。

创建

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

# 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),其中包括名为 自描述元数据的元数据校验和方案。它基于 CRC32,可提供额外的保护以防止元数据损坏(例如,意外断电时)。当使用 xfsprogs 3.2.3 或更高版本时,校验和默认启用,但可以使用 -m crc=0 开关在调用 mkfs.xfs(8) 时禁用(对于在旧内核上进行读写挂载是必要的)

# mkfs.xfs -m crc=0 /dev/target_partition
注意: 禁用元数据 CRC 也会禁用对以下 #空闲 inode btree#反向映射 btree#大时间戳 功能以及“引用计数 btree”的支持(有关详细信息,请参阅 mkfs.xfs(8) § OPTIONS)。

从 Linux Kernel 3.15 开始,XFS v5 磁盘格式被认为是生产工作负载稳定的。

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

空闲 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 状态毕业,并已准备好用于生产环境。但是,在线文件系统检查和修复(到目前为止)是此功能的唯一用例,因此它将至少在在线检查毕业到生产就绪状态之前保持为可选功能。

来自 mkfs.xfs(8) § OPTIONS

反向映射 btree 将文件系统块映射到文件系统块的所有者。大多数映射将指向 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 设备指定条带单元和宽度。

(参见 #条带大小和宽度

提示: 当在 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 下的几何结构,但如果您重塑它或您正在使用硬件 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

直到编辑任一文件并且发生写时复制。这对于创建(大型)文件的快照非常有用。

数据去重

可以使用 duperemovehardlink(1) 等工具从 util-linux 对现有文件系统进行去重。

外部 XFS 日志

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

注意: 使用闪存存储器可能会磨损驱动器。有关 SSD 磨损的详细信息,请参阅 提高性能#减少磁盘读取/写入

要在创建 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,则文件系统会自动扩展到最大可能的大小,即分区的大小。

注意: xfs 仅对收缩提供有限的支持,如 xfs_growfs(8) 中所述:“只有一个 AG 的文件系统不能进一步收缩,并且文件系统不能收缩到仅剩 1 个 AG 的程度。”,其中 AG 代表分配组

在线元数据检查 (scrub)

警告: 此程序是实验性的,这意味着其行为和界面可能随时更改。请参阅 xfs_scrub(8)

xfs_scrub 请求内核 scrub XFS 文件系统中的所有元数据对象。扫描元数据记录以查找明显错误的值,然后与其他元数据交叉引用。目标是通过检查各个元数据记录与文件系统中其他元数据的一致性,建立对整体文件系统一致性的合理信心。如果存在完整的冗余数据结构,则可以从其他元数据重建损坏的元数据。

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

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

修复

注意: “与其他 Linux 文件系统不同,xfs_repair 不会在启动时运行,即使 XFS 文件系统未干净卸载也是如此。如果发生不干净的卸载,xfs_repair 只会在挂载时重放日志,以确保文件系统的一致性。”[12]

来自 检查和修复 XFS 文件系统 (重点是我们的)

如果您无法挂载 XFS 文件系统,可以使用 xfs_repair -n 命令检查其一致性。通常,您只会在您认为存在问题的未挂载文件系统的设备文件上运行此命令xfs_repair -n 命令显示输出,指示如果需要完成修复操作,则会对文件系统进行的更改,但不会直接修改文件系统。
如果您可以挂载文件系统并且没有合适的备份,则可以使用 xfsdump 命令备份现有文件系统数据。但是,请注意,如果文件系统的元数据已损坏,则该命令可能会失败。
您可以使用 xfs_repair 命令尝试修复由其设备文件指定的 XFS 文件系统。该命令重放日志以修复可能由于文件系统未干净卸载而导致的不一致性。除非文件系统存在不一致性,否则您通常不需要使用以下命令,因为每次挂载 XFS 文件系统时都会重放日志。
# xfs_repair device
如果日志已损坏,您可以通过指定 -L 选项给 xfs_repair 来重置日志。
警告
  • xfs_repair 实用程序无法修复具有脏日志的 XFS 文件系统。要清除日志,请挂载并卸载 XFS 文件系统。如果日志已损坏且无法重放,请使用 -L 选项(“强制日志归零”)清除日志,即 xfs_repair -L /dev/device。请注意,这可能会导致进一步的损坏或数据丢失。[13]
  • 重置日志可能会使文件系统处于不一致状态,从而导致数据丢失和数据损坏。除非您有使用 xfs_db 调试和修复 XFS 文件系统的经验,否则建议您重新创建文件系统并从备份还原其内容。[14]
如果您无法挂载文件系统或没有合适的备份,则运行 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 配额挂载选项(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 失败

当使用没有 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/shbase hook 提供,因此解决方案是将其添加到 /etc/mkinitcpio.conf 中的 HOOKS 数组的前面。例如

HOOKS=(base systemd ... )

参见