在之前关于 Linux 文件系统的文章中,我写了对 Linux 文件系统的介绍以及一些更高层次的概念,例如一切都是文件。我想更详细地介绍 EXT 文件系统的细节,但首先,让我们回答这个问题,“什么是文件系统?”文件系统包括以下所有内容:

  1. **数据存储:**任何文件系统的主要功能是成为存储和检索数据的结构化场所。

  2. **命名空间:**一种命名和组织方法,提供命名和结构化数据的规则。

  3. **安全模型:**定义访问权限的方案。

  4. API: 系统函数调用来操作文件系统对象,如目录和文件。

  5. **实现:**实现上述内容的软件。

本文重点关注列表中的第一项,并探讨为 EXT 文件系统中的数据存储提供逻辑框架的元数据结构。

EXT 文件系统历史

虽然是为 Linux 编写的,但 EXT 文件系统起源于 Minix 操作系统和 Minix 文件系统,它比 Linux 早了大约 5 年,于 1987 年首次发布。如果我们查看历史和技术,了解 EXT4 文件系统要容易得多EXT 文件系统家族从 Minix 根源的演变。

更多 Linux 资源

  • Linux 命令备忘单

  • 高级 Linux 命令备忘单

  • 免费在线课程:RHEL 技术概述

  • Linux 网络备忘单

  • SELinux 备忘单

  • Linux常用命令备忘单

  • 什么是 Linux 容器?

  • 我们最新的 Linux 文章

Minix

在编写最初的 Linux 内核时,Linus Torvalds 需要一个文件系统,但当时不想编写。所以他简单地包含了Minix 文件系统,它是由Andrew S. Tanenbaum编写的,并且是 Tanenbaum 的 Minix 操作系统的一部分。Minix是为教育目的而编写的类 Unix 操作系统。它的代码可以免费获得并获得适当的许可,以允许 Torvalds 将其包含在他的第一个 Linux 版本中。

Minix 具有以下结构,其中大部分位于生成文件系统的分区中:

  • 引导扇区位于安装它的硬盘驱动器的第一个扇区中。引导块包括一个非常小的引导记录和一个分区表。

  • 每个分区中的第一个块是一个超级块,其中包含定义其他文件系统结构并将它们定位在分配给该分区的物理磁盘上的元数据。

  • inode 位图块,它决定了哪些 inode 被使用,哪些是空闲的。

  • inode,在磁盘上有自己的空间。每个 inode 包含有关一个文件的信息,包括数据块的位置,即属于该文件的区域。

  • 区域位图,用于跟踪已使用和空闲数据区域。

  • 数据区,实际存储数据的地方。

对于这两种类型的位图,一位代表一个特定的数据区域或一个特定的 inode。如果该位为零,则区域或 inode 空闲并可使用,但如果该位为 1,则数据区域或 inode 正在使用中。

什么是inode? index-node 的缩写,inode 是磁盘上的一个 256 字节块,用于存储有关文件的数据。这包括文件的大小;文件的用户和组所有者的用户 ID;文件模式(即访问权限);以及三个时间戳,指定时间和日期:文件上次访问、上次修改和 inode 中的数据上次修改。

inode 还包含指向文件数据在硬盘驱动器上的位置的数据。在 Minix 和 EXT1-3 文件系统中,这是数据区域或块的列表。 Minix 文件系统 inode 支持九个数据块,七个直接和两个间接。如果您想了解更多信息,请参阅 Wikipedia 上的Minix 文件系统结构和inode 指针结构的详细描述的优秀 PDF。

分机

最初的EXT 文件系统(扩展)由Rémy Card编写,并于 1992 年随 Linux 一起发布,以克服 Minix 文件系统的一些大小限制。主要的结构变化是文件系统的元数据,它基于 Unix 文件系统 (UFS),也称为伯克利快速文件系统 (FFS)。我发现很少有关于可以验证的 EXT 文件系统的已发布信息,显然是因为它存在重大问题并且很快被 EXT2 文件系统取代。

EXT2

EXT2 文件系统相当成功。它在 Linux 发行版中使用了很多年,它是我在 1997 年左右开始使用 Red Hat Linux 5.0 时遇到的第一个文件系统。EXT2 文件系统具有与 EXT 文件系统基本相同的元数据结构,但 EXT2 更先进- 看起来,因为元数据结构之间留有大量磁盘空间以供将来使用。

与 Minix 一样,EXT2 在其安装的硬盘的第一个扇区中有一个引导扇区,其中包括一个非常小的引导记录和一个分区表。然后在引导扇区之后有一些保留空间,它跨越引导记录和硬盘驱动器上的第一个分区之间的空间,通常在下一个柱面边界上。GRUB2— 可能还有 GRUB1 — 将这个空间用于它的部分引导代码。

每个 EXT2 分区中的空间被划分为柱面组,以便对数据空间进行更精细的管理。根据我的经验,组大小通常约为 8MB。下面的图 1 显示了气缸组的基本结构。柱面中的数据分配单元是块,通常大小为 4K。

气缸组-01_1.png

图 1:EXT 文件系统中柱面组的结构

柱面组中的第一个块是一个超级块,它包含定义其他文件系统结构并将它们定位在物理磁盘上的元数据。分区中的一些附加组将具有备份超级块,但不是全部。损坏的超级块可以通过使用 dd 之类的磁盘实用程序将备份超级块的内容复制到主超级块来替换。这种情况并不经常发生,但多年前曾经有一次,我有一个损坏的超级块,我能够使用其中一个备份超级块来恢复它的内容。幸运的是,我有先见之明,使用 dumpe2fs 命令转储了我系统上分区的描述符信息。

以下是 dumpe2fs 命令的部分输出。它显示了超级块中包含的元数据,以及文件系统中前两个柱面组中的每一个的数据。

# dumpe2fs /dev/sda1

文件系统卷名:boot

最后安装在: /boot

文件系统 UUID: 79fc5ed8-5bbc-4dfe-8359-b7b36be6eed3

文件系统幻数:0xEF53

文件系统修订号: 1(动态)

文件系统特性:有_journal ext_attr resize_inode dir_index 文件类型需要_recovery extent 64bit flex_bg sparse_super large_file huge_file dir nlink extra_isize

文件系统标志: signed_directory_hash

默认挂载选项: user_xattr acl

文件系统状态:干净

错误行为: 继续

文件系统操作系统类型:Linux

索引节点数: 122160

块数: 488192

保留块数:24409

空闲块: 376512

空闲索引节点: 121690

第一个区块: 0

块大小: 4096

片段大小: 4096

组描述符大小:64

保留的 GDT 块: 238

每组块数: 32768

每组片段: 32768

每组的索引节点: 8144

每组的 inode 块:509

弹性块组大小:16

创建的文件系统:2017 年 2 月 7 日星期二 09:33:34

上次挂载时间: 2017 年 4 月 29 日星期六 21:42:01

最后写入时间:2017 年 4 月 29 日星期六 21:42:01

挂载次数: 25

最大安装计数: -1

最后检查: 2017 年 2 月 7 日星期二 09:33:34

检查间隔: 0 (<none>)

终身写入: 594 MB

保留块 uid: 0(用户 root)

保留块 gid: 0(组根)

第一个索引节点: 11

索引节点大小: 256

所需的额外大小: 32

所需的额外尺寸: 32

日志索引节点: 8

默认目录哈希:half_md4

目录哈希种子: c780bac9-d4bf-4f35-b695-0fe35e8d2d60

日志备份: inode 块

日记功能: 日记_64位

期刊大小: 32M

期刊长度: 8192

日志序列: 0x00000213

日记开始: 0

第 0 组:(块 0-32767)

主超级块位于 0,组描述符位于 1-1

在 2-239 保留 GDT 块

块位图在 240 (+240)

255 (+255) 处的 inode 位图

索引节点表在 270-778 (+270)

24839 个空闲块,7676 个空闲 inode,16 个目录

空闲块:7929-32767

空闲索引节点:440、470-8144

第 1 组:(区块 32768-65535)

备份超级块在 32768,组描述符在 32769-32769

在 32770-33007 保留 GDT 块

块位图在 241 (bg #0 + 241)

256 处的 inode 位图 (bg #0 + 256)

索引节点表在 779-1287 (bg #0 + 779)

8668 个空闲块,8142 个空闲 inode,2 个目录

空闲块:33008-33283, 33332-33791, 33974-33975, 34023-34092, 34094-34104, 34526-34687, 34706-34723, 34817-35374, 35421-354, 35421-354 -36355, 36357-36863, 38912-39935, 39940-40570, 42620-42623, 42655, 42674-42687, 42721-42751, 42798-42815, 428247, 428247, 4248275-428279, 42943, 42975, 43000-43007, 43519, 43559-44031, 44042-44543, 44545-45055, 45116-45567, 45601-45631, 45658-456563, 45687--456567, 45687--4565659, 45687-\ , 45802-45823, 45857-45887, 45919, 45950-45951, 45972-45983, 46014-46015, 46057-46079, 46112-46591, 46921-47103, 49012-47103, 49012 -50355, 52237-52255, 52285-52287, 52323-52351, 52383, 52450-52479, 52518-52543, 52584-52607, 52652-52671, 527234-527334-527335,

空闲索引节点:8147-16288

第 2 组:(块 65536-98303)

块位图在 242 (bg #0 + 242)

257 处的 inode 位图 (bg #0 + 257)

索引节点表在 1288-1796 (bg #0 + 1288)

6326 个空闲块,8144 个空闲 inode,0 个目录

空闲块:67042-67583、72201-72994、80185-80349、81191-81919、90112-94207

空闲索引节点:16289-24432

第 3 组:(块 98304-131071)

<剪辑>

每个柱面组都有自己的 inode 位图,用于确定该组中使用了哪些 inode 以及哪些是空闲的。 inode 在每个组中都有自己的空间。每个 inode 包含有关一个文件的信息,包括属于该文件的数据块的位置。块位图跟踪文件系统中已使用和空闲的数据块。请注意,上面显示的输出中有大量关于文件系统的数据。在非常大的文件系统上,组数据可以长达数百页。组元数据包括组中所有空闲数据块的列表。

EXT 文件系统实施了确保最小文件碎片的数据分配策略。减少碎片提高了文件系统的性能。这些策略在下面关于 EXT4 的部分中进行了描述。

我在某些情况下遇到的 EXT2 文件系统的最大问题是崩溃后可能需要数小时才能恢复,因为 fsck(文件系统检查)程序需要很长时间才能找到并纠正任何文件系统中的不一致。曾经在我的一台计算机上,在崩溃后重新启动时完全恢复磁盘需要 28 多个小时——那时磁盘的大小只有数百兆字节。

zz100006 外部

EXT3 文件系统的唯一目标是克服 fsck 程序完全恢复因文件更新操作期间发生的不正确关闭而损坏的磁盘结构所需的大量时间。 EXT 文件系统的唯一补充是日志,它预先记录了将对文件系统执行的更改。磁盘结构的其余部分与 EXT2 中的相同。

EXT3 中的日志不像以前的版本那样直接将数据写入磁盘的数据区域,而是将文件数据及其元数据写入磁盘上的指定区域。一旦数据安全地保存在硬盘上,就可以将其合并或附加到目标文件中,丢失数据的可能性几乎为零。当这些数据被提交到磁盘的数据区域时,日志会被更新,以便在日志中的所有数据都被提交之前,如果系统发生故障,文件系统将保持一致的状态。在下次启动时,将检查文件系统是否存在不一致,然后将保留在日志中的数据提交到磁盘的数据区域以完成对目标文件的更新。

日志确实会降低数据写入性能,但是日志提供三个选项,允许用户在性能、数据完整性和安全性之间进行选择。我个人的偏好是出于安全考虑,因为我的环境不需要繁重的磁盘写入活动。

日志功能将故障后检查硬盘驱动器的不一致所需的时间从数小时(甚至数天)减少到最多几分钟。多年来,我遇到了许多让我的系统崩溃的问题。细节可以写另一篇文章,但只要说大多数都是自己造成的就足够了,就像踢掉电源插头一样。幸运的是,EXT 日志文件系统已将启动恢复时间缩短到两到三分钟。此外,自从我开始使用 EXT3 和日记功能以来,我从未遇到过丢失数据的问题。

可以关闭 EXT3 的日志功能,然后将其用作 EXT2 文件系统。日志本身仍然存在,空的和未使用的。只需使用 type 参数指定 EXT2 使用 mount 命令重新挂载分区。您可以从命令行执行此操作,具体取决于您使用的文件系统,但您可以更改 /etc/fstab 文件中的类型说明符,然后重新启动。我强烈建议不要将 EXT3 文件系统安装为 EXT2,因为这可能会导致丢失数据和延长恢复时间。

现有的 EXT2 文件系统可以通过使用以下命令添加日志来升级到 EXT3。

tune2fs -j /dev/sda1

其中 /dev/sda1 是驱动器和分区标识符。请务必更改 /etc/fstab 中的文件类型说明符并重新挂载分区或重新启动系统以使更改生效。

EXT4

EXT4 文件系统主要提高了性能、可靠性和容量。为了提高可靠性,添加了元数据和日志校验和。为了满足各种关键任务要求,文件系统时间戳得到了改进,增加了低至纳秒的间隔。在时间戳字段中添加两个高位位会将2038 年问题推迟到 2446 年——至少对于 EXT4 文件系统。

在 EXT4 中,数据分配从固定块更改为扩展。范围由其在硬盘驱动器上的开始和结束位置来描述。这使得在单个 inode 指针条目中描述非常长的、物理上连续的文件成为可能,这可以显着减少描述较大文件中所有数据的位置所需的指针数量。 EXT4 中还实施了其他分配策略,以进一步减少碎片。

EXT4 通过将新创建的文件分散在磁盘上来减少碎片,这样它们就不会像许多早期的 PC 文件系统那样聚集在磁盘开头的一个位置。文件分配算法尝试在柱面组之间尽可能均匀地分布文件,并且在需要碎片时,使不连续的文件范围尽可能靠近同一文件中的其他文件,以尽可能减少磁头寻道和旋转延迟尽可能。其他策略用于在创建新文件或扩展现有文件时预先分配额外的磁盘空间。这有助于确保扩展文件不会自动导致其碎片化。新文件永远不会在现有文件之后立即分配,这也防止了现有文件的碎片。

除了磁盘上数据的实际位置之外,EXT4 还使用功能策略,例如延迟分配,以允许文件系统在分配空间之前收集所有写入磁盘的数据。这可以提高数据空间连续的可能性。

较旧的 EXT 文件系统,例如 EXT2 和 EXT3,可以作为 EXT4 挂载来获得一些小的性能提升。不幸的是,这需要关闭 EXT4 的一些重要新功能,所以我建议不要这样做。

自 Fedora 14 以来,EXT4 一直是 Fedora 的默认文件系统。可以使用 Fedora 文档中描述的过程将 EXT3 文件系统升级到 EXT4,但是由于残留的 EXT3 元数据结构,它的性能仍然会受到影响。从 EXT3 升级到 EXT4 的最佳方法是备份目标文件系统分区上的所有数据,使用 mkfs 命令将一个空的 EXT4 文件系统写入分区,然后从备份中恢复所有数据。

索引节点

之前描述的 inode 是 EXT 文件系统中元数据的关键组件。图 2 显示了 inode 与存储在硬盘上的数据之间的关系。此图是单个文件的目录和 inode,在这种情况下,可能是高度碎片化的。 EXT 文件系统积极工作以减少碎片,因此您不太可能看到包含这么多间接数据块或范围的文件。事实上,正如您将在下面看到的,EXT 文件系统中的碎片极少,因此大多数 inode 将仅使用一两个直接数据指针,而没有使用间接指针。

inodesanddataallocation-01_0.png

图 2:inode 存储有关每个文件的信息,并使 EXT 文件系统能够找到属于它的所有数据。

inode 不包含文件名。对文件的访问是通过目录条目,它本身就是文件的名称并包含指向 inode 的指针。该指针的值是 inode 编号。文件系统中的每个 inode 都有一个唯一的 ID 号,但同一台计算机(甚至同一个硬盘驱动器)上的其他文件系统中的 inode 可以具有相同的 inode 号。这对链接有影响,这个讨论超出了本文的范围。

inode 包含有关文件的元数据,包括其类型和权限以及大小。 inode 还包含 15 个指针的空间,这些指针描述了柱面组数据部分中数据块或扩展区的位置和长度。十二个指针提供对数据范围的直接访问,应该足以处理大多数文件。但是,对于具有大量碎片的文件,有必要以间接节点的形式具有一些附加功能。从技术上讲,这些并不是真正的 inode,因此为了方便起见,我在这里使用术语“节点”。

间接节点是文件系统中的普通数据块,仅用于描述数据,不用于存储元数据,因此可以支持超过 15 个条目。例如,一个 4K 的块大小可以支持 512 个 4 字节的间接节点,单个文件允许 12(直接)+ 512(间接)u003d 524 个扩展。还支持双重和三重间接节点支持,但我们大多数人不太可能遇到需要这么多范围的文件。

数据碎片

对于许多较旧的 PC 文件系统,例如 FAT(及其所有变体)和 NTFS,碎片一直是一个严重的问题,导致磁盘性能下降。碎片整理本身就成为了一个行业,拥有不同品牌的碎片整理软件,从非常有效到仅勉强有效。

Linux 的扩展文件系统使用数据分配策略,有助于最大限度地减少硬盘驱动器上的文件碎片,并在碎片发生时减少碎片的影响。您可以在 EXT 文件系统上使用 fsck 命令来检查文件系统的总碎片。下面的示例检查我的主工作站的主目录,它只有 1.5% 的碎片。请务必使用 -n 参数,因为它会阻止 fsck 对扫描的文件系统执行任何操作。

fsck -fn /dev/mapper/vg_01-home

我曾经进行了一些理论计算来确定磁盘碎片整理是否会导致任何明显的性能改进。虽然我做了一些假设,但我使用的磁盘性能数据来自一个新的 300GB 西部数据硬盘,磁道到磁道的寻道时间为 2.0ms。此示例中的文件数是我进行计算当天文件系统中存在的实际数量。我确实假设每天都会接触到相当大量的碎片文件(20%)。

文件总数

271,794

% 碎片

5.00%

不连续性

13,590

每天接触的碎片文件百分比

20%(假设)

额外寻道次数

2,718

平均寻道时间

10.90 毫秒

每天的总额外寻道时间

29.63 秒

0.49 分钟

磁道到磁道寻道时间

2.00 毫秒

每天的总额外寻道时间

5.44 秒

0.091 分钟

表 1:碎片对磁盘性能的理论影响

我对每天的总额外寻道时间进行了两次计算,一次基于磁道到磁道的寻道时间,由于 EXT 文件分配策略,这对于大多数文件来说更可能发生,另一种是平均寻道时间,我认为这将是一个公平的最坏情况。

正如您从表 1 中看到的,碎片对现代 EXT 文件系统的影响对于大多数应用程序来说都是最小的并且可以忽略不计。您可以将环境中的数字插入到您自己的类似电子表格中,以查看您对性能影响的预期。这种类型的计算很可能不会代表实际性能,但它可以提供一些关于碎片及其对系统的理论影响的洞察力。

我的大部分分区大约有 1.5% 或 1.6% 是碎片化的;我确实有一个碎片率为 3.3%,但它是一个 128GB 的大型文件系统,只有不到 100 个非常大的 ISO 映像文件;多年来,由于分区太满,我不得不多次扩展分区。

这并不是说某些应用程序环境不需要更大的保证,甚至更少的碎片。知识渊博的管理员可以仔细调整 EXT 文件系统,他们可以调整参数以补偿特定的工作负载类型。这可以在创建文件系统时或稍后使用 tune2fs 命令完成。应测试、仔细记录和分析每个调整更改的结果,以确保目标环境的最佳性能。在最坏的情况下,性能无法提高到所需水平,其他文件系统类型可能更适合特定工作负载。请记住,在单个主机系统上混合文件系统类型以匹配每个文件系统上的负载是很常见的。

由于大多数 EXT 文件系统上的碎片量很少,因此没有必要进行碎片整理。无论如何,EXT 文件系统没有安全的碎片整理工具。有一些工具可让您检查单个文件的碎片或文件系统中剩余可用空间的碎片。有一个工具,e4defrag,它将在剩余可用空间允许的范围内对文件、目录或文件系统进行碎片整理。顾名思义,它只适用于 EXT4 文件系统中的文件,并且确实有一些限制。

如果有必要对 EXT 文件系统执行完整的碎片整理,那么只有一种方法可以可靠地工作。您必须从文件系统中移动所有文件以进行碎片整理,确保在安全复制到另一个位置后将其删除。如果可能,您可以增加文件系统的大小以帮助减少未来的碎片。然后将文件复制回目标文件系统。即使这样也不能保证所有文件都将被完全碎片整理。

结论

20 多年来,EXT 文件系统一直是许多 Linux 发行版的默认设置。它们提供稳定性、高容量、可靠性和性能,同时需要最少的维护。我尝试过其他文件系统,但总是返回到 EXT。我在 Linux 上工作过的每个地方都使用过 EXT 文件系统,并且发现它们适用于它们上使用的所有主流负载。毫无疑问,EXT4 文件系统应该用于大多数 Linux 系统,除非有令人信服的理由使用另一个文件系统。

Logo

更多推荐