什么是journal日志

作为日志文件系统,ext4使用journal来对文件系统操作进行记录,它和文件系统数据是分开进行管理的,当我们写入文件系统时,会先把最新的数据保存在journal区域中,然后再写入到真正文件系统中,当多次写入时会不停的更新journal中的数据内容,以保持最新的写入数据。这样做保证了文件系统的可靠性,并且当文件系统出现问题时,利于分析问题。

journal block的创建

那么这个journal区域是在什么时候创建的呢?
使用Linux系统中的mkfs.ext4命令创建一个ext4文件系统(实际上调用的是mke2fs工具),从下面的输出log可以看到,对应的ext4文件系统会创建journal block。

$ dd if=/dev/zero of=test.img bs=1M count=512
$ mkfs.ext4 test.img 
mke2fs 1.42.13 (17-May-2015)
Discarding device blocks: 完成                            
Creating filesystem with 131072 4k blocks and 32768 inodes
Filesystem UUID: 6482c469-a195-48d0-bed4-2033baec77c4
Superblock backups stored on blocks: 
	32768, 98304

Allocating group tables: 完成                            
正在写入inode表: 完成                            
Creating journal (4096 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

可以通过如下命令选项对journal的区域大小进行配置:

-J size=64

这个选项传入参数的单位是M字节,默认为64M大小。我们修改为32M可以使用如下命令:

mkfs.ext4 -J size=32 test.img

通过挂载上该文件系统镜像后进入挂载目录查看df信息,可以发现原本生成的一个512M的文件系统大小,只剩余472M的总容量,那么其他的容量在哪里?
实际上这里显示的总容量并没有包含journal区域和superblock以及superblock备份区域,因此它显示的总容量是少于原本镜像的大小的。

$ df . -h
文件系统        容量  已用  可用 已用% 挂载点
/dev/loop0      472M  396K  436M    1% /media/xiehaocheng/test

可以使用dumpe2fs来查看该文件系统相关的metadata信息:

dumpe2fs 1.42.13 (17-May-2015)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          d6193181-b0c1-41b4-8c4e-4629636209fa
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              32768
Block count:              131072
Reserved block count:     6553
Free blocks:              120719
Free inodes:              32757
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      31
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Mon Aug 19 19:19:45 2019
Last mount time:          Mon Aug 19 19:20:43 2019
Last write time:          Mon Aug 19 19:20:43 2019
Mount count:              1
Maximum mount count:      -1
Last checked:             Mon Aug 19 19:19:45 2019
Check interval:           0 (<none>)
Lifetime writes:          32 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:	          256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      0c1a2d41-bbf6-4a73-a2fc-93125b58521a
Journal backup:           inode blocks
Journal features:         (none)
日志大小:             32M
Journal length:           8192
Journal sequence:         0x00000002
Journal start:            1


Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
  Checksum 0x5742, unused inodes 8181
  主 superblock at 0, Group descriptors at 1-1
  保留的GDT块位于 2-32
  Block bitmap at 33 (+33), Inode bitmap at 37 (+37)
  Inode表位于 41-552 (+41)
  30673 free blocks, 8181 free inodes, 2 directories, 8181个未使用的inodes
  可用块数: 2095-32767
  可用inode数: 12-8192
Group 1: (Blocks 32768-65535) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x4075, unused inodes 8192
  备份 superblock at 32768, Group descriptors at 32769-32769
  保留的GDT块位于 32770-32800
  Block bitmap at 34 (bg #0 + 34), Inode bitmap at 38 (bg #0 + 38)
  Inode表位于 553-1064 (bg #0 + 553)
  32735 free blocks, 8192 free inodes, 0 directories, 8192个未使用的inodes
  可用块数: 32801-65535
  可用inode数: 8193-16384
Group 2: (Blocks 65536-98303) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0xe120, unused inodes 8192
  Block bitmap at 35 (bg #0 + 35), Inode bitmap at 39 (bg #0 + 39)
  Inode表位于 1065-1576 (bg #0 + 1065)
  24576 free blocks, 8192 free inodes, 0 directories, 8192个未使用的inodes
  可用块数: 73728-98303
  可用inode数: 16385-24576
Group 3: (Blocks 98304-131071) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0xc611, unused inodes 8192
  备份 superblock at 98304, Group descriptors at 98305-98305
  保留的GDT块位于 98306-98336
  Block bitmap at 36 (bg #0 + 36), Inode bitmap at 40 (bg #0 + 40)
  Inode表位于 1577-2088 (bg #0 + 1577)
  32735 free blocks, 8192 free inodes, 0 directories, 8192个未使用的inodes
  可用块数: 98337-131071
  可用inode数: 24577-32768

journal挂载选项

关于挂载选项可以参考内核文档,linux/Documentation/filesystems/ext4.txt:

 data=journal        All data are committed into the journal prior to being
             written into the main file system.  Enabling
             this mode will disable delayed allocation and
             O_DIRECT support.
 
 data=ordered    (*) All data are forced directly out to the main file
             system prior to its metadata being committed to the
             journal.
 
 data=writeback      Data ordering is not preserved, data may be written
             into the main file system after its metadata has been
             committed to the journal.

和journal有关的如上所述,主要分为三种数据写入方式:

  • journal方式

所有数据(data+metadata)在被写入文件系统前,都要先写入到journal区域,可靠性很好,但是性能却最差。

  • ordered方式

这种方式不用记录data,但是需要在data写入文件系统之后,把metadata写入到journal区域,相比前一种提高了性能,稍微降低的可靠性。

  • writeback

这种方式不用记录data,只需要把metadata写入到journal区域,但不保证data已经写入文件系统,所以它的可靠性最差。

默认挂载方式采用的是ordered方式,这种方式是另外两种的一种平衡,使得可靠性和性能都能达到一个均衡。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐