Linux文件系统基础
一、 磁盘基础
1. 机械硬盘基础
- 磁头:用来在每个盘片上读取数据
- 盘片:通过一个马达带动做同心旋转,双面都可以存储数据,硬盘中可以有多个盘片
- 磁道:track,用来存储数据,在每个盘片上都会划分,形状为圆形,一个盘片可以划分出多个同心圆
- 柱面:cylinder,在不同盘片上,相同编号的磁道组成的逻辑柱状空间,分区是按照柱面分的,最外圈的柱面单位时间内所能读取的数据也是最多的
- 扇区:secotr,每个盘片上扇形空间
2. 磁盘接口类型
IDE
:并口,早期个人桌面应用SCSI
:并口,IDE接口不适用于I/O频率较高的场景,而诞生了SCSI,早期企业级应用的硬盘接口SATA
:串口,现阶段用于个人桌面SAS
:串口的SCSI技术
3. 命名方式
/dev/hd[a-z]
:IDE硬盘,centos 6后就不加区别了,统称为sd开头/dev/sd[a-z]
:SCSI、SATA、USB、SAS
4. MBR
Master Boot Record,主引导记录,用于记录磁盘磁道、柱面、扇区的划分方式。通常被分配在0磁道的0扇区。共512字节
- 前446字节:用来存放操作系统的加载程序,我们称为Bootloader
- 中64字节:存放分区表,每16字节标识一个分区,最多支持4个分区,而现如今磁盘空间越来越大,如果依旧使用4个分区显然已不能满足需求,为解决MBR天生只支持4个分区的问题,诞生了GPT,最多支持128个分区
- 最后2字节:标识当前mbr区域是否有效,一般55AA表示有效
注:扩展分区,因4个分区不够使用,所以可以将一个原本存储主分区表信息的空间指向磁盘上的一段空间,利用新指向的空间来划分区,那么存储指向信息的主分区就叫做扩展分区,而在被指向的空间中划分出来的分区,就叫做逻辑分区
二、 文件系统
1. 文件系统功用
用来按照特定的组织结构来存取数据,通过高级格式化实现,用来在磁盘分区中区分出元数据及数据的存储区域
2. 文件系统的组成(用ext系列文件系统说明)
为了便于管理,ext文件系统首先把磁盘空间分成若干个块组,接着在每个块组中划分出元数据区和数据区,元数据区和数据区都是由若干个小的磁盘块组成
下面是基于单个块组的介绍
2.1 元数据区
元数据是由Inode(索引节点)、inode table(inode表)、位图索引(位图)、块索引(位图)、数据指针
2.1.1 Inode(Index Node | 索引节点)
按照特定格式组织,用来存储单个文件的存放位置、大小、时间戳、权限、属主、属组等属性信息的空间,这个条目就称之为一个Inode(一个索引节点),如果需要访问数据,我们就必须先找到这个文件的Inode,在Inode中提取出这个文件的元数据信息,而后才可以访问
2.1.2 数据地址指针
数据地址指针是用来标识某个文件存储在哪些磁盘块当中。单个文件的大小取决于一个inode可以指向(引用)多少个磁盘块,为了能兼容更大的文件,ext文件系统就引入多级数据地址指针的概念,使得其可以兼容更大的单个文件,有直接指针、间接指针、三级指针之分,多级指针的概念很类似于扩展分区中指向逻辑分区的概念
2.1.3 索引位图 (inode bitmap)
假如新建一个文件,我们首先需要在Inode中找到一条空闲Inode,再分配使用,但这种方式效率太低了。可以利用一段空间专门存放Inode空闲的情况,这个条目就叫位图索引
2.1.4 块位图
类似索引位图,只是它是用来标识磁盘块的空闲情况的
2.1.5 inode table
存储inode条目的表格
2.2 数据区
2.2.1 块组描述符
用来描述本块组的大小、数据校验码、本块组Inode表的存储位置、位图索引的存放位置、空闲的块和inode、可用的数据块和可用的Inode条目的位置
2.2.2 超级块
用来描述整个文件系统的逻辑架构,里面定义了一共有多少个块组、每个块组的大小、文件系统的卷标、UUID、文件系统的特性、空闲磁盘块数、空闲Inode数等一些关于文件系统的信息,超级块自己也在块组中的某个磁盘块中存储,并且会在不同的块组中存储多份
2.2.3 磁盘块
专门用来存储数据的空间
2.3 日志区
无日志区的情况下,如果文件数据在存储过程中出现断电等异常情况,开机后,要想知道哪些文件没存完只能全盘扫描,对于容量很大的盘,需要的时间也会很长。如果有了日志区,在文件存储过程中,首先把文件的元数据存储在日志区中,如果这时出现断电,下次开机仅用查看日志区的内容就可以知道哪些文件没有存完。不过日志区也是有缺点的,因为任何文件的元数据在存储时都先存储到日志区,等全部数据存储完毕后,再将日志区的数据挪动到元数据区,这样就会带来一次额外的I/O操作的,它对比非日志文件系统的性能一定会有所下降的,不过对于今天的磁盘性能,这种差别都是微乎其微的,但它带来的好处却是显而易见的,所以设置日志区还是很有必要的
2.4 预留空间
在数据区会预留一些空间,用于在数据区数据存放满了的时候,管理员可以使用这些地方来挪动文件
3. 一次完整的文件查找过程
假设寻找文件/var/log/messages
- 首先,找到
/
的Inode元数据,从/
元数据中提取出/
的数据指针,接着根据指向查找磁盘块,在磁盘块中,一定会记录着/var
的目录名称和与之对应的Inode编号,从中提取出/var
目录的inode编号 - 拿到
/var
目录的Inode编号后,从元数据区找到这条Inode条目,提取出数据指针,接着根据指针指向去查找存储着/var
目录信息的磁盘块,其中一定有log/
目录的Inode编号 - 取得
log/
的Inode编号,在元数据区中取得log/
对应的数据块,从数据块中可找到message/
的Inode编号,最后通过message/
的inode条目,获取message/
的数据块存放位置,就可以查看message/
的数据了
注:其实目录也是一个文件,但它仅仅存放着通过这个目录能直接找到的文件和与之对应的Inode编号(父目录不存储子目录中文件的Inode编号,只存放直接能找到的文件的Inode编号),在内核查找文件的过程中,目录的作用就像一个路标,需要根据指向来回多次的才能找到最终数据,所以对于经常访问的数据,就可以将它缓存在内存中来加速访问,这就是buffer/cache
的意义
4. 格式化种类
假如把磁盘空间比作一个图书馆,那么格式化就是在屋子里摆上书架,并准备好一本册子用来做索引的过程
- 低级格式化:一般是在厂商出厂时进行的,用来划分磁道,行程簇等
- 高级格式化:分区之后进行,创建文件系统
5. 交换分区
程序员在编程时不能预知用户的内存资源,但又想充分利用用户的内存资源,所以linux就虚拟出一个内存空间告诉进程随便用,一旦物理内存满了,内核就会根据lru算法(最近最少使用算法)将有些进程挪到硬盘上的交换分区去。交换分区配额对不同的应用要求是各不相同的,如果跑的应用的Oracle或MySql这样的数据库,一旦使用了交换分区,那么它的性能是急剧下降的,对于这种应用交换分区分配1G或512MB就可以了,因为这种应用如果想跑的顺畅,那么就要提供充足的物理内存。如果跑的应用是科学计算、批处理的类似Hadoop这样的应用,对于内存量要求很大,但是对于性能要求不是很高,就可以使用大一些的交换分区。早期时候物理内存较小的时候如128MB、512MB,使用的交换分区大小是遵循物理内存的1.5倍到2倍,不过现在服务器内存动辄8G、16G,已经不太适用了,具体还是根据实际需求分配
6. 常见的文件系统
- ext系列:ext2、ext3、ext4
- xfs:centos7默认采用的文件系统
- btrfs:
- reiserfs:因作者入狱,后来没人维护了
- iso9660:光盘的文件系统
- 网络文件系统:nfs,cifs
- 集群文件系统:gfs2、ocfs2
- 内核级分布式文件系统:ceph
- windows:vfat、ntfs
- 伪文件系统:proc、sysfs、tmpfs、hugepagefs
- Unix文件系统:UFS、FFS、jfs(日志文件系统)
- 用户空间的分布式文件系统:mogilefs、moosefs、glusterfs
- vfs:虚拟文件系统,程序员开发程序时,不能预知用户的文件系统,为了不增加程序员的开发负担,就把底层各种类型的文件系统类型向上统一为vfs,由它解决底层的文件系统不统一问题
(8) 文件系统相关的配置文件:
- /proc/filesystems:可查看当前系统支持的文件系统类型
- /etc/mtab:追踪当前系统的所有挂载和卸载,mount命令查看的文件
- /proc/mounts:内核真正识别到的mount的分区
- /proc/partations
注:任何类型的文件系统如果想使用,那么必须事先加载它的模块,可使用lsmod查看
三、 文件系统管理工具
1. fdisk
提供了一个交互式接口管理分区,有许多子命令,分别用于不用的管理功能,所有操作均在内存中完成,不会直接保存在磁盘上,直到使用w保存才会生效,最能可管理15个分区信息
命令格式:fdisk [DEVICES]
交互式管理接口菜单选项
- m
:查看使用帮助
- l
:列出所有分区ID
- d
:删除指定分区信息
- p
:显示分区信息
- t
:改变分区类型
- n
:创建新的分区
- w
:保存分区
- q
:退出
|
注:分区分好后,如果没有显示分区,需要使用命令使内核重读分区表,partx -a [DEV]
2. mkfs类
命令格式:
用法一:mkfs.fs_type [option] /dev/
用法二:mkfs -t fs_type [option] /dev/
|
3. mke2fs
ext系列的文件系统的专用工具,mke2fs -t [option] {ext2|ext3|ext4}
|
4. mkswap命令:
-
格式
mkswap [option] /dev/
option
-L 'label':指定卷标NOTE:格式化交换分区要先调整分区类型为82(交换分区)
-
启用交换分区:
swapon [option] [device]
option
-a:激活所有分区
-p #:指明优先级,如果有性能好的swap,应该把其优先级提升,如果性能相同的话也可以设置相同优先级,使其负载均衡,
需要注意的是,如果两个swap分区在同一个硬盘样,那负载均衡就没有意义了 -
禁用:
swapoff [option] [device]
5. e2label
ext系列文件系统的专用命令,格式:e2label dev [label]
label:省略为查看,指定为设置
6. tune2fs
重新设定ext系列文件系统可调整参数的值
格式:tune2fs [option] /dev
|
7. dumpe2fs
格式:dump2fs [option] /dev/
-h:查看超级块信息
8. blkid
格式:blkid [option] /dev/
|
9. fsck:文件系统检测命令
用法一:fsck.fs_type [option]
用法二:fsck -t fs_type [option]
|
10. e2fsck:ext系列文件系统专用工具
格式:e2fsck [option] /dev/
|
四、 挂载
1. 挂载的意义
将额外文件系统与根文件系统的某目录建立关联关系,进而使得此目录可作为其它文件访问入口的操作,我们称之为挂载。解除此关系称为卸载
2. 命令
格式:mount [option] [-o option] /dev/ dir
|
3. 配置文件:/etc/fstab的六个字段
- 要挂载的设备或伪文件系统
- 设备文件
- LABEL:
LABEL=""
- UUID:
UUID=""
- 伪文件系统
- 挂载点:如果要挂载,它的挂载点就叫swap
- 文件系统类型
- 挂载选项
- 转储频率:多长时间备份一次
0:表示不做转储
1:每天转储一次
2:每隔一天转储 - 自检次序:系统非法关机后,自检的顺序
0:不自检
1:首先自检,一般只有rootfs才用1
2:1自检完在自检
4. 挂载光盘设备
- 接口
- IDE:/dev/hdc
- SATA:/dev/sr0
- 链接文件:
- /dev/cdrom
- /dev/cdrw
- /dev/dvd
- /dev/dvdrw
5. 卸载
- 命令:umount
- 查看哪个用户正在访问设备:
fuser -v mount_dir
lsof mount_dir
fuser -km mount_dir
:强行T掉正在访问此设备的进程。
五、链接
1. 硬链接
- 文件数据查找其实就是多次查找Inode指向的数据,如果让多个路径都指向同一个Inode,那么就能通过多个路径找到这些数据,并且每次添加一个路径,这个Inode的引用计数就会加1,删除其中的任何一个文件都不会影响数据,因为还有另一个路径可以找到这些数据
- 不能跨分区进行:因为不能保证A分区上引用的B分区是否已经挂载。第二点,应该是因为A、B分区Inode属于自治的,可能会出现重复,所以不能引用
- 不能够对目录使用:因为对目录使用的话,可能会引起循环引用,但是系统中其实是有目录的硬链接的,是目录的自引用,分别是
.
和..
2. 软链接
- 当通过软链接访问数据时,在此软连接的基名对应的Inode条目中,不会指向任何的磁盘块,而是在其中保存源文件的路径,接着在根据这个路径再去寻找源文件。所以,当源文件删除的时候,这个软链接也就失效了。软连接的大小为其指向的路径字符串的字节数,不增加或减少目标文件inode的引用计数
- 可以对目录进行,可以跨分区
3. 命令
格式:ln [option] src_link dest_link
|
4. 特殊文件的元数据
- 链接文件的元数据:存储数据指针的空间当中,存储的是真实文件的访问路径
- 设备文件:存放数据指针的空间当中,存储的是设备的主、次设备号,同样没用占据真正的数据块
六、 空间信息查看命令
1. free命令
查看内存空间的使用情况
格式:free [option]
|
2. df命令
格式:df [option]
|
3. du命令
统计目录占用大小
格式:du [option] [DIR]
|
4. dd命令
格式:dd if=/PATH/FROM/SRC of=/PATH/TO/DEST bs=# conut=#
七、练习:
1. 创建一个10G的分区,并格式化为ext4文件系统
- block大小为2048,预留空间为2%,卷标为MYDATA
[root@node1 ~]# mkfs.ext4 -b 2048 -m 2 -L 'MYDATA' /dev/sdb1
- 挂载至/mydata目录,要求挂载时禁止程序自动运行,且不更新文件的访问时间戳
[root@node1 ~]# mount -o nodiratime,noexec /dev/sdb1 /mydata
[root@node1 ~]# mount
/dev/sdb1 on /mydata type ext4 (rw,noexec,nodiratime,relatime,seclabel,data=ordered) - 可开机自动挂载
[root@node1 ~]# vim /etc/fstab
LABEL="MYDATA" / ext4 defaults,noexec,nodirtime 0 0
2. 创建一个大小为1G的swap分区,并启动
|
3. 创建一个20G的文件系统,块大小为2048,文件系统ext4,卷标为TEST,要求此分区开机后自动挂载至/testing目录,且默认有acl挂载选项
|
4. 创建一个5G的文件系统,卷标HUGE,要求此分区开机自动挂载至/mogdata目录,文件系统类型为ext3
|
5. 写一个脚本
- 列出当前系统识别到的所有磁盘设备
- 如磁盘数量为1,则显示其空间使用信息,否则显示最后一个磁盘上的空间使用信息
|