磁盘的组成

磁盘由磁盘盘,机械手臂,磁盘读取头、主轴马达组成
磁盘盘有两种单位,1.扇区,2.磁道
扇区的物理量设计有两种大小,1. 512bytes,2.4Kbytes

盘片 片面 和 磁头

参考地 址https://www.cnblogs.com/jswang/p/9071847.html

硬盘中一般会有多个盘片组成,每个盘片包含两个面,每个盘面都对应地有一个读/写磁头。
受到硬盘整体体积和生产成本的限制,盘片数量都受到限制,一般都在5片以内。
盘片的编号自下向上从0开始,如最下边的盘片有0面和1面,再上一个盘片就编号为2面和3面。
如下图:

clipboard.png

图1

扇区 和 磁道

下图显示的是一个盘面,盘面中一圈圈灰色同心圆为一条条磁道,
从圆心向外画直线,可以将磁道划分为若干个弧段,每个磁道上一个弧段被称之为一个扇区(图践绿色部分)。
扇区是磁盘的最小组成单元,通常是512字节。(由于不断提高磁盘的大小,部分厂商设定每个扇区的大小是4096字节)

clipboard.png

图2

磁头 和 柱面

硬盘通常由重叠的一组盘片构成,每个盘面都被划分为数目相等的磁道,并从外缘的“0”开始编号,具有相同编号的磁道形成一个圆柱,称之为磁盘的柱面。
磁盘的柱面数与一个盘面上的磁道数是相等的。由于每个盘面都有自己的磁头,因此,盘面数等于总的磁头数。 如下图

clipboard.png

图3

磁盘分区

为什么需要磁盘分区

把不同文件放于不同分区
ex:1.系统文件在一分区,2.数据文件在二分区,3.日志文件在三分区
1.易于管理和使用
2.有利于数据安全;
3.节约寻找文件的时间

磁盘分区方式-MSDOS(MBR)|GPT

一圈一圈的磁柱与分区有什么关系呢?爱的魔力转圈圈

从外圈0开始形成一个一个的磁柱,磁柱是分区槽的最小单位,意味着比如A分区最少为1磁柱,这个是MBR分区方式
但是GPT,由于GPT的分区表有更大的空间支持,所以分区的最小单位为1扇区

MBR简介

MSDOS 全称Microsoft Disk Operating system 微软磁盘操作系统
MBR 全称 Master Boot record-主要开机记录取
由于linux早期为了兼容Windows磁盘,因此使用的是Windows的MBR的方式来处理开机管理程序与分区表

MBR

MBR一般存在磁盘的第一个扇区
磁盘的第一个扇区
1.由主要启动记录器MBR:可以安装开机管理程序的地方,446bytes
2.分区表:记录整颗磁盘的分区状态,64bytes;
由于分区表只有64bytes,所以只能记录4组记录,意味着只能有4个分区

分区类型

分区类型有两种1.主分区primary partion和2.Extended partion 扩展分区
主分区最多有4个,扩展分区最多有一个
因为扩展分区Extened还可以拆分成多个逻辑分区Logical partion
同时由于分区的最小单位为连续的磁道组成的磁柱,因此把扩展分区Extended partion放在最后一个分区
同时Extended 也方便扩容
推荐的分区方式 P P P E(L,L,L...)

MBR的限制

1.操作系统无法抓取到2.2T以上的磁盘容量,因此要把磁盘一个一个拆出来 拆成逻辑分区
2.同时MBR只存在于一个扇区,如果损坏,将无法使用
3.MBR的开机管理程序区块只有446bytes,无法容纳更多的代码

所以出现了GPT分区,GPT分区解决了上述问题

GPT

GPT扇区大小 512bytes----4KBytes
早期的扇区大小为:512bytes
GPT为了兼容所有磁盘,因此在扇区的定义上,大多使用逻辑区块地址(Logical Address,LBA)512bytes
GPT使用了34个LBA区块记录分区信息,整个磁盘的最后33个LBA也拿来做备份
这样GPT就解决了
1.操作系统无法抓取2.2T以上的磁盘容量
2.如果GPT的扇区损坏,可以用备份扇区
LBA0,存储了第一个阶段的开机管理程序
LBA1,GPT表头,记录了分区表的位置和大小和备份的分区表位置
LBA2-LBA33,实际记录分区信息

lsblk(list block devices)

[root@VM_158_86_centos ~]# lsblk
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  50G  0 disk  #硬盘
└─vda1 253:1    0  50G  0 part / #分区

查看分区类型 parted

[root@VM_158_86_centos ~]# parted /dev/vda1 print
Model: Virtio Block Device (virtblk)
Disk /dev/vda1: 53.7GB
Sector size (logical/physical): 512B/512B
Partition Table: loop #这里显示为loop其实是为MBR,如果为GPT会显示gpt
                            
Disk Flags: 

Number  Start  End     Size    File system  标志
 1      0.00B  53.7GB  53.7GB  ext3

文件系统

文件系统简诉

磁盘分区完毕后需要格式化,之后操作系统才能使用这个文件系统,为什么需要格式化呢?
因为每种操作系统设定的文件属性/权限并不相同

文件系统格式
windows98:FAT16
windows2000...:NTFS
Linux:Ext2

传统的磁盘与文件系统应用中,
一个分区槽只能被格式化成为一个文件系统,也就是一个partion对应一个文件系统

新的磁盘与文件系统应用中,
LVM:Logical Volume Manager,可以把一个partion格式化为多个文件系统
RAID:Redundant Arrays of Independent Drives,将多个分区槽合成一个文件系统
因此,目前我们在格式化时已经不再说针对partition来格式化了,一个可被挂载的数据为一个文件件系统,而不是一个分区槽

文件系统三元素

superblock:记录此filesystem 的整体资讯,包括inode/block的总量、使用量、剩余量, 以及档案系统的格式与相关资讯等;
inode:记录档案的属性,一个档案占用一个inode,同时记录此档案的资料所在的block 号码;
block:实际记录档案的内容,若档案太大时,会占用多个block 。

索引式文件系统

索引式
EXT2:有inode 记录了该文件所有占用的block号,可以直接通过inode取出所有block
非索引式
FAT:没有inode,不能直接取出全部,只能通过上一个block记录的下一个block取出

文件系统一开始将inode与block规划好了

档案系统一开始就将inode与block规划好了,除非重新格式化(或者利用resize2fs等指令变更档案系统大小),否则inode与block固定后就不再变动

为什么需要 block group

当文件系统高达数百GB时,如果把inode和block放在一起,inode和block就会太过于庞大,为了方便管理 引入 block group 来处理

clipboard.png

ext2文件系统格式化时候基本上是区分多个block group,每个block group都有独立的inode/block/superblock
并且文件系统最前面有一个启动扇区,相当于每个文件系统的挂载点,可以安装不同的开机管理程序

block的特性

原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化);
每个block 内最多只能够放置一个档案的资料;
承上,如果档案大于block 的大小,则一个档案会占用多个block 数量;
承上,若档案小于block ,则该block 的剩余容量就不能够再被使用了(磁碟空间会浪费)。

inode记录的属性

该文件的存取模式(read/write/excute);
该文件的拥有者与群组(owner/group);
该文件的容量;
该文件建立或状态改变的时间(ctime);
最近一次的读取时间(atime);
最近修改的时间(mtime);
定义文件特性的旗标(flag),如SetUID...;
该文件真正内容的指向(pointer);

inode特性

每个inode 大小均固定为128 bytes (新的ext4 与xfs 可设定到256 bytes);
每个文件都仅会占用一个inode 而已;
承上,因此文件系统能够建立文件案数量与inode 的数量有关;
系统读取文件时需要先找到inode,并分析inode 所记录的权限与使用者是否符合,若符合才能够开始实际读取 block 的内容。

block 与inode 的大小

block 为1, 2, 4K,
inode 为128bytes 或256bytes

假设我一个档案有400MB 且每个block 为4K 时, 那么至少也要十万笔block 号码的记录呢!inode 哪有这么多可记录的资讯?

因此Inode记录block号码的区域被系统灵活的设计为
12个直接指向,1个间接指向,1个双间接指向,1个三间接指向,

clipboard.png

**当block大小为1k(1024byte)时,每个block号码占用4byte,也就是1k能记录256个block号码
对应这256个block**

inode以及对应的1k单位block的单一文件大小限制

12个直接指向: 12*1K=12K 
由于是直接指向,所以总共可记录12笔记录,因此总额大小为如上所示;

间接: 256*1K=256K 
每笔block号码的记录会花去4bytes,因此1K的大小能够记录256笔记录,因此一个间接可以记录的档案大小如上; 

双间接: 256*256*1K=256 2 K 
第一层block会指定256个第二层,每个第二层可以指定256个号码,因此总额大小如上;

三间接: 256*256*256*1K=256 3 K 
第一层block会指定256个第二层,每个第二层可以指定256个第三层,每个第三层可以指定256个号码,因此总额大小如上;

总额:将直接、间接、双间接、三间接加总,得到12 + 256 + 256*256 + 256*256*256 (K) = 16GB

当block为2k或4k时,计算结果也会相应的增大,分别为256GB和2TB

但是有些软件或文件系统不支持大于2k的block设计

superblock特性

block 与inode 的总量;
未使用与已使用的inode / block 数量;
block 与inode 的大小(block 为1, 2, 4K,inode 为128bytes 或256bytes);
filesystem 的挂载时间、最近一次写入资料的时间、最近一次检验磁碟(fsck) 的时间等档案系统的相关资讯;
一个valid bit 数值,若此档案系统已被挂载,则valid bit 为0 ,若未被挂载,则valid bit 为1 

为什么一个文件系统只有一个superblock 而不是一个block group一个superblock

每个block group 都可能含有superblock
但是我们也说一个档案系统应该仅有一个superblock 而已,那是怎么回事啊?
事实上除了第一个block group 内会含有superblock 之外,
后续的block group不一定含有superblock , 
而若含有superblock 则该superblock 主要是做为第一个block group 内superblock 的备份,
这样可以进行superblock的救援

EXT家族查询inode block superblock

[root@VM_158_86_centos ~]# blkid
/dev/vda1: UUID="49f819fd-e56d-48a4-86d3-7ebe0a68ec88" TYPE="ext3" 
[root@VM_158_86_centos ~]# dumpe2fs -h /dev/vda1
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   <none>
Last mounted on:          /
Filesystem UUID:          49f819fd-e56d-48a4-86d3-7ebe0a68ec88
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              3276800
Block count:              13106944
Reserved block count:     655341
Free blocks:              10647845
Free inodes:              3163700
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      508
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Thu Apr 21 15:00:29 2016
Last mount time:          Thu May 23 12:02:40 2019
Last write time:          Thu May 23 12:01:29 2019
Mount count:              16
Maximum mount count:      -1
Last checked:             Thu Apr 21 15:00:29 2016
Check interval:           0 (<none>)
Lifetime writes:          736 GB
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
First orphan inode:       139996
Default directory hash:   half_md4
Directory Hash Seed:      e74c0d45-bdb1-4aaa-9864-f29ad06e91c1
Journal backup:           inode blocks
Journal features:         journal_incompat_revoke
日志大小:             128M
Journal length:           32768
Journal sequence:         0x0066dd50
Journal start:            22289


Group 0: (Blocks 0-32767)-   ##这个就是block group 0
  主 superblock at 0, Group descriptors at 1-4
  保留的GDT块位于 5-512
  Block bitmap at 513 (+513), Inode bitmap at 514 (+514)
  Inode表位于 515-1026 (+515)
  26201 free blocks, 8173 free inodes, 2 directories

查询inode号码

[root@VM_158_86_centos ~]# ls -li
总用量 16
131079 -rw-------. 1 root root 2523 4月  21 2016 anaconda-ks.cfg
131086 drwxr-xr-x  2 root root 4096 9月   4 2018 dockerTest
133347 drwxr-xr-x  4 root root 4096 5月  17 16:08 linux_learn
223431 drwxr-xr-x  3 root root 4096 9月  29 2018 project

目录的inode和block

当创建一个目录时,文件系统会分配一个inode以及至少一个block给目录
目录的inode:记录了目录的属性和权限,以及目录对应的block
目录的block:记录了该目录下的文件的inode和文件名

为什么文件系统会分配至少一个block,而不是一个?
一个block号占用4byte,一个文件名(文件名不相同)大概就6byte,
这样假如1个1k的block只能记录100个文件,那当超出的文件就只能有inode的下一个直接指向来处理

目录的block图:

clipboard.png

文件的inode和block

当创建一个文件时,其他都目录类似,只是文件的block存储的是真实的数据
当第一个block容量不够时,会用下一个直接指向,间接指向...

目录树读取

inode本身并不记录文件名,文件名的记录是在目录的block当中。那么因为档名是记录在目录的block当中,因此当我们要读取某个档案时,就务必会经过目录的inode与block ,然后才能够找到那个待读取档案的inode号码,最终才会读到正确的档案的block内的资料。

由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的inode 号码,此时就能够得到根目录的inode 内容,并依据该inode 读取根目录的block 内的档名资料,再一层一层的往下读到正确的档名

如果我想要读取/etc/passwd 这个档案时,系统是如何读取的呢?

[root@VM_158_86_centos sbin]# ll -di / /etc /etc/passwd
     2 dr-xr-xr-x. 21 root root  4096 6月  11 16:48 /
458753 drwxr-xr-x. 89 root root 12288 5月  27 16:49 /etc
459310 -rw-r--r--   1 root root  1833 5月  27 16:49 /etc/passwd
/的inode:
透过挂载点的信息找到inode号码为128的根目录inode,且inode规范的权限让我们可以读取该block的内容(有r与x) ;

/的block:
经过上个步骤取得block的号码,并找到该内容有etc/目录的inode号码(33595521); 

etc/的inode:
读取33595521号inode得知dmtsai具有r与x的权限,因此可以读取etc/的block内容; 

etc/的block:
经过上个步骤取得block号码,并找到该内容有passwd档案的inode号码(36628004); 

passwd的inode:
读取36628004号inode得知dmtsai具有r的权限,因此可以读取passwd的block内容; 

passwd的block:
最后将该block内容的资料读出来。

文件的存取

先确定使用者对于欲新增档案的目录是否具有w 与x 的权限,若有的话才能新增;
根据inode bitmap 找到没有使用的inode 号码,并将新档案的权限/属性写入;
根据block bitmap 找到没有使用中的block 号码,并将实际的资料写入block 中,且更新inode 的block 指向资料;
将刚刚写入的inode 与block 资料同步更新inode bitmap 与block bitmap,并更新superblock 的内容。

inode和block称为数据存放区域

inode bitmap和block bitmap称为中介数据metadata

数据不一致情况

例如你的档案在写入档案系统时,
因为不知名原因导致系统中断(例如突然的停电啊、系统核心发生错误啊~等等的怪事发生时),
所以写入的资料仅有inode table及data block而已,最后一个同步更新中介资料的步骤并没有做完,
此时就会发生metadata的内容与实际资料存放区产生不一致(Inconsistent)的情况了。

既然有不一致当然就得要克服!在早期的Ext2档案系统中,如果发生这个问题,那么系统在重新开机的时候,就会藉由Superblock当中记录的valid bit (是否有挂载)与filesystem state (clean与否)等状态来判断是否强制进行资料一致性的检查!若有需要检查时则以e2fsck这支程式来进行的。

弊端:
不过,这样的检查真的是很费时~因为要针对metadata 区域与实际资料存放区来进行比对, 呵呵~得要搜寻整个filesystem 呢~如果你的档案系统有100GB 以上,而且里面的档案数量又多时, 哇!系统真忙碌~而且在对Internet 提供服务的伺服器主机上面, 这样的检查真的会造成主机复原时间的拉长~真是麻烦~这也就造成后来所谓日志式档案系统的兴起了。

日志文件系统

预备:当系统要写入一个档案时,会先在日志记录区块中纪录某个档案准备要写入的资讯;
实际写入:开始写入档案的权限与资料;开始更新metadata 的资料;
结束:完成资料与metadata 的更新后,在日志记录区块当中完成该档案的纪录。
在这样的程序当中,万一资料的纪录过程当中发生了问题,那么我们的系统只要去检查日志记录区块, 就可以知道哪个档案发生了问题,针对该问题来做一致性的检查即可,而不必针对整块filesystem 去检查, 这样就可以达到快速修复filesystem 的能力了!这就是日志式档案最基础的功能啰~

文件系统运作

系统会将常用的档案资料放置到主记忆体的缓冲区,以加速档案系统的读/写;
承上,因此Linux 的实体记忆体最后都会被用光!这是正常的情况!可加速系统效能;
你可以手动使用sync 来强迫记忆体中设定为Dirty 的档案回写到磁碟中;
若正常关机时,关机指令会主动呼叫sync 来将记忆体的资料回写入磁碟内;
但若不正常关机(如跳电、当机或其他不明原因),由于资料尚未回写到磁碟内, 因此重新开机后可能会花很多时间在进行磁碟检验,甚至可能导致档案系统的损毁(非磁碟损毁)。

挂载点

挂载点一定是目录,该目录为进入该文件系统的入口


[root@study ~]# ls -lid / /boot /home 
128 dr-xr-xr-x. 17 root root 4096 May 4 17:56 /
 128 dr-xr-xr-x. 4 root root 4096 May 4 17 :59 /boot
 128 drwxr-xr-x. 5 root root 41 Jun 17 00:20 /hom

由于XFS filesystem最顶层的目录之inode一般为128号,因此可以发现/, /boot, /home为三个不同的filesystem,因为inode相同(每个filesystem只会有一个唯一的inode),而文件属性不相同,所以不是同一个文件,为不同的三个文件系统

[root@study ~]# ls -ild / /. /..
128 dr-xr-xr-x. 17 root root 4096 May 4 17:56 /
128 dr-xr-xr-x. 17 root root 4096 May 4 17:56 /.
128 dr-xr-xr-x. 17 root root 4096 May 4 17:56 /..

inode相同,文件属性相同,所以为同一文件

Linux VFS (Virtual Filesystem Switch)管理文件系统 filesystem

假设你的 / 使用的是 /dev/hda1 ,用 ext3 ,而 /home 使用 /dev/hda2 ,用 reiserfs , 那么你取用 /home/dmtsai/.bashrc 时,有特别指定要用的什么文件系统的模块来读取吗?
这个就是 VFS 的功能啦!透过这个 VFS 的功能来管理所有的 filesystem, 省去我们需要自行配置读取文件系统的定义啊~方便很多!整个 VFS 可以约略用下图来说明:

clipboard.png

df:列出档案系统的整体磁盘使用量;

[root@VM_158_86_centos sbin]# df
文件系统          1K-块    已用     可用 已用% 挂载点
/dev/vda1      51474044 8896976 39955704   19% /
devtmpfs         930500       0   930500    0% /dev
tmpfs            941176      24   941152    1% /dev/shm
tmpfs            941176     440   940736    1% /run
tmpfs            941176       0   941176    0% /sys/fs/cgroup
tmpfs            188236       0   188236    0% /run/user/0

du:评估文件系统的磁盘使用量(常用在推估目录所占容量)

-s :列出总量而已,而不列出每个各别的目录占用容量
[root@VM_158_86_centos sbin]# du -s /*
4    /a.txt
0    /bin
173504    /boot
0    /b.txt
4    /data
0    /dev
39516    /etc
176    /home
0    /lib
0    /lib64
16    /lost+found
4    /media
4    /mnt
8    /opt
0    /proc

硬链接与软连接

硬链接:

clipboard.png

两个链接文件的inode都指向real-inode,删除其中一个对另一个没有影响,修改其中一个的内容,另一个的内容都相应被更改
局限:

不能跨 Filesystem;
不能 link 目录。
不能跨 Filesystem 还好理解,那不能 hard link 到目录又是怎么回事呢?
这是因为如果使用 hard link 链接到目录时, 链接的数据需要连同被链接目录底下的所有数据都创建链接

创建硬链接

[root@VM_158_86_centos ~]# ln linux_learn/learn_01.sh 
[root@VM_158_86_centos ~]# ll -i /root/learn_01.sh linux_learn/learn_01.sh 
133351 -rwxr-xr-x 2 root root 99 3月   1 17:38 linux_learn/learn_01.sh
133351 -rwxr-xr-x 2 root root 99 3月   1 17:38 /root/learn_01.sh

其中的2表示连结数量

符号链接(快捷方式):

[root@www ~]# ln -s /etc/crontab crontab2
[root@www ~]# ll -i /etc/crontab /root/crontab2
1912701 -rw-r--r-- 2 root root 255 Jan  6  2007 /etc/crontab
 654687 lrwxrwxrwx 1 root root  12 Oct 22 13:58 /root/crontab2 -> /etc/crontab

由上表的结果我们可以知道两个文件指向不同的 inode 号码,当然就是两个独立的文件存在! 而且连结档的重要内容就是他会写上目标文件的『文件名』, 你可以发现为什么上表中连结档的大小为 12 bytes 呢? 因为箭头(-->)右边的档名『/etc/crontab』总共有 12 个英文,每个英文占用 1 个 byes ,所以文件大小就是 12bytes了

clipboard.png

[root@www ~]# ln [-sf] 来源文件 目标文件
选项与参数:
-s  :如果不加任何参数就进行连结,那就是hard link,至于 -s 就是symbolic link
-f  :如果 目标文件 存在时,就主动的将目标文件直接移除后再创建!

Symbolic Link 与 Windows 的快捷方式可以给他划上等号,由 Symbolic link 所创建的文件为一个独立的新的文件,所以会占用掉 inode 与 block

符号链接文件的block记录指向目标源文件的inode,当源文件被删除,通过符号链接将无法访问源文件。


吴玉宏
16 声望1 粉丝

萌新