Ext4
来自 Ext4 - Linux Kernel Newbies
- Ext4 是最常用的 Linux 文件系统 Ext3 的演进。在许多方面,Ext4 比 Ext3 之于 Ext2 的改进更深入。Ext3 主要是在 Ext2 中添加了日志功能,而 Ext4 修改了文件系统的重要数据结构,例如用于存储文件数据的结构。最终得到的文件系统具有改进的设计、更好的性能、可靠性和功能。
创建一个新的 ext4 文件系统
要格式化分区,请执行以下操作
# mkfs.ext4 /dev/partition
有关更多选项,请参阅 mke2fs(8)。
/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 中浪费了相当多的千兆字节。
可以通过比较 df
和 df -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
中定义的类型。在这些类型中,较大的 largefile
和 largefile4
分别提供每 1 MiB 和 4 MiB 一个 inode 的更相关的比率。它可以这样使用
# mkfs.ext4 -T largefile /dev/device
每 inode 字节数比率也可以通过 -i
选项直接设置:例如,对于 2 MiB 比率使用 -i 2097152
,对于 6 MiB 比率使用 -i 6291456
。
news
(每 4096 字节一个 inode)或 small
(相同,加上更小的 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
$(())
语法用于数学扩展。此语法在 bash 和 zsh 中有效,但在 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 功能较少(仅限于那些不更改磁盘格式的功能,例如多块分配和延迟分配)
步骤
- 编辑
/etc/fstab
并将要挂载为 ext4 的任何分区的“类型”从 ext2/ext3 更改为 ext4。 - 重新挂载受影响的分区。
将 ext2/ext3 分区转换为 ext4
理由
要体验 ext4 的好处,必须完成不可逆的转换过程。
优点
缺点
- 包含大多是静态文件的分区,例如
/boot
分区,可能不会从新功能中受益。此外,添加日志(将 ext2 分区移动到 ext3/4 隐含的)总是会产生性能开销。 - 不可逆(ext4 分区无法“降级”到 ext2/ext3。但是,在启用 extent 和其他唯一选项之前,它是向后兼容的)
步骤
- 如果您转换系统的根文件系统,请确保在重新启动时可以使用“fallback” initramfs。或者,根据 Mkinitcpio#MODULES 添加
ext4
,并在启动前重新生成 initramfs。 - 如果您决定转换单独的
/boot
分区,请确保 引导加载程序 支持从 ext4 启动。
在以下步骤中,/dev/sdxX
表示要转换的分区的路径,例如 /dev/sda1
。
- 备份 要转换为 ext4 的任何 ext3 分区上的所有数据。一个有用的软件包,特别是对于根分区,是 clonezilla。
- 编辑
/etc/fstab
并将要转换为 ext4 的任何分区的“类型”从 ext3 更改为 ext4。 - 启动 live 介质(如果需要)。使用 e2fsprogs 的转换过程必须在驱动器未挂载时完成。如果要转换根分区,最简单的方法是从其他 live 介质启动。
- 确保分区未挂载
- 如果要转换 ext2 分区,第一个转换步骤是通过运行
tune2fs -j /dev/sdxX
作为 root 用户来添加日志;将其转换为 ext3 分区。 - 以 root 身份运行
tune2fs -O extent,uninit_bg,dir_index /dev/sdxX
。此命令将 ext3 文件系统转换为 ext4(不可逆)。 - 以 root 身份运行
fsck -f /dev/sdxX
。- 此步骤是必要的,否则文件系统将无法读取。需要运行此 fsck 以使文件系统恢复到一致状态。它将在组描述符中找到校验和错误 - 这是预期的。
-f
选项要求 fsck 强制检查,即使文件系统看起来是干净的。-p
选项可以放在顶部以“自动修复”(否则,将要求用户为每个错误输入)。
- 此步骤是必要的,否则文件系统将无法读取。需要运行此 fsck 以使文件系统恢复到一致状态。它将在组描述符中找到校验和错误 - 这是预期的。
- 推荐:挂载分区并以 root 身份运行
e4defrag -c -v /dev/sdxX
。- 即使文件系统现在已转换为 ext4,在转换之前写入的所有文件仍未利用 ext4 的 extent 选项,这将提高大文件性能并减少碎片和文件系统检查时间。为了充分利用 ext4,所有文件都必须在磁盘上重写。使用 e4defrag 来处理此问题。
- 重启
提升性能
禁用访问时间更新
ext4 文件系统记录有关上次访问文件的时间的信息,并且记录此信息需要成本。有关 noatime
和相关选项,请参阅 fstab#atime options。
增加提交间隔
可以通过为 commit
选项提供更长的时间延迟来增加数据和元数据的同步间隔。
默认的 5 秒意味着如果断电,将丢失最新的 5 秒的工作。它强制每 5 秒将所有数据/日志完全同步到物理介质。但是,由于日志功能,文件系统不会损坏。以下 fstab 说明了 commit
的用法
/etc/fstab
/dev/sda5 / ext4 defaults,commit=60 0 1
关闭 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=journal
或 data=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) 或更高版本创建文件系统时,默认启用元数据校验和。可以转换现有文件系统以启用元数据校验和支持。
如果 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
不兼容,这可能会阻止容器软件(如 Docker 或 Podman)在该文件系统上工作。高级 systemd 功能(如 systemd-sysext(8) 扩展映像)也可能变得不可用。
ext4 可以在不区分大小写模式下使用,这可以提高在 Wine 中运行的应用程序和游戏的性能。此功能不影响整个文件系统,仅影响启用了不区分大小写属性的目录。
首先,在文件系统中启用该功能
# tune2fs -O casefold /dev/path/to/disk
现在您可以在任何目录中启用不区分大小写的属性
$ chattr +F /mnt/partition/case-insensitive-directory
请注意,目录必须为空,并且从其他位置移动子目录不会导致它们继承该属性,因此请提前计划。
参见
- Ext4 内核文档
- 官方 ext4 wiki (已存档)
- Ext4 加密 LWN 文章
- Ext4 加密的内核提交 [7] [8]
- e2fsprogs 变更日志
- Ext4 元数据校验和
- Ext4 快速提交