linux磁盘及文件系统管理初步
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux磁盘及文件系统管理初步相关的知识,希望对你有一定的参考价值。
分区创建以及让内核重新读取分区表演示操作:
分区演示:
[[email protected] ~]# fdisk -l //查看当前系统上的磁盘分区情况
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
[[email protected] ~]#
根据上面的显示可知我们还能创建逻辑分区,因为扩展分区总大小为“137829376”,但是扩展分区的实际大小为“4096000”,所以我们还能创建逻辑分区,
[[email protected] ~]# fdisk /dev/sda //进入指定的磁盘管理窗口
WARNING: DOS-compatible mode is deprecated.It‘s strongly recommended to
switch off the mode (command ‘c‘) and change display units to
sectors (command ‘u‘).
Command (m for help): p //查看当前磁盘的分区情况
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
Command (m for help): n //添加新的磁盘
First cylinder (9460-26109, default 9460):
Using default value 9460
Last cylinder, +cylinders or +size{K,M,G}(9460-26109, default 26109): +2G//指定新分区的大小
Command (m for help): p //显示新的分区表信息
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
/dev/sda6 9460 9721 2100029 83 Linux
Command (m for help): d //删除分区
Partition number (1-6): 6 //删除分区标号为6的分区
Command (m for help): p
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
Command (m for help): n
First cylinder (9460-26109, default 9460):
Using default value 9460
Last cylinder, +cylinders or +size{K,M,G}(9460-26109, default 26109): +2G
Command (m for help): P
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
/dev/sda6 9460 9721 2100029 83 Linux
Command (m for help): W //我们分区完成后,用w命令保存退出时,会有一些问题告诉我们,下面显示的信息,说设备资源忙,这代表了什么意思呢?这时我们使用命令:‘fdisk -l’
命令查看我们的分区表,能够看到我们的新分区,但是使用命令“cat /etc/partitions”查看时,这个文件记录的内核能够是别的分区中,并没有我们先创建的分区。
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING:Re-reading the partition table failed with error 16: Device or resource busy.
Thekernel still uses the old table. The new table will be used at
thenext reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
[[email protected] ~]# fdisk -l //这里能够显示我们新创建的分区,但是并不代表我们的内核就能够识别他,我们以前讲过,对于硬件的管理,都要靠操作系统,而在linux上管理硬件的操作系统,我们称之为内核。
Disk /dev/sda: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108cylinders
Units = cylinders of 16065 * 512 = 8225280bytes
Sector size (logical/physical): 512 bytes /512 bytes
I/O size (minimum/optimal): 512 bytes / 512bytes
Disk identifier: 0x000066a0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinderboundary.
/dev/sda2 26 6400 51200000 83 Linux
/dev/sda3 6400 8950 20480000 83 Linux
/dev/sda4 8950 26109 137829376 5 Extended
/dev/sda5 8950 9460 4096000 82 Linux swap / Solaris
/dev/sda6 9460 9721 2100029 83 Linux
[[email protected] ~]# cat /proc/partitions //这个文件中保存了内核能够识别的所有分区,可 以看到这里并没有sda6分区,也就是说新建的分 区并没有被内核识别。注意:在已经分区并且已经 挂载其中某个分区的磁盘设备上创建新的分区,内 核可能在创建完成后无法直接识别;
major minor #blocks name
8 0 209715200 sda
8 1 204800 sda1
8 2 51200000 sda2
8 3 20480000 sda3
8 4 1 sda4
8 5 4096000 sda5
[[email protected] ~]#
[[email protected] ~]# partx -a /dev/sda //当我使用这个命令更新内核的这个文件时,可能出 现第一次更新不成功的现象,我们需要再次执行上述的命令。
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
BLKPG: Device or resource busy
error adding partition 3
BLKPG: Device or resource busy
error adding partition 4
BLKPG: Device or resource busy
error adding partition 5
[[email protected] ~]#
[[email protected] ~]# partx -a /dev/sda //再次执行这个命令,出现了我们新添加的分区
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
BLKPG: Device or resource busy
error adding partition 3
BLKPG: Device or resource busy
error adding partition 4
BLKPG: Device or resource busy
error adding partition 5
BLKPG:Device or resource busy
erroradding partition 6
[[email protected] ~]# cat /proc/partitions
major minor #blocks name
8 0 209715200 sda
8 1 204800 sda1
8 2 51200000 sda2
8 3 20480000 sda3
8 4 1 sda4
8 5 4096000 sda5
8 6 2100029 sda6
[[email protected] ~]#
创建新分区的时候,指定分区大小的时候,centos6是指定加多少个柱面,centos7是加多少个扇区,一个扇区大小为512字节,但是我们这里不管这些,我们一般都是直接加大小,单位为“K,M,G”
注意:
在已经分区并且已经挂载其中某个分区的磁盘设备上创建新的分区,内核可能在创建完成后无法直接识别;
查看新建的分区是否被内核识别:
cat /proc/partitions
通知内核强制重读磁盘分区表:
centos5:partprobe [device] //如果[device]省略。则表示重读所有的磁盘分区表
centos6,7:partx 或 kpartx
partx -a [device] //如果执行一次不行,我们需要连续执行两次
kpartx -af [device]
只有确认在文件/proc/partitions中,有了新建的分区,我们才能继续后面的相关操作。比如说创建文件系统等相关操作。
分区创建完成以后,我们下一步在分区上创建文件系统。
注意:
在centos系统上能够实现分区创建创建的工具有:parted,sfdisk;
创建文件系统:
为什么会用到文件系统?
解:
对于一个分区创建完成以后,其实他就是一大段的连续空间,但是对于这个大段空间来讲,我们以后放多少个文件,放什么样的文件,每一个文件放在什么位置,我们如何做到按名存取文件,这就特别麻烦,因为在磁盘上,文件数据最终都表现为0101010101....的二进制磁性信息的存放,但是我们要想最终能够做到按照文件名的方式来存取,就需要现在一个分区上,进行格式化操作。
一个磁盘分区如果也想要实现类似于书上的目录那样,按名存取数据,这中法则,那么文件系统也需要存取数据和元数据,但是这两者是要分开存放的。所以所谓高级格式化的过程,或者叫创建文件系统的过程,就相当于在分区这段空间上,切割出一部分空间,用来放元数据,而另外一部分剩下的用来存放数据。而且元数据一般情况下占的空间比较小,所以文件系统分为元数据区域和数据区域,
元数据区存放什么呢?
就放每一个文件的属性信息,比如文件的大小,文件的权限,文件的属主属组,文件的时间戳,但是一定要注意,文件的元数据不包含文件名,文件名是在目录上存放的。文件元数据中,是不包含文件名的,其文件名是在目录中存放的。
格式化操作分为:低级格式化,高级格式化
低级格式化:是在硬件出厂时,由生产商进行的,低格的主要作用在于划分磁道,这是在分区之前要做的,形成簇。
高级格式化:是在分区之后进行,主要作用创建文件系统。
文件是由元数据和数据组成。
比方说书,书上的目录就好比元数据。
磁盘分区被划分为:元数据区和数据区
元数据区:
文件元数据:inode(index node)
大小,权限,属主属组,时间戳,数据块指针.....
(每个文件的元数据格式是一样,只是里面填充的内容不一样,用来为单个文件,存储其属性的,或者说存储其元数据的空间,就称为文件的索引节点号,inode)
数据块指针:指向了磁盘中那些编号的数据块是用来存放这个文件的。
所以只有找到了文件的元数据,然后才能找到文件的数据块指针,然后由数据块指针才能知道在这海量的数据块中,那些数据块是被这个文件所使用,从而我们才能读到这个文件的内容。
数据块指针是需要磁盘空间存储的,而在元数据存储空间中,存储数据块指针的空间大小是一定得,也就是文件的大小是由上限的,
(每一个文件的元数据格式是一样的,只是填充的内容不一样,这每一个用来存放单个文件存储其属性的元数据的,每一个固定格式的空间,就叫做他的索引节点号。所以每一个文件都是按照固定格式存放的,所以每一个文件的inode格式都一样,但是里面的数据不一样,所以我们的系统在格式化时,直接将这个inode区域划分好了,直接划分好有多少个inode,只不过是这些inode是空的,里面没有填充任何数据,只有当我们保存一个文件时,这个inode空间中,才会被填充上数据,才会被临时填充进去,这个inode空间的大小是规定的,因为每个文件的inode格式是一样的。那么就爱你的数据是存放在数据区,那么数据区很大,我们应该将数据存放在哪里?
而且文件的大小是不同的,有的文件1K,有的文件1M,我们应该怎样组织这样的空间,使得能够为每个文件分配足够的空间,同时又不至于太浪费,应该怎样做?
其实很容易理解,我们就将这个空间划分去肯多的子单位,我们将这些子单位称为块,叫block,最大的磁盘块我为4K,其实这个块要比扇区大,而且这些块能存放2^n个扇区,通常很少有单扇区的,一般来讲是2^1个,2^2个,....因为一个扇区是512字节,所以两个扇区就是1K,所以这样我们的磁盘空间就被统统划分成了磁盘快,等更小的逻辑组织单元,因此一个文件到底该占多少块呢?
看文件的大小,这样文件到底需要填充多少数据,我们按需给他分配块数即可,如果能连续固然很好,如果某个文件占用的磁盘快不连续,就说明这个文件中有碎片
为什么我们的文件占用的磁盘块不连续?
解:
因为我们在磁盘上经常创建文件删除文件,而文件的大小各不相同,这就导致了可用的磁盘空间块不连续了,因此一个文件占据的磁盘块就有可能是一段,然后跳过另一个文件占用的磁盘块,然后再是自己所占用的一段连续的磁盘快,这种情况我们就叫做磁盘空间生成了碎片,或者说文件中有碎片,那么我们就想这个磁盘块该多大好呢?1K?2K?
.....我们知道块是最小的存储单元,所以一个块只能存储一个文件,那么如果当前系统上小文件比较多,一个文件中只存那么几个字节,那么这时候磁盘块是小了好,因为这个块只能属于这一个文件,而这个文件一共就占几个字节,剩下的空间就浪费掉了。并且浪费是必然的。在windows上也是有这种现象,在某一目录点击右键,看文件大小,会显示文件大小与所占的空间大小不一样,文件已占据的空间一般是大于文件的大小的,就是这个原因导致的,所以说这个块大小,是取决于我们的文件大小。)
上面就是一个文件系统布局的简单描述。数据区要有block,元数据区要有inode,这个inode要不断地通过其数据块指针来标明这个文件到底占据了哪些磁盘快。
什么是链接文件?什么是设备文件?他们为什么很特殊,特殊在什么地方?
解:
链接文件特殊在,在每一个链接文件中,本来这个文件的inode中最后是指向磁盘块的,但是他没有指向任何磁盘快,而是指向了另一个文件的访问路径,该存放数据块指针的地方,没有存放数据块指针。
即:
符号链接文件:存储数据指针的空间当中存储的是真实文件的访问路径;
设备文件:存放数据指针的空间当中存储的是设备号(major,minor);
符号链接文件和设备文件是不真正占据磁盘数据空间的
一个较大的分区里面,应该创建多少个inode?也就是说我们的元数据区多大为好?
如果说我们的元数据区过小,里面只存储了100个inode,而我们的100个文件又都很小,导致的结果是,100个文件创建完了,元数据区就没有空间了,然后我们的数据区中我们利用的空间只占据我们数据区总空间的三分之一,那么三分之二的空间还在那空闲着呢,并且这些空间就不能再被利用了,除非我们现有的文件增大,否则数据区那些数据块就用不上了,因为我们知道,任何数据块要想被访问到,只能通过元数据区的数据指针来指向,但是现在我们的元数据区中的没有多余的空间了,所以我们剩余的数据块就不能再被利用,并且有可能还有另外一个极端,我们存放了好多个大的单个文件,使得数据区的空间占完了,但是我们的元数据区的空间只用了三分之一,那三分之二就没用了,没用了,那么空间就白白浪费了,那么这两种可能性都会出现,那么就需要我们在这两者之间找一个较好的折中值,相差不要太多,那么想多多少为好呢,这个几乎是无法预估的,除非我们做一下精确计算,一般我们都是采用历史经验来进行评估,比如我们评估以后,我们大体上得出,每多少个数据块留一个inode,例如,每10个块一个inode,每4个块一个inode,这样子吧空间划分开来,做一下评估,像这种方法就是数据块与inode之间的比率,二者之间是有一个比率的,这个比率多少为好,我们需要根据我们的使用经验,来判断,没有合理的值,如果说我们的磁盘空间装满了,怎么办?我们作为一个系统管理员来讲,我们的磁盘空间满了的话,我们的所有运行的进程,那怕是要产生的临时文件,或者做一些操作时,因为没有空间,就会导致这些操作都不能进行,我们不应该看到这种情况发生,那我们应该怎样做?
我们的磁盘空间划分成元数据区,和数据区后,我们要在数据区预留出一部分空间,供超级管理用户使用,万一这些磁盘空间被占满了,那么将来如果希望将一些文件改改名或者移动一下,或者删除了,那么我们留下这段空间就当做我们的工作空间,这就叫做预留空间,一般来讲,我们的linux系统都是需要预留空间的,这就是我们linux系统管理的基本法则,
当我们的文件系统使用很久以后,我们怎样知道元数据区中那些inode被分配了,哪些inode还尚未被分配,还可以继续使用,一个磁盘块只有1K,一个100G的空间,该有多少个这样的块?将来我想存一个新文件的时候,首选需要在元数据区找一个inode,将文件的元数据填进去,然后再到磁盘空间中找一些block,来存放文件的数据,那我们怎样知道哪些block是空闲的,哪些inode是空闲的呢?
解:
如果我们要做一下全盘扫描的话,效率会非常低,为了要找一个空闲块,我们从开始到最后一个个的去找,效率必然是非常慢的,那么我们就考虑索引,因此磁盘块要索引,inode也要考虑索引,所以我们就需要找一个位置,专门用来存放所有磁盘快的索引,每一个对位索引,第一个磁盘块就占据这个索引的第一个位置,对于每一个磁盘块在这个位置上只给他一位的空间,用数字0表示这个磁盘块是空闲中,用数字1表示这个磁盘块已经被使用,所以将来我们要想知道哪些磁盘块已经被使用,哪些磁盘块没有被使用,就不需要扫描整个空间了,我们只需扫描这个索引即可,而这个索引是按位对位索引的,每一个磁盘快一位,所以这种就叫做位图索引。
bitmap index:位图索引。
对于inode也同样适应,inode的索引叫inodemap index:inode位图索引。每一个inode按序号对应一个位,标记为1,表示inode已使用,标记为0表示inode为空闲状态,可使用。所以我们将来再找的时候,我们只需去扫描这个inode位图索引,或者磁盘块的位图索引。
其实上面所说的一切,组合起来其实都是放在元数据区中,所以我们的元数据区中,除了存放inode数据之外,还有inode位图索引所占据的空间,以及block的位图索引所占据的空间,但是即便如此,我们管理起来仍然又不便的地方,比如说100G的空间,到底有多少个数据块,就算我们扫描block的位图索引,也需要半天扫描,也需要花费不等的时间,比方说我们有一本书,这本书有一万页,即便是这本书有目录,但是我们找其中的某些内容也是很慢的,那么我们能不能将这一万页中的内容进行分分类,比方说,我们将第一章单独成书,第二章单独成书,所以现在的磁盘分区,并不是上来就是元数据区,和数据区,而是在分区内部有划分了二级结构,我们拿到任何磁盘分区的时候,在其内部划分问件系统是这样划的,首先是将这个分区划分成一个一个的独立的逻辑单位,作为用户来讲是不可见的,而这些独立的逻辑单位主要作用就是来存放磁盘块的,这样就把磁盘快分组了,所以我们叫这个逻辑区叫块组,叫datablock,而每一个块组,就是一个自治区,他从高度的中央集权制,转换成了联邦制,每一个联邦都有自己独立的司法权,所以这些每一独立的块组,都可以有自己的元数据区和数据区,而且是每个块组之间的元数据区和数据区是分而治之的。那么这就有一个问题,当我们在第一个块组中存放文件时,如果存不下了,那该怎么办?因为这些块组只是逻辑上划分的空间,就好比中国的山东省的公民,就不能来北京,因为这个人仍然都属于整个中国人,也就是说山东人照样可以去北京买房子,这也是可以的,从买没有户口一说,没有几年的社保一说,因为我们都是一个国家的公民,大家是生而平等的,道理是一样的,当我们在分区中的第一个块组中存放文件时,当空间不够用了,我们可以到其他的块组中使用其他块组的磁盘块,这是没有问题的,当然要是能在一个块组中是更理想的。
所以这样以来,我们每一个磁盘分区内部,就能够通过块组的机制,把一个大问题切割成n个小问题,每个小问题在自己内部独立解决,解决不了的在块组之间进行协调
而真正现实中使用时,也是基于这种机制来实现的。
而对于这些每一个块组来讲,还需要一个整体的想象开对外展示,所以我们就需要有这么一段空间来明确标明,这个空间有多少个逻辑块,每一个逻辑块有多大的空间,而这个空间对于我们的磁盘来讲就叫做超级块叫做superblock,这里面定义了我们的磁盘分区中有多少个块组,每一个块组从哪一个编号开始,到哪个编号结束,都在这个超级快进行了统计,所以如果这个超级块坏了,就意味着整个逻辑结构就崩塌了,因此就没法使用了,所以说超级快至关重要。
所以我们为了避免这个超级块损坏而使得整个磁盘空间不能使用,那么我们就需要将这个超级块进行备份,要做冗余处理,我们又知道,超级快首先是一个数据块才行,所以说超级块首先也是属于块组,也就是说,超级块也是在块组中的某个块中存放。
由此超级块放在哪里呢?
超级快可能放在某些块组中的某个编号的块上
综上所述:
所谓的块组,首先他是先划分成块的,划分成一个有一个的块,然后在这些众多的块之间才去切割谁是元数据,谁是数据的。其实在前面我们说的,分区中,上来解切割元数据区和数据区,是不精确的,而是整个磁盘分区首先划分成块,然后再拿出一部分块来存放元数据,其他的数据块存放数据,同样块组也是一样,有些块是存放元数据,有些块是存放数据,只不过在这些众多的块中,有一些块是superblock,有些是数据块。而不是每个块组都有超级块,超级块仅仅是存在于某些块组中的某个编号的块上,但是在每个块组中的元数据区中,除了可能有超级块之外,还必须要有一个记录本块组使用哪些磁盘块的记录,这个就称为块组描述符,我们成为GDT,块组描述符,这个GDT中存放的是本块组中的块的编号是从哪里开始,到哪里结束,并且还记录了,本块组中有多少个inode,多少个datablock,而且这写inode中,哪些已用,哪些未用,应该用位图索引,其实这时候的位图索引是单块组实现的,即无论是块位图索引,还是inode位图索引,,都是在块组级别上实现的。通常这些要结合,Gdt和位图索引,再加上inode表实现的。
什么是inode表?
在分区中,存放大量的inode信息,这个空间就叫做inodetable,并且每一个inode都有一个inode编号,一定要注意,每一个inode都要有其编号的。
演示:
[[email protected] ~]# ls -i //每个文件前面会出现一个数字,而这个数字就是这个文件的元 数据索引inode的编号。注意不是inode的本身,是他的编号。
2372936 anaconda-ks.cfg 2373363functions 2372956 Pictures
2373295 cacert.pem 2373457 grep.txt 2372953 Public
2373482 CentOS 2359298 install.log 2372952 Templates
2372950 Desktop 2359299 install.log.syslog 2372457 testdev
2372954 Documents 2373035 lovers.txt 2372957 Videos
2372951 Downloads 2372955 Music 2372949 welcome.sh
2373340 fstab 2373350 myshell.sh
[[email protected] ~]#
[[email protected] ~]# stat anaconda-ks.cfg //查看inode中存放的数据,注意inode是元数据 不是真正的数据。
File: `anaconda-ks.cfg‘
Size: 1481 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 2372936 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2016-10-17 00:14:01.127279925 +0800
Modify: 2016-10-11 12:54:08.092999187 +0800
Change: 2016-10-11 12:54:39.871999161 +0800
[[email protected] ~]#
上面讲过,文件名不在分区中的元数据区存放,而是在目录中存放,目录也是一个文件,并不像windows中描述的目录是文件夹一样的东西。
linux中目录到底怎样用?
我们以前讲过根文件系统,什么是根文件系统?根文件系统在什么时候被内核识别的?
内核启动完成后,就要加载这个根,然后我们才能真正访问根上的文件和命令,才能被shell运行起来,所以根在哪呢?在内存中,在内核上,内核自己会知道的,但是不管怎么讲,根也是一个目录,假如说我们现在要找一个文件,
例如。我们要找/var/log/messages这个文件,那么这个路径名到底是怎样映射的?
刚刚我们一直在讲,每一个文件都有她自己的inode,首先根的inode在什么地方?在内核中,我们要知道根是能够自己引导的,是能够自我识别的,有这么一种机制,那我们应该怎样找“/var/log/messages”文件呢?我们先找根的inode,目录也是文件,也有自己的元数据和数据,当们找到了根的inode,在根的inode元数据区中的数据指针,是指向存放数据的磁盘快,然后这个磁盘块中放的是什么?这个磁盘块存放的是这个这个目录下可以直接找打的所有的文件的文件名和文件的inode对应关系,也就是说,我们通过根的数据指针找到了根的数据块,这个数据块总存放了文件var和其对应的inode编号,然后我们在根据var的inode对应的编号,反过来再查这个存放文件的表,var的inode编号指向的肯定是一个具体的inode,然后这个inode中存放的是var自己的元数据,然后var也应该指向他所指定的磁盘块,然后这个磁盘快中存放的是在var目录下直接能够找到的文件名和对应的inode编号,同理,我们就能找到了文件messages然后我们在根据messages的元数据指针找到文件的磁盘快,然后读取文件的内容。
所以目录其实就是路径的映射,如果每一次找文件都这样找是不是太慢了?那我们将找到的文件缓存下来,下次再找就快了,我们在内存中有大量的空间都是用来存放缓存数据的。
[[email protected] ~]# free //可以查看我们的内存空间,和使用情况,还有缓存情况
total used free shared buffers cached
Mem: 1907300 727024 1180276 2308 37876 345276
-/+ buffers/cache: 343872 1563428
Swap: 4095996 0 4095996
[[email protected] ~]#
buffers cached //中既有元数据又有数据,但是他们是分开存放的。
文件名并不是在inode中存放,而是在目录上存放,目录也是文件,也就是说文件名是存放在数据块上。
根据上面的描述,我们可以描述一下linux中的文件系统:
文件系统有很多种,想windows中的FAT32,有NTFS,像linux也有很多种文件系统:xfs,ext2, ext3,ext4,btrfs;linux是开源的,能够支持n种文件系统。
不同的文件系统意味着什么呢?
意味着他们在磁盘上,划分磁盘块,创建元数据,查找元数据,各自组织结构并不完全相同,是各自一套管理机制,不同的操作系统在不同的场景下优势也是不一样的,linux是开源的自由的,所以他能支持N多种文件系统,但是不同的文件系统,他们各自管理的文件方式是各不相同的,各自的访问接口也是不相同的,但是如果对于一个程序员来讲,我创建程序是要随时创建文件,但是对方的文件系统不知道,要各自实现一边,所以很麻烦,所以对于linux而言它使用VFS
linux是用的文件系统是:VFS,全称:virtual file system
什么是VFS?
就是当两个层次不衔接时,在中间加上一个中间层,这个中间层自己要能够与不同的事件打交道,但是向上输出的接口是整洁而统一的。所以程序要要想往不同的文件系统存数据时,只需要调用VFS的接口就行,这一层就是虚拟层;
在linux中有一个重要的一句话:
任何两个层次不能衔接时,都能加上一个中间层进行衔接。
linux通过这种机制,使得自己能够支持市面上大多数的文件系统:
Linux的文件系统:
ext2,ext3,ext4,xfs(是一个企业级的文件系统,单个文件没有上限),reiserfs,btrfs,
光盘文件系统:iso9660
网络文件系统:nfs,cifs
集群文件系统:gfs2,ocfs2
内核级分布式文件系统:ceph
windows的文件系统:vfat,ntfs
伪文件系统:proc,sysfs,tmpfs,hugepagefs
Unix的文件系统:UFS,FFS ,JFS
交换文件系统:swap
用户空间的分布式文件系统:mogilefs moosefs glusterfs
上面的众多文件系统中,只有ext2没有日志。
交换文件系统
交换文件系统是用来做数据交换的。我们知道对于计算机来讲,五大部件是CPU,内存,I/O;但是内存空间很有限,但是作为一个程序员来讲,我们应该假设自己有多少内存可以用呢?程序跑是跑在内存上,数据至少在内存里面,但是作为程序员来讲,在开发时必然手动操作内存,那么我们应该假设自己有多大的内存可用?如果对方有4G,但是我们自己仅假设有512M,那么这样就不能利用对方的性能了,在一个,如果对方的内存为512M,我们却假设有4G,那程序就跑不起来,为了避免出现这种情况,现在任何程序员写的程序,也不会跑在硬件上,事实上,我们的linux采用这么一种机制来实现,叫虚拟内存,我们就找一个磁盘空间,伪装成内存使用,那怎么是交换呢?
因为虚拟内存,毕竟是假的,不能拿来直接使用,CPU想访问数据时,,只能使用真实的内存中的数据,但是真实情况下内存的空间被占满了,怎么办?把那些不常用的,叫最近最少使用我们有一个lru算法,这个算法叫最近最少使用算法,当然还有别的算法,这个算法将内存中不常用的,活动量不大的进程移到虚拟内存中,然后内存就又有空间运行其他的进程了。让这个进程在被使用时,则再将其他的进程移动到虚拟内存,然后再将这个进程运行。所以就叫交换分区。
对于现在操作系统来讲,交换分区是必须要有的,因为现在的操作系统,linux还是windows都是虚拟内存机制的,所以这就叫做交换分区,叫swap
创建文件系统,其实就是格式化一个分区
文件系统管理工具:
(1)创建文件系统工具
mkfs
mkfs.etx2,mkfs.etx3,mkfs.etx4,mkfs.xfs,mkfs.vfat,......
(2)检测及修复文件系统的工具
fsck
fsck.ext2,fsck.ext3,.........
(3)查看其属性的工具
dumpe2fs,tune2fs
(4)调整文件系统特性:
tune2fs
日志(journal):
文件系统可以分为两类:
有日志的文件系统;
无日志的文件系统。
那日志有什么用呢?
文件系统有两类内容,一种是元数据,一种是数据,我们创建文件时,即创建元数据,也要创建数据,假如我现在创建一个新文件,则第一步,在inode表中找一个空闲的inode,把文件的创建时间,访问时间,修改时间,时间戳写进去,属主属组也确定了,那么我们在想在文件真正存储完之前,我们是不能确定这个文件真正需要多少个磁盘块的,那么我们应该给这个文件分配几个磁盘块呢?一个,并不理想,如果我们的文件系统有大量的文件正在存储,第一个文件用第一个块,第二个文件放在第二个块,但是当第一个文件使用的第一个块不够时,还需要另外的磁盘块进行存储,但是第二块已经被占用,所以这样存储的文件就不连续了。不连续的文件在将来访问的时候,性能会很差,我了避免出现文件碎片,或者说为了降低出现文件碎片的概率我们应该怎么办?因为磁盘碎片是避免不了的,一般来说,我们在创建文件时,我们会一下给这个文件分配多个磁盘块,例如我们一下给一个文件分配了8个连续的磁盘块,但是文件存完后只占据了两个磁盘快,然后剩下的6个我们再将其释放掉就行了。如果8个不够用,那么就再分配8个,
所以我们在创建一个文件时,我们先是去找一个元数据区,然后将这个文件填进去,然后再分8个块,用来存数据,那么我们想象一下,这个数据的确会占据8个块,或者占据6个块,但是我们存数据的时候,存到第五个块时,突然断电了,那么这个文件不完整,下次开机进行访问时,我们打开文件发现文件不完整,像这样的文件就叫做“不一致文件”;像这种文件我们应该怎么办?要是能够补完整,就补完整,如果不能补就把这个文件删掉,否则放着是对别人的一种误导,而且还占据空间,
那么我们怎样知道上次断电时,哪些文件没有写完, 不知道,就自上而下进行扫描, 看看哪个文件的时间戳,在上次关机时发生的,然后再找找他的文件是不是完整,但是这样就必然是全盘扫描,如果我们的磁盘是200G,有180G的文件,那么这个一扫描,一上午的时间就过去了,那该怎么办?
我们应该加速这个过程,这就是日志的作用,我们可以在我们的磁盘空间中再找一段空间,做日志区,刚才我们讲创建文件时,我们现在元数据区分配磁盘块,然后我们再在数据块中存储数据,但是这个时候我们的元数据不再放在元数据区,而是放在日志区,把文件的元数据先放在日志区,接着我们一样给文件分配磁盘块,存数据,如果存数据时完整的存储了,那么再将元数据信息,从日志区移动到元数据区,如果存到一般系统停了,那么但凡处在日志区的都是没有完成的,所以开机的时候我们只需修复日志区的数据即可,不用再去全盘扫描了,这就是日志的作用。
日志的缺点:
有了日志功能,最大的劣势就是系统性能的损失,因为元数据需要写两次,每一次都是I/O。
链接文件:
访问同一个文件的不同路径;
硬链接:
硬链接是指向同一个inode,的多个路径。
因为每一个inode指向的磁盘块是固定的,那么既然两个路径找到了同一个inode,那 么他找到的文件应该是一样的。
特性:
(1)目录不支持硬链接;
(为了避免循环连接)
(2)硬链接不能跨文件系统;
(不同的文件系统他的inode是独立管理的)
(3)创建硬链接会增加inode引用计数;
创建:
ln src link_file //一定要注意,源文件在前,连接文件在后
支持的选项:
-v:表示显示详细的创建过程;
举例:
[[email protected]~]# ls -l
-rw-r--r--.1 root root 899 Oct 26 22:29 fstab
[[email protected]~]# ln fstab fstab.2 //创建硬链接,格式是源文件在前,连接文件在后
[[email protected]~]# ls -l //并且注意到硬链接文件不会指向源文件
-rw-r--r--.2 root root 899 Oct 26 22:29 fstab
-rw-r--r--.2 root root 899 Oct 26 22:29 fstab.2
[[email protected]~]# ln -s fstab fstab.3 //创建符号连接文件
[[email protected]~]# ls -l //符号链接文件会指向源文件
lrwxrwxrwx.1 root root 5 Nov 8 16:51 fstab.3 -> fstab
-rw-r--r--.2 root root 899 Oct 26 22:29 fstab
-rw-r--r--.2 root root 899 Oct 26 22:29 fstab.2
[[email protected]~]# rm -f fstab //现在我们将源文件删除
[[email protected] ~]# cat fstab.2 //硬链接文件仍然可以使用,因为他指向的是inode。
#
# /etc/fstab
# Created by anaconda on Tue Oct 1112:39:17 2016
#
# Accessible filesystems, by reference, aremaintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8)and/or blkid(8) for more info
#
UUID=2ead7599-15b0-4b11-b96d-5f9b59e2e7eb/ ext4 defaults 1 1
UUID=edb28e3e-5ee7-400f-8226-fab5fa157188/boot ext4 defaults 1 2
UUID=32376552-a128-416d-be08-0aa6acab4661/testdir ext4 defaults 1 2
UUID=091e5b14-8201-4ffc-9278-41b7acae00d9swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[[email protected] ~]#
[[email protected] ~]# cat fstab.3 //源文件删除,符号链接文件就失效了。
cat: fstab.3: No such file or directory
[[email protected] ~]#
[[email protected] ~]# ls -l //再次查看时,如果符号链接的源文件被删除,那么现实的符号链 接会变红,并闪烁。
上述情况,我们要想恢复这个符号连接,我们只需再创建一个文件,并起名为fstab即可,他不会关心文件的内容;
符号连接:
指向同一个文件路径的另一个文件路径;
每一个文件都应该有他自己的inode,但是在自己的inode中的磁盘快指针区域没有指向磁盘块而是指向了另外一个文件的路径。
特性:
(1)符号链接文件与源文件是两个各自独立的文件,各有自己的inode;
(2)支持对目录创建符号链接,可以跨文件系统;
(3)删除符号链接文件不影响源文件,删除源文件,符号指定的路径即不存在, 此时会变成无效连接;
创建:
ln -sv src link_file
支持的选项:
-s:创建软连接时使用的选项
-v
注意:符号链接文件的大小是其指定的文件的路径字符串的字符个数;
举例说明:
(1)假如说我们去一商场购物,有两条路都可以去,其中一条路坏了,我们从另一条路上也可以到达,这两条路的互不影响,这就是同一文件的硬链接,彼此之间互不影响。
(2)我们同样去一个地方,我们有一个向导A带着我们,但是路程走到一半的时候哈,A告诉我们怎么去,他忘了,但是他告诉我他知道B知道怎么去,然后就让我们去问B,然后我们就再去找B,然后通过这个人我们才能真正到达目的地。所以现在我们看来,真正指向内容的文件是真正的文件,但是指向另外一个文件的文件,就叫符号连接文件。他只是多了一条路径。符号连接也称为软连接。
硬链接与符号连接的区别,硬链接指向同一个inode,而符号连接是不同的inode,是一个文件路径指向另外一个文件路径,前一个文件有自己的inode,inode中存储的是另一个文件的路径。而第二个文件的inode是指向磁盘块的。
创建硬链接:
ln 源文件 连接文件
创建符号连接:
ln -s 源文件 链接文件
本文出自 “11847750” 博客,请务必保留此出处http://11857750.blog.51cto.com/11847750/1875113
以上是关于linux磁盘及文件系统管理初步的主要内容,如果未能解决你的问题,请参考以下文章