三分薄地,认真耕耘

导航

 

本文用于记录学习体会、心得,兼做笔记使用,方便以后复习总结。内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK老师和学神教育的优质教学。希望各位因学习需求而要进行转载时,能申明出处为学神教育,谢谢各位!



1、 机械硬盘结构


1.1 机械硬盘结构

机械硬盘截图如下图所示:

硬盘结构

  • 空气过滤片
  • 主轴(马达电机与轴承在其下方)
  • 音圈马达
  • 永磁铁
  • 磁盘:Magnetic arm
  • 磁头:Magnetic head
  • 磁头臂

磁盘内部不是真空,只不过里面的空气很干净。如果是真空,还不利于散热。

硬盘的内部是金属盘片,将圆形的盘片划分成若干个扇形区域,这就是扇区sector。若干个扇区就组成整个盘片。为什么要分扇区?是逻辑化数据的需要,能更好的管理硬盘空间。 以盘片中心为圆心,把盘片分成若干个同心圆,那每一个划分圆的“线条”,就称为磁道track。

硬盘内的盘片有两个面,都可以储存数据,而硬盘内的盘片往往不止一张,常见的有两张,那么,两张盘片中相同位置的磁道,就组成一个“柱面”,盘片中有多少个磁道,就有多少个柱面。盘片两面都能存数据,要读取它,必须有磁头,所以,每一个面,都有一个磁头,一张盘片就有两个磁头。

硬盘的存储容量=磁头数×磁道(柱面)数×每道扇区数×每道扇区字节数。

磁道从外向内自0开始顺序进行编号,各个磁道上的扇区数是在硬盘格式化时确定的。

文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。

比较古老的CHS (Cylinder/Head/Sector :磁头(Heads)、柱面(Cylinder)、扇区(Sector))结构体系. 因为很久以前,在硬盘的容量还非常小的时候,人们采用与软盘类似的结构生产硬盘。也就是硬盘盘片的每一条磁道都具有相同的扇区数,由此产生了所谓的3D参数,即是磁头数(Heads)、柱面数(Cylinders)、扇区数(Sectors)以及相应的3D寻址方式。

CHS结构体系

如上图所示的磁盘,每个磁道的扇区都一样,这样外磁道整个弧长要大于内部的扇区弧长,因而其磁记录密度就要比内部磁道的密度要小。最终,导致了外部磁道的空间浪费。

Zoned-bit recording(ZBR 区位记录)是一种物理优化硬盘存储空间的方法,此方法通过将更多的扇区放到磁盘的外部磁道而获取更多存储空间。即磁盘内部磁道的扇区少,外部刺刀的扇区多,充分利用的磁道空间。

ZBR磁盘扇区结构示意图

ZBR磁盘扇区结构示意图

由于单位时间内,光盘内圈和外圈旋转的角度一样,所以外圈旋转的磁道更长,访问的扇区更多,因此数据存放的位置越靠外面,访问速度越快。一般机械磁盘的0扇区都是从最外面开始,越往磁盘内部扇区号越大,访问速度越慢。

使用ZBR 区位记录法做的磁盘有以下特点:读外圈的数据快,读内圈的数据慢,所以测试硬盘经常看到读取速度越来越慢的曲线图就很正常了。

ZBR磁盘外圈磁道和内圈磁道扇区比较

ZBR磁盘内外磁道速度比较

磁盘写数据时,先从外面往里。所以windows系统盘和linux系统分区boot的都是在最外面的磁道

windows : C盘安装最外,速度也是最快

Linux : boot分区和 swap分区,装最外面

1.2 簇和block

windows中的簇类似于Linux系统中的block

磁盘上的磁道、扇区、簇

例:在win10系统,新一个文本文件“新建文本文档.txt”,只输入aa两个字符。

右击属性查看大小: 说明我的NTFS文件系统中默认的簇大小为4KB

[root@linuxprobe ~]# stat /etc/passwd ##查看linux中block的大小
文件:"/etc/passwd"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:37107837硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:system_u:object_r:passwd_file_t:s0
最近访问:2019-05-09 22:37:00.968000146 +0800
最近更改:2019-04-30 10:58:57.840068859 +0800
最近改动:2019-04-30 10:58:57.842068859 +0800
创建时间:-

IO 块:4096 说明系统的block是4096大小。


2、文件系统结构


linux文件系统由三部分组成:文件名、inode,block

linux文件系统格式: ext3、ext4、xfs

windows文件系统格式: FAT32、NTFS

2.1 文件名

[root@linuxprobe ~]# cp /etc/passwd ./a.txt
[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 1 root root 3379 5月 9 23:46 a.txt

此处的a.txt即为文件名

2.2 inode的内容

inode包含文件的元信息,具体来说有以下内容:

  • 文件的字节数
  • 文件拥有者的User ID
  • 文件的Group ID
  • 文件的读、写、执行权限
  • 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  • 链接数,即有多少文件名指向这个inode
  • 文件数据block的位置

可以用stat命令,查看某个文件的inode信息:

[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146853硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-09 23:46:22.991072117 +0800 ##access time
最近更改:2019-05-09 23:46:22.991072117 +0800 ##modify time
最近改动:2019-05-09 23:46:22.991072117 +0800 ##change time
创建时间:-

atime : access time 访问文件内容的时间。对文件进行一次读操作,它的访问时间就会改变。例如像:cat、more等操作,但是像之前的stat还有ls命令对atime是不会有影响的。比如:cat a.txt
mtime : modify time 修改文件内容的时间。文件的内容被最后一次修改的时间,我们经常用的ls -l命令显示出来的文件时间就是这个时间,当用vim对文件进行编辑之后保存,它的mtime就会相应的改变;比如:如:echo aa >> a.sh 或vim a.txt 修改内容
ctime : change time 指inode上一次文件属性变动的时间。当文件的状态被改变的时候,状态时间就会随之改变,例如当使用chmod、chown等改变文件属性的操作是会改变文件的ctime的。chmod +x a.txt

[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 1 root root 3379 5月 9 23:46 a.txt

举例

1)使用cat命令查看文件后,文件atime变更

[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146853硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-09 23:46:22.991072117 +0800
最近更改:2019-05-09 23:46:22.991072117 +0800
最近改动:2019-05-09 23:46:22.991072117 +0800
创建时间:-

[root@linuxprobe ~]# cat a.txt

[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146853硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-10 00:00:28.391086736 +0800 #使用cat查看文件后指挥变更atime
最近更改:2019-05-09 23:46:22.991072117 +0800
最近改动:2019-05-09 23:46:22.991072117 +0800
创建时间:-

2)使用vim命令写文件w后,文件atime、mtime、ctime都会变更。如果只是查看没有写的话,只会变更atime。

[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146862硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-10 00:03:57.313090348 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改动:2019-05-10 00:03:57.349090349 +0800
创建时间:-
[root@linuxprobe ~]# vim a.txt
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146862硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-10 00:04:42.803091135 +0800 ##不进行写操作,只会变更atime
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改动:2019-05-10 00:03:57.349090349 +0800
创建时间:-

3)使用chmod命令后,文件ctime会变更

[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146862硬链接:1
权限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-10 00:04:42.803091135 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改动:2019-05-10 00:03:57.349090349 +0800
创建时间:-
[root@linuxprobe ~]# chmod +x a.txt
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:67146862硬链接:1
权限:(0755/-rwxr-xr-x) Uid:(0/root) Gid:(0/root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2019-05-10 00:04:42.803091135 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改动:2019-05-10 00:07:55.227094462 +0800 ##ctime变更
创建时间:-

2.3 inode的大小

inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

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

inode号:每个inode都有一个号码,操作系统用inode号码来识别不同的文件,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

例1: 使用ls -i命令,可以看到文件名对应的inode号码

[root@linuxprobe ~]# ls -i a.txt
67146862 a.txt

例2:查看每个硬盘分区的inode总数和已经使用的数量,可以使用df -i命令。

[root@linuxprobe ~]# df -i
文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点
/dev/mapper/centos-root 31453184 375866 31077318 2% /
devtmpfs 478669 417 478252 1% /dev
tmpfs 482939 1 482938 1% /dev/shm
tmpfs 4829391520 481419 1% /run
tmpfs 482939 16 482923 1% /sys/fs/cgroup
/dev/sda1 524288 378 523910 1% /boot
tmpfs 482939 7 482932 1% /run/user/42
tmpfs 482939 21 482918 1% /run/user/1001
/dev/sr0 0 00- /run/media/oracle/CentOS 7 x86_64

注:由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件

2.4 目录文件

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。
目录文件的结构非常简单,就是一系列目录项的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

[root@linuxprobe ~]# ls -id /etc
33554497 /etc

2.5 block块大小

block 是真正存储数据的地方。

block是 文件系统 中最小的存储单位

扇区 是 磁盘 中最小的存储单位

磁盘的扇区和簇

在linux下中叫:block,在windows中叫:簇

操作系统读取硬盘的时候,不会一个个扇区(512字节)地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是1KB,即连2个 sector扇区组成一个 block。或4K即8个扇区组成一个“块”。

例1:格式化修改磁盘,修改簇大小

格式化磁盘

修改簇的大小

簇和block调大:

优点: 速度快,节约寻址时间。

缺点:空间浪费


3 文件的硬链接和软链接


3.1 linux链接概念

Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为软链接,即符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。

【硬连接】:硬连接指通过索引节点号来进行连接。inode是可以对应多个文件名的

在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。

在Linux中,多个文件名可以指向同一索引节点。一般这种连接就是硬连接。

硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。

只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

【软连接】:另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

3.2 实战-1:ln命令创建硬链接

语法格式:ln 源文件 目标文件

[root@linuxprobe ~]# touch a.txt
[root@linuxprobe ~]# ln a.txt b.txt ##创建b.txt作为a.txt的硬链接
[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 2 root root 0 5月 10 00:41 a.txt
[root@linuxprobe ~]# ll b.txt
-rw-r--r--. 2 root root 0 5月 10 00:41 b.txt ##查看发现a.txt和b.txt文件属性相同,mtime都一致
[root@linuxprobe ~]# echo 222>>a.txt
[root@linuxprobe ~]# echo 222 > a.txt
[root@linuxprobe ~]# cat a.txt
222
[root@linuxprobe ~]# cat b.txt
222 ##修改a.txt文件后,b.txt文件也同样被修改
[root@linuxprobe ~]# ls -i a.txt
67146853 a.txt
[root@linuxprobe ~]# ls -i b.txt ##两个文件的inode一致
67146853 b.txt
[root@linuxprobe ~]# chmod 777 a.txt
[root@linuxprobe ~]# ll a.txt
-rwxrwxrwx. 2 root root 4 5月 10 00:42 a.txt
[root@linuxprobe ~]# ll b.txt
-rwxrwxrwx. 2 root root 4 5月 10 00:42 b.txt ##修改一个文件的权限后,另外一个文件的权限也会修改

硬链接的原理就是多个文件名指向同一个inode,因此多个文件名共用一个inode号,达到共享与备份的目的

注意:源文件被删除,不影响链接文件的正常使用

[root@linuxprobe ~]# rm -rf a.txt
[root@linuxprobe ~]# cat b.txt
222
[root@linuxprobe ~]# echo 0000 >> b.txt
[root@linuxprobe ~]# cat b.txt
222
0000

硬链接不能针对目录创建

[root@linuxprobe ~]# ln /etc/ test
ln: "/etc/": 不允许将硬链接指向目录

硬链接不能跨分区进行创建

[root@linuxprobe ~]# ln b.txt /boot/bb.txt
ln: 无法创建硬链接"/boot/bb.txt" => "b.txt": 无效的跨设备连接

因为每个分区的inode号是独立的,跨分区的硬链接有可能会导致inode冲突,所以不容许跨分区的硬链接。

3.3 ln -s 创建软连接

软链接:相当于windows中的快捷方式

语法:ln -s 源文件 软链接的名字

例1:创建软连接,然后删除源文件,链接文件能否正常使用。

软连接删除源文件

注:源文件被删除,链接文件失效

例2:能针对目录和跨分区创建软链接

创建目录的软连接

[root@linuxprobe ~]# ll test
总用量 0
lrwxrwxrwx. 1 root root 5 5月 10 01:01 etc -> /etc/ ##创建/etc的软连接

创建跨分区的软连接,源文件必须写绝对路径

[root@linuxprobe ~]# ln -s /boot/grub/splash.xpm.gz c.txt
[root@linuxprobe ~]# ll c.txt
lrwxrwxrwx. 1 root root 24 5月 10 01:03 c.txt -> /boot/grub/splash.xpm.gz

3.4 inode的特殊作用

由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。

  1. 有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。

  2. 移动文件或重命名文件,只是改变文件名,不影响inode号码。

  3. 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。
    互动:为什么每次修改完服务器配置文件后,都需要重新加载一下配置文件?

    [root@linuxprobe ~]# ls -i a.txt
    67146858 a.txt
    [root@linuxprobe ~]# vim a.txt
    [root@linuxprobe ~]# ls -i a.txt
    67146871 a.txt

因为vim每次修改完后,Inode号都会变,系统还是读取的原来inode号的配置文件,每次修改完服务器的配置文件,都要重启服务,重新读一下配置文件。


4、实战:解决磁盘有空间但创建不了文件-修复服务器文件系统


4.1 解决磁盘有空间但创建不了文件

实战场景:在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情况,发现/data分区只使用了80%,还有1.9G的剩余空间,但是无法创建新的文件。当时使用的是root用户。服务器没有被黑。

[root@xuegod63 ~]# df -h
文件系统 容量已用 可用 已用% 挂载点
/dev/sda310G 8.0G 1.9G 80%/

常识: 只要权限够,磁盘上有空间一定可以创建文件。 这个是错的。

排查:

[root@xuegod63 ~]# df -i
文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点
/dev/sda3 5242880 52428800 100%/

后来用df -i查看了一下/data所在的分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录和文件。

查找原因:
  /data/cache目录中存在数量非常多的小字节缓存文件,占用的Block不多,但是占用了大量的inode。

解决方案1:删除/data/cache目录中的部分文件,释放出/data分区的一部分inode。

解决方案2 : 在/data备份好一些文件,然后删除这些文件,释放一些inode,然后创建一个文件夹/data/cache2。在cache2下挂载一个新分区: sda4 ,下次写数据需要写到新分区cache2目录下。

inode分区完后,不可以增加inode数量,改变inode大小,但是inode总数和inode大小是在格式化时进行修改的。

mkfs.xfs
no device name given in argument list
Usage: mkfs.xfs
/* blocksize / [-b log=n|size=num]
/
metadata / [-m crc=0|1,finobt=0|1,uuid=xxx]
/
data subvol / [-d agcount=n,agsize=n,file,name=xxx,size=num,
(sunit=value,swidth=value|su=num,sw=num|noalign),
sectlog=n|sectsize=num
/
force overwrite / [-f]
/
inode size / [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,
projid32bit=0|1]
/
no discard / [-K]
/
log subvol / [-l agnum=n,internal,size=num,logdev=xxx,version=n
sunit=value|su=num,sectlog=n|sectsize=num,
lazy-count=0|1]
/
label / [-L label (maximum 12 characters)]
/
naming / [-n log=n|size=num,version=2|ci,ftype=0|1]
/
no-op info only / [-N]
/
prototype file / [-p fname]
/
quiet / [-q]
/
realtime subvol / [-r extsize=num,size=num,rtdev=xxx]
/
sectorsize / [-s log=n|size=num]
/
version */ [-V]
devicename
is required unless -d name=xxx is given.
is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),
xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).
is xxx (512 byte blocks).

参数:

[-i bytes-per-inode] 修改inode大小

[-I inode-size] 修改inode数量

4.2 实战:修复服务器文件系统

实战场景:公司服务器突然断电后,再次启动后,报如下错误。

linux文件系统修复

根据提示输入CTRL+D或者输入ROOT密码
解决方法:
输入root 密码
fsck -f -y /dev/sda1 #把引导分区文件系统修复一下,举例引导分区在/dev/sda1下,需要确认自己的引导分区
fsck -f -y /dev/sda3 #把根分区文件系统修复一下 ,需要提前确认自己的根分区挂在在那个盘
reboot 重启
fsck参数:
-y 对所有问题都回答 "yes"
-f 即使文件系统标记为 clean 也强制进行检查


---END---
2019-5-10 1:19:28
posted on 2019-05-10 01:23  平复心态  阅读(1487)  评论(0)    收藏  举报