文件系统原理

文档状态:编辑中....



[网评]

设计

  1. 文件系统使用者的特征是什么?大文件居多还是小文件居多?如果基本都是大文件应用,那么数据块可以做的大一点,使得元数据信息少点,减少这方面的开销。
    例如淘宝的TFS集群文件系统,由于系统前端采用了大量的缓存,从而使得TFS的输入全是大文件,因此可以采用大文件设计思想对其进行优化,可以减少目录层次,这样在检索一个文件的时候,不需要花费太多的时间,这种处理可以提升系统性能。

  2. 文件系统是读应用为主还是写应用为主?这点也是很重要的,如果是写为主的应用,那么可以采用log structured的方式优化IO pattern
    例如在备份系统中,基本都是以写请求,那么对于这样的系统,可以采用log structured的方式使得底层IO更加顺序化。

  3. 文件系统的可扩展性,其中包括随着磁盘容量的增长,文件系统是否可以无缝扩展?
    例如以前的FAT文件系统由于元数据的限制,对支持的容量有着很强的限制。而中科蓝鲸的BWFS元数据和数据IO流分离,可以达到很高的集群性能,但是,这种架构也有一个问题,当应用文件以小文件为主的时候,元数据服务器会成为整个系统的性能瓶颈。因为局部性原理,并且元数据与数据分开写致使出现抖动现象.所以可以对元数据进行缓存.

  4. 数据在磁盘上如何布局?数据在磁盘上的不同布局会对文件系统的性能产生很大的影响。
    如果元数据信息离数据很远,那么一次写操作将会导致剧烈的磁盘抖动。EXT3将整个磁盘空间划分成多个块组让元数据与数据信息离得很近.

  5. 数据安全性如何保证?如果文件系统的元数据遭到了破坏,如何恢复文件数据?如果用户误删了文件,如何恢复用户的数据?这些都需要文件系统设计者进行仔细设计。

  6. 如何保证操作事务的一致性?对于一次写操作设计到元数据更新和文件数据的更新,这两者之间的操作次序如何设计?既能保证很好的性能,又能在系统crash的时候保证文件系统的一致性?在很多设计中采用数据先于元数据的方式,并且通过日志机制保证事务一致性。

  7. 文件系统元数据占用多少系统内存?如果一个文件系统占用太多的系统内存,那么会影响整个系统的性能

messy

文件访问控制的演变

访问策略

  1. 添加ACL(access-control list)即访问控制列表

    • 优:自主选择让谁用,不让谁用
    • 缺:需事先知道系统的用户列表,且列表长度会扩大
    • 应用范围:用户数量较少且固定已知身份id的系统 比如(局域网络系统)
  2. 用户组控制

    • 优:用户多时方便统一授权,不必每个用户单独设置访问权限
    • 缺:不能说有缺点吧
    • 局限:需要联合用户授权机制使用,系统应该提供用户默认的用户组
    • 应用范围:大量用户,需要对数据严格控制的系统.比如:(数据库管理系统)

superblock

对于ex系列文件系统来说,存储在分区的第二个block(令一个大小为1k),平时的时候为了提高检索速度,这个元信息会加载到内存中,让我们观察一下。

  • 工具
    fdisk&vim&dumpe2fs&dd&/usr/include/linux/extn_fs.h

操作

  1. fdisk -l
    得知文件系统在/dev/sda7
  2. dd if=/dev/sda7 bs=1k(amount/per) skip=1(offset) count=1(times) of=superblock
  3. vim superblock+:%! xxd
    od -x superblock
  4. 再开一个终端dumpe2fs /dev/sda7 |grep "Inode count"
  5. 根据小端法阅读superblock对照Inode count

结果

  1 00000000: 0020 7302 0064 cc09 666b 7d00 5726 7e09  . s..d..fk}.W&~.
  2 00000010: 8d4b 6e02 0000 0000 0200 0000 0200 0000  .Kn.............
  3 00000020: 0080 0000 0080 0000 0020 0000 8a6a 7d5a  ......... ...j}Z
  4 00000030: 756a 7d5a 1b00 ffff 53ef 0100 0100 0000  uj}Z....S.......
  5 00000040: 451d 725a 0000 0000 0000 0000 0100 0000  E.rZ............
  6 00000050: 0000 0000 0b00 0000 0001 0000 3c00 0000  ............<...
  7 00000060: 4602 0000 7b00 0000 b70d a271 346b 4ff6  F...{......q4kO.
  8 00000070: 954b cb93 5b23 9512 0000 0000 0000 0000  .K..[#..........
  9 00000080: 0000 0000 0000 0000 2f00 6172 6765 7400  ......../.arget.
 10 00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 11 000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 12 000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 13 000000c0: 0000 0000 0000 0000 0000 0000 0000 d803  ................
 14 000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 15 000000e0: 0800 0000 0000 0000 9505 0401 df82 d27e  ...............~
 16 000000f0: 0536 4cce 86b3 2a8c 0c06 0730 0101 0000  .6L...*....0....
 17 00000100: 0c00 0000 0000 0000 451d 725a 0af3 0200  ........E.rZ....
 18 00000110: 0400 0000 0000 0000 0000 0000 ff7f 0000  ................
 19 00000120: 0080 e004 ff7f 0000 0100 0000 ffff e004  ................
 20 00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 21 00000140: 0000 0000 0000 0000 0000 0000 0000 0008  ................
 22 00000150: 0000 0000 0000 0000 0000 0000 1c00 1c00  ................
 23 00000160: 0100 0000 0000 0000 0000 0000 0000 0000  ................

0020 7302小端阅读 02732000(16)=>41099264(10)

dumpe2fs结果

dumpe2fs 1.42.13 (17-May-2015)
Inode count:              41099264
Journal inode:            8

ok!
自行对应数据结构

日志系统

Ext3的日志特性主要是依靠其下层一个名为“日志块设备层”的中间设备来完成,叫做JBD(Journaling Block Device layer 简称JBD)。JBD并不是文件系统规范的一部分,它和ext3文件系统的规范是没有任何的关系的,而JBD正是文件系统事务处理功能的实现基础。简而言之,JBD被设计成在任何块设备上实现日志的特殊目的.
Ext3 通过“钩入(hooking in)”JBD的API 来实现其日志记录的功能。

iNode

  1. 文件的时间戳,共有三个:
  2. ctime指inode上一次变动的时间
  3. mtime指文件内容上一次变动的时间
  4. atime指文件上一次打开的时间。

inode大小

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

tips

  • mount命令查看文件系统的日志记录模式
    Ext3文件系统提供了三种记录日志的方式:
    日志模式data=journal:这种模式会记录所有对文件数据和元数据的修改.首先将元数据和数据写进日志,然后再写进相应的磁盘位置。该方式提供了很高安全性,不论系统在元数据写入日志阶段还是实际数据写入日志阶段发生崩溃,均不影响实际的主文件系统。这种模式将丢失数据的风险降到最低但也付出了效率的代价,因为所有数据都要写入两次.
    顺序模式data=ordered:这种模式只会记录对文件系统元数据的修改。首先将文件数据写入磁盘,然后将元数据写进日志,最后再把元数据写进磁盘。通过记录元数据的方式足以恢复磁盘文件系统数据结构的一致性,但由于文件数据不写入日志的原因,还是无法防止系统故障对文件内容造成的损害。
    回写模式data=writeback:这种模式也只记录对元数据的修改。先把数据写入磁盘,然后将元数据先写入日志再写入磁盘。但数据和元数据的写入没有固定的先后顺序。这种模式由于对文件数据的更改和文件元数据的修改时异步进行的,所以有可能出现文件系统中元数据不一致的情况

  • dumpe2fs -h查看日志分区大小

  • 根据Journal inode号查看信息
    echo "stat <inode number>" |debugfs /dev/sda7
  • superblock损坏怎么办
  • 带参数程序修复[fsck]
  • 手动使用命令修复
    可以使用 dumpe2fs /dev/sda1 | grep -i superblock 来查看 sda1 分区的 superblock 备份有哪一份是可用的。我们假设 dumpe2fs 输出了这样一行:Backup superblock at 163840, Group descriptors at 163841-163841 ,通过这条信息,我们就可以尝试使用这个 superblock 备份:/sbin/fsck.ext3 -b 163840 -B 1024 /dev/sda1。请注意,这里我们假设 block 的大小为 1024 字节。
  • format
    [meta@meta ~]# mkfs.ext4 -I 2048 -b 2048 /dev/sdb1
    [meta@meta ~]# dumpe2fs /dev/sdb1 |grep "Block size"
    Block size: 2048
  • 简单查看磁盘使用情况
    df -h

FAQ

  1. 一个100M的磁盘分区,分别写入1K和1M的文件,分别可以写多少个?
假设inode size=128byte  block size=1024byte  可写入1k文件100000000/(128+1024) 可写入1M文件  100000000/(1048576+128)  
假设inode size=256byte  block size=4096byte  可写入1k文件100000000/(256+4096)  可写入1M文件 100000000/1048576+256)  

Reference

[1].Inode