Linux ext2, ext3, ext4 文件系统解读[4]

时间:2022-01-04 19:35:27


ext2 ext3 ext4 文件系统的区别:

ext2为非日志文件系统,即在文件系统的运行期间不会记录写操作的日志,这就有一个很大的弊端,即文件系统只能单纯依靠InodeData BlockBitmap来确定数据写入的状态。

我们先来了解一下写入数据的一些具体的步骤:

  1. 当用户尝试写入一个文件时,首先系统判断当前用户对于这个文件尝试写入的目录是否有写权限,如果有权限的话才允许写入。
  2. 文件系统根据Inode Bitmap找到第一个未使用的Inode,得到Inode的编号,将文件权限和属性写入Inode结构中。
  3. 文件系统根据Data Block Bitmap找到未使用的Data Block,将文件内容写入其中,并将Inode中的Data Block指针指向Data Block,如果一块Data Block不足以存放文件内容,就再找下一块Data Block,如果直接块不足以存放内容,就在间接块中进一步分配空间。
  4. Data Block数据写完并且Inode中的指针更新完成后,会更新Inode BitmapData Block Bitmap,将占用的InodeData Block对应的比特标记为0(使用中)。
  5. 最后会更新Super Block的内容(更新空闲和使用的数量)。

 

数据不一致:

通常我们将InodeData Block中的数据称为数据部分,将Super Block/Inode Bitmap/Data Block Bitmap称为元数据(Metadata)。从上面数据写入的过程可以很容易看到问题,如果在意外情况下(例如掉电,Kernel Crash,读写异常等等),数据写入成功,但是元数据没有完成写入,这时就会出现元数据与实际数据不一致的情况。当出现这种不一致的情况时,可以通过文件系统自检来针对数据一致性进行检查(fsck),一致性检查要遍历整个文件系统,根据元数据中的标志位来与实际数据存放进行对比,如果文件数量和大小很多,那么整个过程的耗时就会非常长。

为了克服上述的问题,在ext3中引入了日志功能,ext3文件系统由ext2发展而来(二者的Magic Number都是一样的,可见其兼容性),ext3文件系统本身的数据结构(例如Super BlockInodeGroup DescriptorDir Entry等)基本与ext2一致,可以完全兼容ext2文件系统,使得用户可以平滑地过度到一个带有日志功能的文件系统中。

引入日志功能后,文件系统会划分出部分Block用于日志的写入,当进行文件写入时,系统首先会把待写的Block数据写入日志中,当数据成功提交到日志中后,会进一步向文件系统的Data Block中提交,数据成功提交到文件系统后,日志中的临时数据就会被丢弃。

当出现系统故障,通过fsck进行一致性检查和恢复的时候,会存在以下两种情况:

  1. 数据在提交到日志之前发生系统故障,此时数据还没有向文件系统中写入,fsck会直接忽略这次提交的内容,保证元数据和数据的一致性,但是此次写入的数据就丢失了。
  2. 数据提交到日志之后,尚未完全写入文件系统之前,发生系统故障,此时在进行fsck的时候,会重新将日志中的临时写入数据提交到文件系统中,保证数据一致性,同时此次写入操作能够正常完成。

从上面的两种情况可以看到,引入日志系统后,能够保证数据一致性,但是并不能保证数据不丢失。

ext3支持三种日志模式,区别是写入日志的Block是元数据的Block还是Data Block,以及何日提交日志:

  1. Journal:文件系统所有数据和元数据的改变都要提交到日志,这种模式下会减少所有Block丢失数据以及数据不一致的可能性,但是会有相当大的磁盘空间被日志Block占用,当一个文件被创建时,所有的Data Block在提交前都会提交到日志,相当于所有数据写入都执行了两次(一次对日志,一次对文件系统本身),所以这是最安全但是最慢的日志模式。
  2. Ordered:只有对元数据的改变才会提交到日志,这种模式下能够确保数据一致性,但是对于文件内容的可靠性不做保证。尽管这种情况下并不保证文件内容,但是在元数据修改之前,会先提交文件内容,然后再提交元数据对应的Block到日志,最后再提交到文件系统。这个模式会对文件系统的性能有少量影响。Ordered模式是ext3文件系统的默认日志模式。
  3. Writeback:只有对元数据的改变才会提交到日志,但是和Ordered模式不同的是,这个模式下文件数据提交后和元数据的更新可以异步进行,由于元数据的更新不会等文件数据提交后进行,所以很有可能出现元数据更新已经完成,但是文件数据还没有完成提交,造成数据不一致的情况。

上面三种日志模式,可以在手动mount的时候通过-o参数指定,也可以在/etc/fstab中指定,例如:

[root@DanCentOS65 daniel]# mount -o data=writeback /dev/sde1 /mnt/sde

[root@DanCentOS65 daniel]# mount -v

/dev/sda1 on / type ext4 (rw)

proc on /proc type proc (rw)

sysfs on /sys type sysfs (rw)

devpts on /dev/pts type devpts (rw,gid=5,mode=620)

tmpfs on /dev/shm type tmpfs (rw)

none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

/dev/sdb1 on /mnt/resource type ext4 (rw)

/dev/sdd1 on /mnt/sdd type ext4 (rw)

/dev/sdc1 on /mnt/sdc type ext2 (rw)

/dev/sde1 on /mnt/sde type ext3 (rw,data=writeback)

# /etc/fstab

# Created by anaconda on Tue Mar 29 17:12:12 2016

#

# Accessible filesystems, by reference, are maintained under '/dev/disk'

# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#

UUID=8fc4d768-29cd-462c-a7ab-5bf4bcfa9fa2 /    ext4    defaults        1 1

tmpfs                  /dev/shm                tmpfs   defaults        0 0

devpts                 /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                  /sys                    sysfs   defaults        0 0

proc                   /proc                   proc    defaults        0 0

/dev/sde1              /mnt/sde                ext3    data=writeback  0 0

ext3日志可以存储到一个文件中,也可以存放在单独的设备中,可以在建立文件系统的时候,指定将日志记录到其他设备上,例如:

[root@DanCentOS65 daniel]# mkfs.ext3 -J device=/dev/sdf1 /dev/sdc1

文件系统本身并不处理日志,而是通过日志块设备(Journaling Block DeviceJBD)的通用内核层进行处理。

ext3文件系统与JBD的交互过程主要基于三个单元:

  1. 日志记录:用于描述文件系统的一次低级操作,在某些日志系统中,日志记录只包括操作所修改的数据范围以及起始位置。JBD使用的日志记录由一次低级操作所包含的数据缓冲区组成,JBD直接对缓冲区和其首部操作。
  2. 原子操作(Atomic handle):一个原子操作是指发生在一次文件系统的高级更新内的所有低级操作,一个原子操作保证在对应的日志提交后才会将数据向文件系统中提交。当系统故障时,文件系统确保原子操作要么提交成功,要么所有该原子操作对应的低级操作都回滚。
  3. 事务(Transaction):处于管理的方便以及性能考虑,JBD将一组原子操作合并为一个事务,每隔一段时间会将日志中的内容同步到文件系统中,或者当日志空间中没有多余的可写空间时,事务的日志会同步到文件系统中。事务会在多个状态之间切换:

运行(Running):表示事务可以接收和处理更多的原子操作

锁定(Locked):不接收新的原子操作,所有已接受的原子操作尚未完成

同步(Flush):事务已完成,正在向提交日志

提交(Commit):日志提交完成,正在向文件系统提交数据

完成(Finished):数据已经全部提交到文件系统中,可以删除此事务

 

ext3日志文件系统的几个特点:

  1. 高可用性:即使是系统故障之后,也不需要进行文件系统自检,通常恢复的过程非常短。
  2. 数据完整性:能够极大提高数据一致性,保证文件系统的完整性,减少系统故障对文件系统的破坏。
  3. 访问速度:尽管ext3文件系统启用了日志功能后,会增加写入磁盘的次数,但是从整体上来看,ext3仍然比ext2性能要好一些,这是因为ext3的日志功能对磁盘驱动器的读写头进行了一些优化,所以从读写性能上看,ext3ext2并没有降低。
  4. 数据转换:ext2文件系统不需要重新格式化,可以通过tune2fs直接将ext2文件系统转换为ext3,例如:

[root@DanCentOS65 daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext2 (rw)

[root@DanCentOS65 daniel]# umount /dev/sdc1

[root@DanCentOS65 daniel]# tune2fs -j /dev/sdc1

tune2fs 1.41.12 (17-May-2010)

Creating journal inode: done

This filesystem will be automatically checked every 31 mounts or

180 days, whichever comes first. Use tune2fs -c or -i to override.

[root@DanCentOS65 daniel]# mount /dev/sdc1 /mnt/sdc

[root@DanCentOS65 daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext3 (rw)

也可以在不修改ext3文件系统的前提下,直接将其重新挂载为ext2文件系统。

  1. 日志模式:ext3的三种不同的日志模式可以让系统管理员根据实际情况在速度和稳定性之间进行灵活配置。

 

ext4文件系统:

ext4文件系统是ext3的改进版,从前面的描述中我们可以看到,ext3仅仅是在ext2文件系统上增加了一个日志功能而已,而ext4则针对ext2/ext3的重要数据结构进行了调整优化,使其可以提供更好的性能和稳定性,以及更为丰富的功能。

ext2转换为ext3一样,无需重新格式化,就可以将ext3文件系统更新为ext4,原有ext3的数据结构依然保留,ext4作用与新的数据。例如:

[root@DanCentOS65 daniel]# umount /dev/sdc1

[root@DanCentOS65 daniel]# tune2fs -O extents,uninit_bg,dir_index /dev/sdc1

tune2fs 1.41.12 (17-May-2010)

Please run e2fsck on the filesystem.

[root@DanCentOS65 daniel]# fsck /dev/sdc1

......

Group descriptor 8181 checksum is invalid. FIXED.

Group descriptor 8182 checksum is invalid. FIXED.

Group descriptor 8183 checksum is invalid. FIXED.

/dev/sdc1 contains a file system with errors, check forced.

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Checking reference counts

Pass 5: Checking group summary information

/dev/sdc1: 23/1047552 files (0.0% non-contiguous), 134133/268173037 blocks

[root@DanCentOS65 daniel]# mount /dev/sdc1 /mnt/sdc

[root@DanCentOS65 daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext4 (rw)

ext3相比,ext4有如下新的特性:

  1. 支持更大的文件系统总大小和更大的单个文件大小,ext4支持的最大文件系统大小为1EB,最大16TB的单个文件。
  2. 支持无限数量的子目录,ext3目前最多支持32000个子目录。
  3. ext3采用间接块映射,当文件大小非常大的时候,通过二级和三级间接块查找文件内容效率极低,与之相比,ext4中引入了extents的概念,每个extent为一组连续数据块,一个大文件会被分解保存在多个extents中,从而大大提高了大文件的访问效率,减少碎片文件。
  4. 当文件写入ext3文件系统时,文件系统的数据块分配器每次只能分配一个Block,而ext4文件系统可以一次调配多个Block,减少在写入文件时Block的调配次数。
  5. ext3的块分配策略是尽快分配,而ext4则尽可能地延迟分配,直到文件在缓存中写完才开始进行数据块的分配,这样能够极大地优化数据块的分布,从而提高后续文件读取的性能。
  6. 对于ext4文件系统来说,系统会维护一个未使用的Inode的表,当进行磁盘自检的时候,会跳过这个表中的Inode,只检查使用中的Inode,而对ext3文件系统fsck则会逐个检查Inode,这个机制使得ext4的自检速度要比ext3快很多。不过需要注意的是,这个Inode表并不是由ext4文件系统维护的,而是由fsck来维护的,所以首先需要执行过一次fsck,才能够在下次fsck的时候得到速度上的优化。
  7. 日志功能对于文件系统而言至关重要,如果日志本身出现问题,而恰好我们又使用这个异常的日志来进行文件系统的恢复的话,那么会导致文件系统更严重的错误。因此,在ext4文件系统中,加入了日志数据校验的功能,能够及时发现日志中潜在的错误。同时,ext4中还将ext3中的日志提交和文件系统数据的提交合并到一起,从而进一步提升约20%左右的性能。
  8. 磁盘碎片的产生在所难免,ext4支持在线碎片整理,在整理时能够保证文件的正常访问。
  9. ext4Inode的默认大小改为256字节,增加的空间用来存放更多的节点信息和扩展属性(例如纳秒时间戳,Inode版本等等),以提升文件的访问速度。节点预留机制:当一个目录被建立时,若干个Inode会被预留出来,以加速文件的建立。
  10. 很多软件为了保证下载文件有足够的空间来存放,通常会提前创建一个与下载文件大小相同的空文件,ext4文件系统中实现了与非陪的机制并提供了相应的API
  11. 默认启用barrier,以保证数据完整性。