现在图书管担任管理大量图书的工作。试想一下,如果图书馆的图书管理人员没有把书进行分类,而是直接把书摆在书架上。那么来图书管查找相关书籍的人想找历史方面或者科学方面的书籍,他该怎么查找呢?很显然他得把整个图书馆的图书全都查找一遍,如果他足够幸运,第一本就是他想找的书籍;换句不好听的话说,如果他不够幸运,最后一本书才是他想找的那本......你可以想象他浪费了多少时间。
然而在现实生活中图书馆并不是把所有的书直接放在书架上,而是对图书进行分类,科学类的放在第一个书架上,历史类的放在第二个书架上,文学类的放在第四个和第五个书架上。采用这种方式之后,假设你去图书馆想找历史方面的书籍,那么你只需要到历史图书所在的书架上找你所需要的书籍。这会大大缩减你找到你所需要的书籍的时间。
在某些比较大的图书馆中。他不光是把图书进行分类,他会图书一层大厅设立一个信息牌,上面指明,历史类书籍在第二层的第几个图书室,科学类的书籍在第三次的第几个图书室......,并且在每个图书室的也有信息牌。以历史类的为例:上面说明关于汉朝历史的书籍在第几个书架上,唐朝历史的书籍在第几个书架上,近代历史的书籍在第几个书架上。通过这种手段,每个不同的人到图书馆找书的时候,只需要进入图书馆大厅,看一下信息牌查找所需要的书在第几层的第几个图书室,然后到达相关图书室的门外,再看一下信息牌查找所需要的书大概在哪个书架,而后就可以快速的找到所需要的书籍了。从理论上来说,每个人需要的书籍只要图书馆中有,那么查找到书籍的时间几乎都是相同的。
文件系统从某种角度来看,可以说是一个比较的大图书馆。它用某种方式在磁盘上组织大量的文件,而不同文件系统的文件组织方式可能并不相同。试想一下,如果你把100G的数据都放在磁盘上,而磁盘上并没有文件系统,直接堆在硬盘中。但程序运行时的数据在内存中可能并不存在,那么程序就需要告诉内核,我要找磁盘上的某个数据,内核就会去磁盘上查找相关数据,由于磁盘上并没有创建文件系统,那么内核就需要遍历整个磁盘,直到找到数据为止。如果数据是在最后被找到呢?你可以想象内核为程序找到相关数据花费了多长的时间。
因此计算机的磁盘上必然是需要一种特定的方式来组织磁盘存储的文件,从而实现在固定的时间内在磁盘上对数据进行快速存取,这也是一个文件系统应该必备的功能。这种特定的方式其实就是文件系统,而文件系统一般都是在磁盘的分区上实现的。
既然说到了磁盘,那我们就说说磁盘的组成结构。磁盘内部结构是由一个转轴上面固定这个一个或多个盘片,每个盘片都有两个盘面。一般来说在距离每个盘面很近的地方都有一个磁头,用来读写数据的。而每个盘面都可以划分成为很多个同心圆,在硬盘出厂的时候,厂家都会的每块硬盘做低级格式化,从而把磁盘上的不同的同心圆为不同的磁道(track),磁道是由许许多多在同一磁道的扇区(sector)组成的,每一个扇区大小为512个字节(byte)。在不同盘面上的同一磁道我们称之为一个柱面(cylinder)。在对磁盘分区时,我们都是对磁盘的柱面进行分区。同一柱面只能属于同一个分区。
目前的大多数硬盘都是以MBR的方式分的区。MBR的大小为512byte,位于以此种方式分区的磁盘的第零磁道的0byte到512byte。其中前446个字节用于存储此硬盘上的操作系统的bootloader。446字节后面的64个字节用于存储分区表,其中每16个字节可以存储一个主分区,所以MBR格式的硬盘分主分区和扩展分区,这两种分区加起来不能超过4个。最后面的两个字节用于标记此MBR是否有效。
由于文件系统用扇区对磁盘管理不方便,于是就把多个扇区组织在一起划分为磁盘块(block),磁盘块的大小一般为1k、2k、4k,每个磁盘块在文件系统中都是有编号的。
接下来我们说说ext系列文件系统的基本结构:
ext系列的文件系统是由众多的块组组成的,块组之间都是相互独立的、大小都是相同的。每个块组都有自己的元数据区和数据区,第0个块组的第一个磁盘块是这个文件系统超级块,这个系统的超级快在众多的快组中都有备份。在文件的超级块中包含了每个快组从哪个块开始,从哪个块结束,此文件系统给管理员预留的磁盘块个数是多少,还有块大小等众多的信息。块组中元数据就相当于图书馆书架和信息牌,在数据查找的过程中起到了路径映射的作用,数据就相当于图书馆的书。
元数据区里面又包含以下内容:
inode:索引节点,相当于图书馆一层大厅的信息牌,索引节点又包含以下信息:
inode号:inode节点编号
文件的权限:文件的属主、属组、其他人,这三类用户的权限
文件的属主:文件的属主
文件的属组:文件的属组
文件的时间戳:访问时间(access)、修改时间(modify)、改变时间(change)
文件所在的每个磁盘块的编号:
inode位图:元数据区中的每个inode用inode位图的其中的一位来标识此inode是否为空闲inode。
block位图:数据区中的每个block用inode位图的其中的一位来标识此block是否为空闲block。
数据区包含的内容:
文件block:存储整个或部分文件数据。
目录block:存储目录中的文件名和对应的inode号
在ext系列的文件系统中的所有文件或目录在元数据区都有与其对应的inode节点和相关属性,单文件名或目录名是存储数据区的磁盘块中,而非元数据区的磁盘块中。
linux系统的文件查找方式:在linux文件系统上,查找所有的文件都需要从根(/)目录开始,根目录也称作rootfs,那我根文件系统在哪个分区的哪个磁盘块上呢?其实根文件系统是自引用的,只要操作系统一启动,内核就会自动去找根文件系统,并记录下来。
例如,我们查找/etc/httpd/conf/httpd.conf这个文件。
第一步、首先内核要在根目录所在的磁盘块,中找到etc目录名和与之对应的inode号;
第二步、内核根据在根文件系统中找到的etc目录的inode号,在文件系统的元数据区中找到与之对应的磁盘编号,从而就知道了etc目录所在的磁盘块;
第三步、内核在etc目录对应的磁盘块中找到httpd目录名和与之对应的inode号;
第四步、内核根据httpd目录的inode号,在文件系统的元数据区中找到与之对应的磁盘编号,从而就知道了httpd目录所在的磁盘块;
第五步、内核在httpd目录对应的磁盘块中找到conf目录名和与之对应的inode号;
第六步、内核根据conf目录的inode号,在文件系统的元数据区中找到与之对应的磁盘编号,从而就知道了conf目录所在的磁盘块;
第七步、内核在conf目录对应的磁盘块中找到与httpd.conf文件名和与之对应的inode号;
第八步、内核根据httpd.conf文件的inode号找到httpd.conf文件所在的磁盘块。然后我们要查找的httpd.conf文件就被找到了。
我们可以从上面查找/etc/httpd/conf/httpd.conf文件的例子可以看出,在linux内核在查找ext系列文件系统上的文件的时候,过程是比较繁琐的,很多过程都是相似的。因此当内核找到程序所需要的文件之后,都会把该文件的路径缓存下来,供以后使用。从而加快查找相同文件所需要的时间。
最后我们来说说和文件系统相关的常用命令及其选项:
mkfs:创建文件系统
用法: mkfs [option]... device
-t fstype: 指定创建文件系统的类型
-c: 在创建文件系统之前,检查分区中有没有坏的磁盘块
-v: 显示详细信息
mke2fs
-b: 指定创建的文件系统的块大小
-i bytes-per-inode: 指定多少个字节创建一个inode
-j: 创建日志文件系统
-L new-volume-label : 指定文件系统的卷标名称
-m reserved-blocks-percentage: 指定为系统管理员预留的磁盘块百分比,数字后面不用加%符号。
-U UUID: 给创建的文件系统指定一个特定的UUID
blkid device: 查看块设备的属性信息
tune2fs: 调整或查看指定ext文件系统的可调整的属性
用法:tune2fs [option]... device
-j: 给文件系统加上日志区域,此选项通常针对ext2文件系统使用
-l: 查看指定文件系统的超级块信息
-l volume-label: 更改指定文件系统的卷标名称
-m reserved-blocks-percentage: 指定为系统管理员预留的磁盘块百分比,数字后面不用加%符号。
-o [^]mount-option[,...]: 为指定的文件系统指定或修改挂载选项
dumpe2fs: 查看ext系列文件系统的详细信息
用法:dumpe2fs [option]... device
-h: 查看给定文件系统的超级块中的信息
e2label: 改变指定的ext系列文件系统的卷标名称
用法: e2label device [ new-label ]
fsck: 检查并修复文件系统
用法: fsck [option] device
-t fstype: 指定要修复的文件系统的类型
-a: 自动修复指定文件系统上的错误
-r: 交互式修复指定文件系统上的错误
e2fsck: 检查并修复ext系列文件系统
用法: e2fsck [option] device
-f: 强制检查指定的文件系统,即使指定的文件系统上没有错误
-y: 对查找到的错误的磁盘块修复问题自动回答为yes