Ext4

来自 ArchWiki

来自 Ext4 - Linux Kernel Newbies

Ext4 是最常用的 Linux 文件系统 Ext3 的演进。在许多方面,Ext4 比 Ext3 之于 Ext2 的改进更深入。Ext3 主要是在 Ext2 中添加了日志功能,而 Ext4 修改了文件系统的重要数据结构,例如用于存储文件数据的结构。最终得到的文件系统具有改进的设计、更好的性能、可靠性和功能。

创建一个新的 ext4 文件系统

安装 e2fsprogs

要格式化分区,请执行以下操作

# mkfs.ext4 /dev/partition

有关更多选项,请参阅 mke2fs(8)

提示: 要查看/配置默认的 mke2fs 选项,请编辑 /etc/mke2fs.conf

每 inode 字节数比率

来自 mke2fs(8)

mke2fs 为磁盘上每 bytes-per-inode 字节的空间创建一个 inode。bytes-per-inode 比率越大,创建的 inode 就越少。

创建新文件、目录、符号链接等至少需要一个空闲的 inode。如果 inode 计数太低,即使文件系统上仍有空间,也无法创建文件。

由于在文件系统创建后无法更改每 inode 字节数比率或 inode 计数,因此 mkfs.ext4 默认使用相对较低的比率,即每 16384 字节(16 KiB)一个 inode,以避免这种情况。

但是,对于大小为数百或数千 GB 且平均文件大小在兆字节范围内的分区,这通常会导致 inode 数量过大,因为创建的文件数量永远不会达到 inode 的数量。

这会导致磁盘空间浪费,因为所有这些未使用的 inode 每个都会占用文件系统上的 256 字节(这也在 /etc/mke2fs.conf 中设置,但不应更改)。256 * 数百万 = 在未使用的 inode 中浪费了相当多的千兆字节。

可以通过比较 dfdf -i 提供的 Use%IUse% 数字来评估这种情况

$ df -h /home
Filesystem              Size    Used   Avail  Use%   Mounted on
/dev/mapper/lvm-home    115G    56G    59G    49%    /home
$ df -hi /home
Filesystem              Inodes  IUsed  IFree  IUse%  Mounted on
/dev/mapper/lvm-home    1.8M    1.1K   1.8M   1%     /home

要指定不同的每 inode 字节数比率,可以使用 -T usage-type 选项,该选项提示文件系统的预期用途,使用在 /etc/mke2fs.conf 中定义的类型。在这些类型中,较大的 largefilelargefile4 分别提供每 1 MiB 和 4 MiB 一个 inode 的更相关的比率。它可以这样使用

# mkfs.ext4 -T largefile /dev/device

每 inode 字节数比率也可以通过 -i 选项直接设置:例如,对于 2 MiB 比率使用 -i 2097152,对于 6 MiB 比率使用 -i 6291456

提示: 相反,如果要设置一个专用于托管数百万个小文件(如电子邮件或新闻组项目)的分区,可以使用较小的 usage-type 值,例如 news(每 4096 字节一个 inode)或 small(相同,加上更小的 inode 和块大小)。
警告: 如果您大量使用符号链接,请确保使用较低的每 inode 字节数比率保持足够的 inode 计数,因为虽然每个新的符号链接不会占用更多空间,但会消耗一个新的 inode,因此文件系统可能会很快耗尽它们。

保留块

默认情况下,文件系统块的 5% 将为超级用户保留,以避免碎片,并“允许 root 拥有的守护进程在非特权进程被阻止写入文件系统后继续正常运行”(来自 mke2fs(8))。

对于现代大容量磁盘,如果分区用作长期存档或对系统操作不重要(如 /home),则此比例高于必要比例。有关保留块的 ext4 开发人员 Ted Ts'o 的意见,请参阅 这封电子邮件,有关此主题的一般背景信息,请参阅 这个 superuser 回答

当分区满足以下任一条件时,通常可以安全地减少保留块的百分比以释放磁盘空间

  • 非常大(例如 > 50G)
  • 用作长期存档,即文件不会经常删除和创建

ext4 相关实用程序的 -m 选项允许指定保留块的百分比。

要在文件系统创建时完全阻止保留块,请使用

# mkfs.ext4 -m 0 /dev/device

要之后将其更改为 1%,请使用

# tune2fs -m 1 /dev/device

要将保留块空间的大小设置为绝对大小(以千兆字节为单位),请使用 -r

# tune2fs -r $((ngigs * 1024**3 / blocksize)) /dev/device

blocksize 是文件系统的块大小,以字节为单位。这几乎总是 4096,但您可以检查以确保

# tune2fs -l /dev/device | grep 'Block size:'
Block size:               4096

$(()) 语法用于数学扩展。此语法在 bashzsh 中有效,但在 fish 中无效。对于 fish,这是语法

# tune2fs -r (math 'ngigs * 1024^3 / blocksize') /dev/device

这些命令可以应用于当前挂载的文件系统,更改会立即生效。您可以使用 findmnt(8) 查找设备名称

# tune2fs -m 1 "$(findmnt -no SOURCE /the/mount/point)"

要查询当前保留块数

# tune2fs -l /dev/mapper/proxima-root | grep 'Reserved block count:'
Reserved block count:     2975334

这是块数,因此必须将其乘以文件系统的块大小才能获得字节数或千兆字节数:2975334 * 4096 / 1024**3 = 11.34 GiB

从 ext2/ext3 迁移到 ext4

在不转换的情况下将 ext2/ext3 分区挂载为 ext4

理由

完全转换为 ext4 和简单地保留 ext2/ext3 之间的一种折衷方案是将分区挂载为 ext4。

优点

  • 兼容性(文件系统可以继续作为 ext3 挂载)– 这允许用户仍然可以从没有 ext4 支持的其他操作系统(例如,带有 ext2/ext3 驱动程序的 Windows)读取文件系统
  • 性能提升(尽管不如完全转换的 ext4 分区)。[1] [2]

缺点

  • 使用的 ext4 功能较少(仅限于那些不更改磁盘格式的功能,例如多块分配和延迟分配)
注意: 除了 ext4 的相对新颖性(可以被视为一种风险),这种技术没有主要的缺点

步骤

  1. 编辑 /etc/fstab 并将要挂载为 ext4 的任何分区的“类型”从 ext2/ext3 更改为 ext4。
  2. 重新挂载受影响的分区。

将 ext2/ext3 分区转换为 ext4

理由

要体验 ext4 的好处,必须完成不可逆的转换过程。

优点

  • 性能提升和新功能。[3] [4]

缺点

  • 包含大多是静态文件的分区,例如 /boot 分区,可能不会从新功能中受益。此外,添加日志(将 ext2 分区移动到 ext3/4 隐含的)总是会产生性能开销。
  • 不可逆(ext4 分区无法“降级”到 ext2/ext3。但是,在启用 extent 和其他唯一选项之前,它是向后兼容的)

步骤

这些说明改编自 内核文档BBS 帖子

警告
  • 如果您转换系统的根文件系统,请确保在重新启动时可以使用“fallback” initramfs。或者,根据 Mkinitcpio#MODULES 添加 ext4,并在启动前重新生成 initramfs
  • 如果您决定转换单独的 /boot 分区,请确保 引导加载程序 支持从 ext4 启动。

在以下步骤中,/dev/sdxX 表示要转换的分区的路径,例如 /dev/sda1

  1. 备份 要转换为 ext4 的任何 ext3 分区上的所有数据。一个有用的软件包,特别是对于根分区,是 clonezilla
  2. 编辑 /etc/fstab 并将要转换为 ext4 的任何分区的“类型”从 ext3 更改为 ext4。
  3. 启动 live 介质(如果需要)。使用 e2fsprogs 的转换过程必须在驱动器未挂载时完成。如果要转换根分区,最简单的方法是从其他 live 介质启动。
  4. 确保分区挂载
  5. 如果要转换 ext2 分区,第一个转换步骤是通过运行 tune2fs -j /dev/sdxX 作为 root 用户来添加日志;将其转换为 ext3 分区。
  6. 以 root 身份运行 tune2fs -O extent,uninit_bg,dir_index /dev/sdxX。此命令将 ext3 文件系统转换为 ext4(不可逆)。
  7. 以 root 身份运行 fsck -f /dev/sdxX
    • 此步骤是必要的,否则文件系统将无法读取。需要运行此 fsck 以使文件系统恢复到一致状态。它将在组描述符中找到校验和错误 - 这是预期的。 -f 选项要求 fsck 强制检查,即使文件系统看起来是干净的。 -p 选项可以放在顶部以“自动修复”(否则,将要求用户为每个错误输入)。
  8. 推荐:挂载分区并以 root 身份运行 e4defrag -c -v /dev/sdxX
    • 即使文件系统现在已转换为 ext4,在转换之前写入的所有文件仍未利用 ext4 的 extent 选项,这将提高大文件性能并减少碎片和文件系统检查时间。为了充分利用 ext4,所有文件都必须在磁盘上重写。使用 e4defrag 来处理此问题。
  9. 重启

提升性能

禁用访问时间更新

ext4 文件系统记录有关上次访问文件的时间的信息,并且记录此信息需要成本。有关 noatime 和相关选项,请参阅 fstab#atime options

增加提交间隔

可以通过为 commit 选项提供更长的时间延迟来增加数据和元数据的同步间隔。

默认的 5 秒意味着如果断电,将丢失最新的 5 秒的工作。它强制每 5 秒将所有数据/日志完全同步到物理介质。但是,由于日志功能,文件系统不会损坏。以下 fstab 说明了 commit 的用法

/etc/fstab
/dev/sda5    /    ext4    defaults,commit=60    0    1

关闭 barriers

警告: 不建议为没有电池备份缓存的磁盘禁用 barriers,这可能会导致严重的文件系统损坏和数据丢失。

Ext4 默认启用写入 barriers。即使在写入缓存断电时,它也能确保文件系统元数据在磁盘上正确写入和排序。这会带来性能成本,特别是对于大量使用 fsync 或创建和删除许多小文件的应用程序。对于以某种方式具有电池备份写入缓存的磁盘,禁用 barriers 可以安全地提高性能。

要关闭 barriers,请将选项 barrier=0 添加到所需的文件系统。例如

/etc/fstab
/dev/sda5    /    ext4    defaults,barrier=0    0    1

禁用日志

警告: 在突然卸载(如断电或内核死锁)的情况下,使用没有日志的文件系统可能会导致数据丢失。

可以使用以下命令在未挂载的磁盘上禁用 ext4 的日志

# tune2fs -O "^has_journal" /dev/sdXn

使用日志优化性能

Ext4 的快速提交 文章介绍简洁地总结了为什么以及与默认的 data=ordered 操作模式相比,挂载选项 data=journaldata=writeback 可以加速整体 ext4 性能。此外,可以通过添加 journal_async_commit 挂载选项来加速日志本身。

注意: journal_async_commit 挂载选项不适用于默认挂载选项 data=ordered,因此请使用不同的模式显式挂载 ext4_device;请参阅 ext4(5) § data=

另一种选择是使用较新的日志格式,请参阅 #启用 fast_commit

如果使用非默认的 data= 选项,在某些情况下,为日志使用专用设备也可能加速文件操作。例如,当相对较慢的设备用于数据本身,而另一个(更快但更小的)设备用于日志时。要设置单独的日志设备

# mke2fs -O journal_dev /dev/journal_device

要将 journal_device 分配为 ext4_device 的日志,请使用

# tune2fs -J device=/dev/journal_device /dev/ext4_device

如果您还想在 ext4_device 上创建新的文件系统,则可以使用 mkfs.ext4 替换 tune2fs

技巧与诀窍

使用基于文件的加密

自 Linux 4.1 以来,ext4 原生支持文件加密,请参阅 fscrypt 文章。加密应用于目录级别,不同的目录可以使用不同的加密密钥。这与 dm-crypt(块设备级别加密)和 eCryptfs(堆叠式加密文件系统)都不同。

在现有文件系统中启用元数据校验和

当使用 e2fsprogs 1.43 (2016) 或更高版本创建文件系统时,默认启用元数据校验和。可以转换现有文件系统以启用元数据校验和支持。

本文或章节已过时。

原因: crc32c_intel 支持在 Linux 6.14 中被弃用(在 Talk:Ext4#crc32c_intel is obsolete 中讨论)

如果 CPU 支持 SSE 4.2,请确保加载 crc32c_intel 内核模块,以启用硬件加速的 CRC32C 算法 [5]。否则,请加载 crc32c_generic 模块。

要了解有关元数据校验和的更多信息,请参阅 ext4 wiki

提示: 使用 dumpe2fs 检查文件系统上启用的功能
# dumpe2fs -h /dev/path/to/disk
注意: 文件系统不得挂载。

首先需要使用 e2fsck 检查和优化分区

# e2fsck -Df /dev/path/to/disk  

将文件系统转换为 64 位

# resize2fs -b /dev/path/to/disk 

最后启用校验和支持

# tune2fs -O metadata_csum /dev/path/to/disk

要验证

# dumpe2fs -h /dev/path/to/disk | grep features:
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum

使用 LVM 时的维护

如果 e2scrub 工具在 LVM 逻辑卷中使用,则会检查 ext4 文件系统的元数据。卷组必须有 256MiB 未分配空间才能进行此检查,因为该工具会创建一个快照进行检查。正如 e2scrub(8) 手册所述,该工具不修复错误,而是报告错误并将文件系统标记为在下次挂载之前需要运行 e2fsck(请参阅 e2fsck(8))。

检查可以自动化,例如通过启用打包的 e2scrub_all.timer 单元。

如果缺少至少 256MiB 未分配空间,请参阅 LVM#一次性调整逻辑卷和文件系统大小

启用 fast_commit

ext4 “快速提交”功能引入了一种新的、更轻量级的日志记录方法。预计这将显着提高 ext4 文件系统的性能,[6]

要在新文件系统上启用该功能,请在 -O 文件系统选项参数中包含 fast_commit

要在现有文件系统上启用该功能,请运行

# tune2fs -O fast_commit /dev/drivepartition

要查询当前配置

# tune2fs -l /dev/drivepartition | grep features

要在现有文件系统上禁用该功能,请运行

# tune2fs -O '^fast_commit' /dev/drivepartition

启用不区分大小写模式

警告
  • 如果已启用 casefold 功能,则无法可靠地再次禁用它(由于 tune2fs 中可能存在的错误)。在启用它之前,请注意以下限制!
  • GRUB 当前不支持 ext4 的 casefold 功能;请参阅 GRUB 错误 #56897。为 GRUB 需要读取的文件系统启用它将导致系统无法启动,并显示无帮助的 unknown filesystem 错误,即使实际上没有目录正在使用该功能。
  • casefold 功能与 overlayfs 不兼容,这可能会阻止容器软件(如 DockerPodman)在该文件系统上工作。高级 systemd 功能(如 systemd-sysext(8) 扩展映像)也可能变得不可用。

ext4 可以在不区分大小写模式下使用,这可以提高在 Wine 中运行的应用程序和游戏的性能。此功能不影响整个文件系统,仅影响启用了不区分大小写属性的目录。

首先,在文件系统中启用该功能

# tune2fs -O casefold /dev/path/to/disk

现在您可以在任何目录中启用不区分大小写的属性

$ chattr +F /mnt/partition/case-insensitive-directory

请注意,目录必须为空,并且从其他位置移动子目录不会导致它们继承该属性,因此请提前计划。

参见