磁盘盘上的物理组成则为:
扇区(Sector)为最小的物理储存单位,且依据磁盘设计的不同,目前主要有512bytes与4K两种格式;
将扇区组成一个圆,那就是磁柱(Cylinder);
早期的分割主要以磁柱为最小分割单位,现在的分割通常使用扇区为最小分割单位(每个扇区都有其号码喔,就好像座位一样);
磁盘分割表主要有两种格式,一种是限制较多的MBR分割表,一种是较新且限制较少的GPT分割表。
MBR分割表中,第一个扇区最重要,里面有:(1)主要开机区(Master boot record,MBR)及分割表(partition table),其中MBR占有446 bytes,而partition table则占有64 bytes。
GPT分割表除了分割数量扩充较多之外,支持的磁盘容量也可以超过2TB。
至于磁盘的文件名部份,基本上,所有实体磁盘的文件名都已经被模拟成/dev/sd[a-p]的格式,第一颗磁盘文件名为/dev/sda。而分割槽的文件名若以第一颗磁盘为例,则为/dev/sda[1-128]。除了实体磁盘之外,虚拟机的磁盘通常为/dev/vd[a-p]的格式。若有使用到软件磁盘阵列的话,那还有/dev/md[0-128]的磁盘文件名。使用的是LVM时,文件名则为/dev/VGNAME/LVNAME等格式。
我们都知道磁盘分割完毕后还需要进行格式化(format),之后操作系统才能够使用这个档案系统。为什么需要进行『格式化』呢?这是因为每种操作系统所设定的档案属性/权限并不相同,为了存放这些档案所需的数据,因此就需要将分割槽进行格式化,以成为操作系统能够利用的『档案系统格式(filesystem)』。
由此我们也能够知道,每种操作系统能够使用的档案系统并不相同。举例来说,windows 98以前的微软操作系统主要利用的档案系统是FAT(或FAT16),windows 2000以后的版本有所谓的NTFS档案系统,至于Linux的正统档案系统则为Ext2(Linux second extended file system,ext2fs)这一个。此外,在预设的情况下,windows操作系统是不会认识Linux的Ext2的。
传统的磁盘与档案系统之应用中,一个分割槽就是只能够被格式化成为一个档案系统,所以我们可以说一个filesystem就是一个partition。但是由于新技术的利用,例如我们常听到的LVM与软件磁盘数组(software raid),这些技术可以将一个分割槽格式化为多个档案系统(例如LVM),也能够将多个分割槽合成一个档案系统(LVM,RAID)!所以说,目前我们在格式化时已经不再说成针对partition来格式化了,通常我们可以称呼一个可被挂载的数据为一个档案系统而不是一个分割槽喔!
那么档案系统是如何运作的呢?这与操作系统的档案数据有关。较新的操作系统的档案数据除了档案实际内容外,通常含有非常多的属性,例如Linux操作系统的档案权限(rwx)与档案属性(拥有者、群组、时间参数等)。档案系统通常会将这两部份的数据分别存放在不同的内存块,权限与属性放置到inode中,至于实际数据则放置到data block内存块中。另外,还有一个超级内存块(superblock)会记录整个档案系统的整体信息,包括inode与block的总量、使用量、剩馀量等。
每个inode与block都有编号,至于这三个数据的意义可以简略说明如下:
superblock:记录此filesystem的整体信息,包括inode/block的总量、使用量、剩馀量,以及档案系统的格式与相关资讯等;
inode:记录档案的属性,一个档案占用一个inode,同时记录此档案的数据所在的block号码;
block:实际记录档案的内容,若档案太大时,会占用多个block。
由于每个inode与block都有编号,而每个档案都会占用一个inode,inode内则有档案数据放置的block号码。因此,我们可以知道的是,如果能够找到档案的inode的话,那么自然就会知道这个档案所放置数据的block号码,当然也就能够读出该档案的实际数据了。这是个比较有效率的作法,因为如此一来我们的磁盘就能够在短时间内读取出全部的数据,读写的性能比较好。
Linux的档案除了原有的数据内容外,还含有非常多的权限与属性,这些权限与属性是为了保护每个使用者所拥有数据的隐密性。而前一小节我们知道filesystem里面可能含有的inode/block/superblock等。为什么要谈这个呢?因为标准的Linux档案系统Ext2就是使用这种inode为基础的档案系统啦!
而如同前一小节所说的,inode的内容在记录档案的权限与相关属性,至于block内存块则是在记录档案的实际内容。而且档案系统一开始就将inode与block规划好了,除非重新格式化(或者利用resize2fs等指令变更档案系统大小),否则inode与block固定后就不再变动。但是如果仔细考虑一下,如果我的档案系统高达数百GB时,那么将所有的inode与block通通放置在一起将是很不智的决定,因为inode与block的数量太庞大,不容易管理。
为此之故,因此Ext2档案系统在格式化的时候基本上是区分为多个内存块群组(block group)的,每个内存块群组都有独立的inode/block/superblock系统。
data block(数据内存块)
data block是用来放置档案内容数据地方,在Ext2档案系统中所支持的block大小有1K,2K及4K三种而已。在格式化时block的大小就固定了,且每个block都有编号,以方便inode的记录啦。不过要注意的是,由于block大小的差异,会导致该档案系统能够支持的最大磁盘容量与最大单一档案容量并不相同。因为block大小而产生的Ext2档案系统限制如下:
Block 大小 | 1KB | 2KB | 4KB |
最大單一檔案限制 | 16GB | 256GB | 2TB |
最大檔案系統總容量 | 2TB | 8TB | 16TB |
除此之外Ext2档案系统的block还有什么限制呢?有的!基本限制如下:
原则上,block的大小与数量在格式化完就不能够再改变了(除非重新格式化);
每个block内最多只能够放置一个档案的数据;
承上,如果档案大于block的大小,则一个档案会占用多个block数量;
承上,若档案小于block,则该block的剩馀容量就不能够再被使用了(磁盘空间会浪费)。
如上第四点所说,由于每个block仅能容纳一个档案的数据而已,因此如果你的档案都非常小,但是你的block在格式化时却选用最大的4K时,可能会产生一些容量的浪费!
2. inode table(inode表格)
基本上,inode记录的档案数据至少有底下这些:
该档案的存取模式(read/write/excute);
该档案的拥有者与群组(owner/group);
该档案的容量;
该档案建立或状态改变的时间(ctime);
最近一次的读取时间(atime);
最近修改的时间(mtime);
定义档案特性的旗标(flag),如SetUID…;
该档案真正内容的指向(pointer);
inode的数量与大小也是在格式化时就已经固定了,除此之外inode还有些什么特色呢?
每个inode大小均固定为128 bytes(新的ext4与xfs可设定到256 bytes);
每个档案都仅会占用一个inode而已;
承上,因此档案系统能够建立的档案数量与inode的数量有关;
系统读取档案时需要先找到inode,并分析inode所记录的权限与使用者是否符合,若符合才能够开始实际读取block的内容。
3.Superblock(超级内存块)
Superblock是记录整个filesystem相关资讯的地方,没有Superblock,就没有这个filesystem了。他记录的信息主要有:
block与inode的总量;
未使用与已使用的inode / block数量;
block与inode的大小(block为1,2,4K,inode为128bytes或256bytes);
filesystem的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck)的时间等档案系统的相关资讯;
一个valid bit数值,若此档案系统已被挂载,则valid bit为0,若未被挂载,则valid bit为1。
Superblock是非常重要的,因为我们这个档案系统的基本信息都写在这里,因此,如果superblock死掉了,你的档案系统可能就需要花费很多时间去挽救啦!一般来说,superblock的大小为1024bytes。相关的superblock信息我们等一下会以dumpe2fs指令来呼叫出来观察!
此外,每个block group都可能含有superblock!但是我们也说一个档案系统应该仅有一个superblock而已,那是怎么回事啊?事实上除了第一个block group内会含有superblock之外,后续的block group不一定含有superblock,而若含有superblock则该superblock主要是做为第一个block group内superblock的备份,这样可以进行superblock的救援呢!
4. Filesystem Description(档案系统描述说明)
这个区段可以描述每个block group的开始与结束的block号码,以及说明每个区段(superblock,bitmap,inodemap,data block)分别介于哪一个block号码之间。这部份也能够用dumpe2fs来观察的。
5. block bitmap(内存块对照表)
如果你想要新增档案时总会用到block吧!那你要使用哪个block来记录呢?当然是选择『空的block』来记录新档案的数据啰。那你怎么知道哪个block是空的?这就得要透过block bitmap的辅助了。从block bitmap当中可以知道哪些block是空的,因此我们的系统就能够很快速的找到可使用的空间来处置档案啰。
同样的,如果你删除某些档案时,那么那些档案原本占用的block号码就得要释放出来,此时在block bitmap当中相对应到该block号码的标志就得要修改成为『未使用中』啰!这就是bitmap的功能。
6. inode bitmap(inode对照表)
这个其实与block bitmap是类似的功能,只是block bitmap记录的是使用与未使用的block号码,至于inode bitmap则是记录使用与未使用的inode号码啰!
dumpe2fs:查询Ext家族superblock信息的指令
现在我们知道磁盘的整体数据是在superblock内存块中,但是每个各别档案的容量则在inode当中记载的。那在文字界面底下该如何叫出这几个数据呢?底下就让我们来谈一谈这两个指令:
df:列出档案系统的整体磁盘使用量;
du:评价档案系统的磁盘使用量(常用在推估目录所占容量)
由于df主要读取的数据几乎都是针对一整个档案系统,因此读取的范围主要是在Superblock内的信息,所以这个指令显示结果的速度非常的快速!在显示的结果中你需要特别留意的是那个根目录的剩馀容量!因为我们所有的数据都是由根目录衍生出来的,因此当根目录的剩馀容量剩下0时,那你的Linux可能就问题很大了。
另外需要注意的是,如果使用-a这个参数时,系统会出现/proc这个挂载点,但是里面的东西都是0,不要紧张!/proc的东西都是Linux系统所需要加载的系统数据,而且是挂载在『內存当中』的,所以当然没有占任何的磁盘空间啰!
至于那个/dev/shm/目录,其实是利用內存虚拟出来的磁盘空间,通常是总实体內存的一半!由于是透过內存模拟出来的磁盘,因此你在这个目录底下建立任何数据档案时,存取速度是非常快速的!(在记忆体内工作)不过,也由于他是內存模拟出来的,因此这个档案系统的大小在每部主机上都不一样,而且建立的东西在下次开机时就消失了!因为是在內存中嘛!
与df不一样的是,du这个指令其实会直接到档案系统内去搜寻所有的档案数据,所以上述第三个示例指令的运作会执行一小段时间!此外,在预设的情况下,容量的输出是以KB来设计的,如果你想要知道目录占了多少MB,那么就使用-m这个参数即可啰!而,如果你只想要知道该目录占了多少容量的话,使用-s就可以啦!
至于-S这个选项部分,由于du预设会将所有档案的大小均列出,因此假设你在/etc底下使用du时,所有的档案大小,包括/etc底下的次目录容量也会被计算一次。然后最终的容量(/etc)也会加总一次,因此很多朋友都会误会du分析的结果不太对劲。所以啰,如果想要列出某目录下的全部数据,或许也可以加上-S的选项,减少次目录的加总喔!