认识文件系统


磁盘组成与分区的复习


磁盘的组成:

  • 圆形碟片
  • 机械手臂, 磁头(擦写数据)
  • 主轴马达, 转动碟片让磁头在碟片上读写数据

碟片的物理组成:

  • 扇区 : 最小的物理存储单位, 目前主要有512B和4KB两种格式
  • 扇区组成一个圆为柱面
  • 早期分区以柱面为最小分区单位, 目前采用扇区作为最小分区单位.
  • 磁盘分区格式: MBR分区与GPT分区表.
  • MBR分区中, 首扇区较为重要, 有: 主引导记录(Master boot record, MBR)及分区表, 其中MBR占有446B, 分区表占有64B.
  • GPT分区支持的磁盘容量可超过2TB,

物理磁盘文件名: /dev/sda
虚拟机磁盘文件名: /dev/vda
软件磁盘阵列: /dev/mda
LVM时: /dev/VGNAME/LVNAME

文件系统特性


磁盘分区完需要进行格式化, 格式化文件系统的目的是管理文件的操作.

Linux最早的文件系统为ext2文件系统, 现在一个分区可以格式化多个文件系统, 多个分区也可以合并为一个文件系统, 及称呼一个可被挂载的数据为一个文件系统而不是一个分区.

文件系统的管理与超级区块, inode与数据区块这几个概念有关:

  • 超级区块: 记录文件系统的整体信息, 包括inode与数据区块的总量, 使用量, 文件系统格式等相关信息.
  • inode : 记录文件的属性, 一个文件占用一个inode, inode同时记录该文件数据区块的区块号码.
  • 数据区块: 实际记录文件的内容, 文件太大会占用多个区块.

根据inode查询数据区块号码的方法又分为:

  • 索引式文件系统 : 根据inode可以直接查询到所有的数据区块号码. Linux的文件系统基本都是此类.
  • 非索引 : 如U盘的FAT格式文件系统, 该文件系统没有inode, 数据区块的号码存储在上一个数据区块中.

碎片整理: 文件写入的区块过于分散导致文件读写性能较差, 通过碎片整理可以将区块集合到一块提高性能.

Linux的ext2文件系统


ext2文件系统是典型基于inode, 数据区块, 超级区块的系统.

文件系统一开始就将inode与数据区块规划好了, 除非重新格式化, 否则inode与数据区块固定后不在变动.

当文件系统过大时ext2不便于管理, 所以ext2采用了区块群组这个概念. 每个区块群组都有独立的inode, 数据区块, 超级区块系统.

在整体的规划中, 文件系统最前面有一个启动扇区, 启动扇区用于安装启动引导程序. 后面接着就是区块群组, 每个区块群组的主要内容如下:

  • 数据区块, 区块支持1k, 2k, 4k三种大小划分, 不同大小的区块有着相应的限制. | Block大小 | 1k | 2k | 4kB | | —- | —- | —- | —- | | 最大单一文件限制 | 16GB | 256GB | 2TB | | 最大文件系统总容量 | 2TB | 8TB | 16TB |

    • 其它限制
    • 区块的大小与数量格式化后不变
    • 每个区块最多只能放一个文件(这可能会导致单文件区块过多或者区块浪费现象)
  • inode table
    • 文件的读写属性
    • 文件的user与group
    • 文件大小
    • 文件建立或状态改变时间(ctime)
    • 最近一次读取时间(atime)
    • 最新修改时间(mtime)
    • 文件特性的标识如SetUID
    • 文件内容的真正指向
    • inode大小固定为128B(ext4和xfs可以设置到256B和512B)
    • 每个文件仅占用一个inode

ext2的inode采用12个直接, 一个间接, 一个双间接与一个三间接记录文件内容.直接标识inode直接存储数据区块号码, 间接标识采用一个数据区块来记录文件数据区块的号码.(这样, 1k大小的数据区块尽可访问16GB的文件内容)

  • Superblock(超级区块) : 记录整个文件系统的相关信息
    • 数据区块与inode的总量
    • 未使用与已使用的inode与数据区块, 数量
    • 数据区块与inode的大小
    • 文件系统的挂载时间, 最近一次写入数据的时间, 最近一次检验磁盘的时间
    • 有效位数值, 0表示该文件系统已挂载; 1表示未挂载

一般超级区块的大小为1024B. 此外, 每个区块群组都可能含有超级区块, 后面的超级区块只是第一个超级区块的备份.

  • Filesystem Discription(文件系统描述说明) : 描述每个区块群组的开始与结束的区块, 以及说明每个区段分别介于哪一个区块之间.
  • 区块对照表 : 该区块是否为空的标识表
  • inode对照表: inode是否被占用的标识表
  • dumpe2fs : 查询ext系统超级区块信息的命令

与目录树的关系


目录与文件在文件系统中是如何记录数据?

目录
新建目录时, 文件系统会分配一个inode与一块区块给目录. inode记录目录的权限与属性, 区块记录目录下的文件名与文件占用的inode号码.

  1. [root@kuaicdn /]# ll -i
  2. 总用量 20
  3. 152 lrwxrwxrwx. 1 root root 7 3 7 2021 bin -> usr/bin
  4. 96 dr-xr-xr-x. 5 root root 4096 3 7 2021 boot
  5. 17060580 drwx--x--x. 4 root root 44 10 19 16:46 data
  6. 3 drwxr-xr-x 19 root root 3100 10 16 11:49 dev

目录的大小基本为1024的倍数, 因为区块的大小的缘故.

文件
新建文件, ext2系统会分配一个inode和相对于该文件大小的数据区块.

目录树读取
读取/etc/passwd文件的流程如下:

  1. /的inode

通过挂载点的信息找到inode号码对应的根目录inode, 判断rx权限读取内容

  1. /的区块

根据inode获取区块号码并找到etc/的inode

  1. etc/的inode

根据inode找到对应的数据区块, 找到passwd的inode

  1. passwd的inode

读取etc/的inode满足权限后读取passwd的区块内容

  1. passwd的区块

文件系统大小与磁盘读写性能
文件系统太大. 数据太离散导致磁盘性能下降

ext2/ext3/ext4文件的存取与日志式文件系统的功能


新建文件的流程:

  • 确定用户对于文件目录是否具有wx权限, 有则新增.
  • 根据inode对照表找到没有使用的inode号码并将新文件的权限/属性写入
  • 根据区块对照表找到没有使用的区块并将数据内容写入区块并且更新inode的区块执行数据区块
  • 将刚刚写入的inode与区块数据同步更新到inode对照表与区块对照表, 并更新超级区块的内容.

inode与区块称为数据存放区域, 其它超级区块, 对照表称为元数据(经常变动的数据)

数据的不一致状态
新建文件时因为故障导致文件新建中断元数据没有同步更新导致数据不一致状态.

解决:
早期的ext2文件系统在启动时会借超级区块当中记录的有效位(是否有挂载)与文件系统状态(正确卸载与否)等状态来强制进行数据一致性的检查. 不过这样的检查十分低效.

日志式文件系统很好的解决了该问题.

日志式文件系统
规划一个区块专门记录写入或修改文件时的步骤.

新建文件流程更改:

  1. 预备: 系统要新建文件前在日志记录区块中记录新建文件信息
  2. 实际操作 : 新建文件
  3. 结束: 完成数据与元数据的的更新后, 在日志记录区块完成该文件的记录.

ext3和ext4, xfs使用了日志式文件系统.

Linux文件系统的运行


考虑到磁盘写入的速度比内存慢很多, 对文件的频繁写入磁盘的效率将会很低. 为了解决这个问题, Linux采用异步处理(sync)的方式:
当系统加载文件到内存后, 如果该文件没有修改,则在内存区段的文件数据被设置为clean, 文件数据被修改后内存区段的文件数据被设置为dirty, 此时所有的操作都在内存中执行并没有写入磁盘, 系统会不定时地将内存中设置dirty的数据写入磁盘, 以保存磁盘与内存数据的一致性.

将常用的文件放到内存中以提高性能:

  • 系统会将常用的文件数据放置到内存的缓冲区, 以加速文件系统的读写操作.
  • 可以手动使用sync来强制内存中设置为dirty的文件写入磁盘
  • 正常关机系统会主动执行sync
  • 不正常关机, 由于数据尚未写入磁盘, 导致系统系统重启后花时间在进行磁盘校验, 甚至可能导致文件系统的损坏.

挂载点的意义


其它Linux支持的文件系统与VFS


Linux支持的文件系统:

  • 传统文件系统 : ext2, minix, FAT, iso9660
  • 日志式文件系统 : ext3, ext4, ReiserFS, Windows’s NTFS
  • 网络文件系统 : NFS, SMBFS

查看Linux支持的文件系统:

[root@kuaicdn /]# ls -l /lib/modules/$(uname -r)/kernel/fs
总用量 52
drwxr-xr-x. 2 root root    19 3月   7 2021 9p
drwxr-xr-x. 2 root root    21 3月   7 2021 afs
-rwxr--r--. 1 root root 30408 3月   4 2021 binfmt_misc.ko
drwxr-xr-x. 2 root root    22 3月   7 2021 btrfs
drwxr-xr-x. 2 root root    27 3月   7 2021 cachefiles
drwxr-xr-x. 2 root root    21 3月   7 2021 ceph
drwxr-xr-x. 2 root root    21 3月   7 2021 cifs
drwxr-xr-x. 2 root root    23 3月   7 2021 cramfs
drwxr-xr-x. 2 root root    20 3月   7 2021 dlm

系统已加载到内存中支持的文件系统:

[root@kuaicdn /]# cat /proc/filesystems 
nodev    sysfs
nodev    tmpfs
nodev    bdev
nodev    proc
nodev    cgroup
nodev    cgroup2
nodev    cpuset

Linux VFS(Virtual Filesystem Switch)
VFS用于识别文件系统.

image.png

XFS文件系统简介


CentOS7采用xfs文件系统替换ext4文件系统.

ext支持度最广, 但格式化超慢
ext在格式化时分配规划了所有的inode与数据区块, xfs是动态分配inode与数据区块.

xfs文件系统的配置
xfs是一个日志式文件系统, 具有ext4几乎所有的功能.
xfs文件系统在数据的分布上,主要规划为三个部分, 数据区, 文件系统活动登录区以及实时运行区.

数据区:
数据区包括了inode, 数据区块, 超级区块等数据. 该区域也分为多个存储区群组(可以理解为区块群组).
与ext系列不同的是, xfs的区块与inode有多种不同的容量可供设置, 区块容量可在512B与64KB之间浮动, 不过, 由于存储控制的关系(页面文件的pagesize的容量原因), 因此最高可以使用的区块大小为4K而已. 至于inode容量在256B-2MB.

文件系统活动登录区:
用于记录文件系统的变化, 日志区块.

实时运行区:
当有文件建立时, xfs会在这个区段里面找一个到数个的extent区块, 将文件放置在这个区块, 等到分配完毕, 再写入到data section的Inode与区块中. 这个extent的大小要在格式化的时候就指定.

xfs文件系统的描述数据观察:
[ xfs_info ]
语法:

xfs_info 挂载点 | 设备文件名
[root@kuaicdn /]# xfs_info /dev/sda3
meta-data=/dev/sda3              isize=512    agcount=4, agsize=1007488 blks
                                                                    inode大小        存储区群组个数    存储区区块个数
         =                       sectsz=4096  attr=2, projid32bit=1
                                                             扇区大小
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=4029952, imaxpct=25
                                                                    区块大小
         =                       sunit=0      swidth=0 blks
                                                             与磁盘阵列相关
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
                    登录区位置在文件系统内部
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
实时运行区                                                                    extent容量

文件系统的简单操作


介绍如何查询文件系统大小与每个目录占用的容量. 还会介绍一下链接文件.

磁盘与目录的容量


磁盘的容量在超级区块中存储, 目录与文件的容量则在inode当中记载. 查询的适合需要借助两个命令完成:

  • df : 列出文件系统的整体磁盘使用量
  • du : 用于目录的磁盘空间

df
查看目录所挂载的文件系统的容量.
语法:

df [-ahikHTm] 目录或文件名
选项与参数
-a : 列出所有的文件系统
-T : 显示文件系统类型
-i : 不用磁盘容量, 显示inode的数量

示例:

[root@kuaicdn ~]# df
文件系统          1K-块    已用    可用 已用% 挂载点
devtmpfs         458872       0  458872    0% /dev
tmpfs            470208       0  470208    0% /dev/shm
tmpfs            470208    6356  463852    2% /run
tmpfs            470208       0  470208    0% /sys/fs/cgroup
/dev/sda3      16109568 7346668 8762900   46% /
/dev/sda2        517868  120924  396944   24% /boot
/dev/sda1        130798   11422  119376    9% /boot/efi
tmpfs             94044       0   94044    0% /run/user/0
overlay        16109568 7346668 8762900   46% /data/docker-root/overlay2/8e8682292ee5e96af18e535ea06b54f8d25bfc570d2946cfea2363b110595c17/merged

[root@kuaicdn ~]# df -h
# 更容易看
文件系统        容量  已用  可用 已用% 挂载点
devtmpfs        449M     0  449M    0% /dev
tmpfs           460M     0  460M    0% /dev/shm
tmpfs           460M  6.3M  453M    2% /run
tmpfs           460M     0  460M    0% /sys/fs/cgroup

[root@kuaicdn ~]# df -aT
文件系统       类型          1K-块    已用    可用 已用% 挂载点
sysfs          sysfs             0       0       0     - /sys
proc           proc              0       0       0     - /proc
devtmpfs       devtmpfs     458872       0  458872    0% /dev
securityfs     securityfs        0       0       0     - /sys/kernel/security
tmpfs          tmpfs        470208       0  470208    0% /dev/shm
devpts         devpts            0       0       0     - /dev/pts
tmpfs          tmpfs        470208    6356  463852    2% /run
tmpfs          tmpfs        470208       0  470208    0% /sys/fs/cgroup
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/systemd
pstore         pstore            0       0       0     - /sys/fs/pstore
efivarfs       efivarfs          0       0       0     - /sys/firmware/efi/efivars
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/hugetlb
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/memory
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/freezer
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/cpu,cpuacct
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/perf_event
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/rdma
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/blkio
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/devices
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/pids
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/net_cls,net_prio
cgroup         cgroup            0       0       0     - /sys/fs/cgroup/cpuset
configfs       configfs          0       0       0     - /sys/kernel/config

[root@kuaicdn ~]# df -h /etc
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        16G  7.1G  8.4G   46% /

[root@kuaicdn ~]# df -ih
文件系统       Inode 已用(I) 可用(I) 已用(I)% 挂载点
devtmpfs        113K     330    112K       1% /dev
tmpfs           115K       1    115K       1% /dev/shm
tmpfs           115K     437    115K       1% /run
tmpfs           115K      17    115K       1% /sys/fs/cgroup
/dev/sda3       7.7M    227K    7.5M       3% /
/dev/sda2       256K      16    256K       1% /boot
/dev/sda1          0       0       0        - /boot/efi
tmpfs           115K       1    115K       1% /run/user/0
overlay         7.7M    227K    7.5M       3% /data/docker-root/overlay2/8e8682292ee5e96af18e535ea06b54f8d25bfc570d2946cfea2363b110595c17/merged

/proc的内容为Linux加载的系统数据,挂载在内存当中, 不占用磁盘空间.
/dev/shm是利用内存虚拟出来的磁盘空间, 通常是物理内存的一半.

du
语法:

du [-ahskm] 文件或目录名称
选项与参数:
-a : 列出所有的文件与目录容量, 默认仅统计目录下面的文件量
-s : 仅列出总量, 而不列出每个各别的目录占用容量
-S : 今列出目录下的文件总量而不包括目录总量
-m : 以MB单位显示cd

示例:

[root@kuaicdn ~]# du
# 分析当前目录的文件与目录占用的磁盘空间, 但是实际显示只会显示目录容量, 所以综合不等于.的容量.单位为1KB
0    ./.pki/nssdb
0    ./.pki
16    ./.ssh
0    ./.ansible/tmp
0    ./.ansible
4    ./.docker
...
100    .

[root@kuaicdn ~]# du -a
# 显示有文件的列表
4    ./.bash_logout
4    ./.bash_profile
...
8    ./nginx/log
12    ./nginx
8    ./.viminfo
100    .

[root@kuaicdn /]# du -sm /*
0    /bin
104    /boot
5617    /data
0    /dev
37    /etc
0    /home
0    /lib
0    /lib64
0    /media
0    /mnt
30    /mydata
1    /opt
du: 无法访问"/proc/2789/task/2789/fd/3": 没有那个文件或目录
du: 无法访问"/proc/2789/task/2789/fdinfo/3": 没有那个文件或目录
du: 无法访问"/proc/2789/fd/3": 没有那个文件或目录
du: 无法访问"/proc/2789/fdinfo/3": 没有那个文件或目录
0    /proc
1    /root
7    /run
0    /sbin
0    /srv
0    /sys
1    /tmp
2296    /usr
533    /var

硬链接与符号链接: ln


在Linux下面的链接文件有两种, 一种是类似Windows的快捷方式功能的文件; 另一种是通过文件系统的inode链接来产生新文件名,而不是产生新文件, 这种被称为硬链接.

硬链接
首先了解:

  • 每个文件都会占用一个inode, 文件内容由inode的记录来指向,
  • 读取文件必须要经过目录记录的文件名来执行到正确的inode号码才能读取.

硬链接只是在某个目录下新增一条文件名连接到某inode号码的关联记录而已.

[root@kuaicdn tmp]# clear
[root@kuaicdn tmp]# ll -i /etc/crontab
8689599 -rw-r--r--. 1 root root 451 6月  10 2014 /etc/crontab
[root@kuaicdn tmp]# ln /etc/crontab .
[root@kuaicdn tmp]# ll -i /etc/crontab crontab 
8689599 -rw-r--r--. 2 root root 451 6月  10 2014 crontab
8689599 -rw-r--r--. 2 root root 451 6月  10 2014 /etc/crontab

两个文件都指向同一个inode, 文件的inode号码相同, 2表示有多个文件名指向该inode. 将任何一个文件名删除时, inode与区块仍然存在.

硬链接的限制:

  • 不能跨文件系统
  • 不能链接目录

符号链接
符号链接就是建立一个独立的文件, 该文件会让数据的读取指向它链接的文件的文件名. 因此, 源文件删除之后符号链接文件无法打开.

[root@kuaicdn tmp]# ln -s /etc/crontab crontab2
[root@kuaicdn tmp]# ll -i /etc/crontab crontab2
8794477 lrwxrwxrwx  1 root root  12 10月 29 20:21 crontab2 -> /etc/crontab
8689599 -rw-r--r--. 2 root root 451 6月  10 2014 /etc/crontab

建立链接文件的ln命令
语法:

ln [-sf] 源文件 目标文件
选项与参数:
-s : 不加参数为硬链接, 加s为符号链接.
-f : 目标文件存在时删除再创建.

目录的链接数量
新建目录时新的目录的链接数为2, 上层目录的链接数加1

磁盘的分区, 格式化, 检验与挂载


电脑新增磁盘的操作:

  1. 对磁盘进行划分, 以建立可用的硬盘分区
  2. 对硬盘分区进行格式化, 以建立系统可用的文件系统
  3. 可选, 对建立好的文件系统检验
  4. 将文件系统进行挂载

观察磁盘分区状态


对于现有的磁盘分区, 需要观察分区的分区表等信息后才好进行文件系统格式化信息.

lsblk列出系统上的所有磁盘列表
lsblk
语法:

lsblk [-dfimpt] [device]
选项:
-i : ASCII字符输出
-p : 列出该设备的完整文件名
-f : 列出文件系统信息, 包括文件系统类型, LABEL, UUID

示例:

[root@kuaicdn tmp]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   16G  0 disk 
├─sda2   8:2    0  512M  0 part /boot
├─sda3   8:3    0 15.4G  0 part /
└─sda1   8:1    0  128M  0 part /boot/efi

[root@kuaicdn tmp]# lsblk -ip
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
/dev/sda      8:0    0   16G  0 disk 
|-/dev/sda2   8:2    0  512M  0 part /boot
|-/dev/sda3   8:3    0 15.4G  0 part /
`-/dev/sda1   8:1    0  128M  0 part /boot/efi
  • NAME : 设备文件名
  • MAJ:MIN : 内核识别设备的主要与次要设备代码
  • RM : 是否为可卸载设备, 如光盘, USB磁盘等
  • SIZE
  • RO : 只读设备
  • TYPE : 磁盘(disk), 分区(partition), 只读存储器(rom)
  • MOUNTPOINT : 挂载点

blkid列出设备的UUID等参数
UUID : 设备的全局唯一标识符.

[root@kuaicdn tmp]# blkid
/dev/sda1: SEC_TYPE="msdos" UUID="E0F7-209C" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="eada01c9-c9e1-4650-b98d-d7079983d8c2" 
/dev/sda2: UUID="30fec928-14ec-4c64-b829-f754df889eef" TYPE="xfs" PARTUUID="21a8e35a-6bb6-4439-b09a-51fd8aaa0c5a" 
/dev/sda3: UUID="6e615d41-1941-45ef-a398-27d641ebbb74" TYPE="xfs" PARTUUID="135a7598-e654-417a-9f28-09519db0601a"

part列出磁盘的分区表类型以及分区信息

[root@kuaicdn tmp]# parted /dev/sda print
Model: Msft Virtual Disk (scsi)
Disk /dev/sda: 17.2GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name                  标志
 1      1049kB  135MB   134MB   fat16        EFI System Partition  启动
 2      135MB   672MB   537MB   xfs
 3      672MB   17.2GB  16.5GB  xfs

可以看出采用gpt分区

磁盘分区: gdisk/fdisk


接下来进行磁盘分区, MBR分区表采用fdisk命令分区. GPT分区表采用gdisk命令分区.

[ gdisk ]
该命令是交互式命令. 直接按照提示进行下一步即可.
语法:

gdisk 设备名称

特别注意gdisk的q与w命令, q是直接退出进行的操作不生效, w是写入后退出.

p命令输出的分区信息:

Disk /dev/sda: 33554432 sectors, 16.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 3C151259-0F65-455C-874B-4A5DCD8C1C23
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 33554398
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          264191   128.0 MiB   EF00  EFI System Partition
   2          264192         1312767   512.0 MiB   0700  
   3         1312768        33552383   15.4 GiB    0700

gdisk新增分区
具体操作使用n命令后按照提示即可,

新增分区按w退出后查看/proc/partitions文件内容, 发现分区表没有更新, 使用partprobe更新分区.

partprobe更新Linux内核分区表信息

partprobe -s

gdisk删除分区
gdisk + d命令

[ fdisk ]

磁盘格式化


使用mkfs可以进行磁盘的格式化

XFS文件系统mkfs.xfs

mkfs.xfs /dev/sda4

XFS文件系统 for RAID性能优化
基本上, 磁盘阵列就是通过将文件先细分为数个小型的分区区块后, 将众多的stripes分别放到磁盘阵列里面的所有磁盘, 所以一个文件是被同时写入到多个磁盘中.

ext4文件系统mkfs.ext4

文件系统检验


xfs_repair处理XFS文件系统
fsck.ext4处理ext4文件系统

通常只有身为root且文件系统有问题时才使用该命令, 负责在正常情况下可能造成比较大的危害.
在执行xfs_repair与fsck.ext4时, 被检查的硬盘分区务必不可挂载到系统上.

文件系统挂载与卸载


挂载前注意:

  • 单一文件系统不应该被重复挂载在不同的挂载点中
  • 单一目录不应该重复挂载多个文件系统
  • 作为挂载点的目录理论都是空目录.

目录不为空时, 挂在了文件系统之后原来目录下的东西会暂时的消失.
挂载命令: mount

mount命令不需要加上-t选项指定文件类型, 系统会自动分析最合适的文件系统类型, Linux会通过分析超级区块搭配Linux的驱动程序去测试挂载.测试参考的文件:

  • /etc/filesystems : 系统指定的测试挂载文件系统类型的优先级
  • /proc/filesystems : Linux系统已经加载的文件系统类型

获取Linux已存在的文件系统类型的驱动程序:

  • /lib/modules/$(uname -r)/kernel/fs/driver

挂载时建议使用UUID来识别文件系统, UUID独一无二.

挂载xfs/ext4/vfat文件系统:

blkid /dev/vda4
mount UUID="" /data/xfs
mkdir -p /data/xfs
df /data/xfs
blkid /dev/vda5
mkdir -p /data/ext4
mount UUID="" /data/ext4
df /data/ext4

挂载CD/DVD光盘:

blkid
mkdir /data/cdrom
mount /dev/sr0 /data/cdrom
df /data/cdrom

光驱一挂载就无法退出光盘, 除非将其卸载之后才能够退出.

挂载vfat中文移动磁盘(USB磁盘):

blkid
mkdir /data/sub
mount -o codepage=950,iocharset=utf8 UUID="" /data/sub
mount -o codepage=950,iocharset=big5 UUID="" /data/sub
df /data/sub

codepage选项指定挂载使用的语系.
当USB磁盘被格式化为NTFS时, 因为CentOS7默认不支持NTFS文件系统, 需要安装NTFS文件系统的驱动程序才可以处理.

重新挂载根目录与挂载不特定目录:
根目录无法卸载
第一种情况是挂载参数需要改变或者根目录处于只读状态, 处理方式如下:

mount -o remount,rw,auto /

第二种情况是文件系统需要额外挂载某个目录, 处理方式有两种, 第一种采用符号链接做链接, 第二种是通过以下方式处理:

将/var目录暂时挂载到/data/var目录下
mkdir -p /data/var
mount --bind /var/ data/var
ls -lid /var /data/var
mount | grep var

设备卸载命令: umount

umount [-fn] 设备文件名或挂载
选项与参数:
-f : 强制卸载, 可用在类似网络文件系统无法读取的情况下
-l : 立刻卸载文件系统, 优先级比-f高
-n : 不更新/etc/mtab的情况下载
mount
umount /dev/vda4
umount /data/ext4
umount /data/cdrom
umount /data/usb
umount /data/var #一定要用挂载点, 因为设备有被其它方式挂载

注意离开文件系统的挂载点再进行卸载

磁盘/文件系统参数自定义


修改当前文件系统参数需要以下命令.

[ mknod ]
Linux中文件如何代表设备? 通过文件的major与minor数值来替代.

[root@kuaicdn ~]# ll /dev/sda*
brw-rw---- 1 root disk 8, 0 10月 29 20:44 /dev/sda
brw-rw---- 1 root disk 8, 1 10月 29 20:44 /dev/sda1
brw-rw---- 1 root disk 8, 2 10月 29 20:44 /dev/sda2
brw-rw---- 1 root disk 8, 3 10月 29 20:44 /dev/sda3

其中, 8为设备主要代码(major), 0-3为次要设备代码(minor).

Linux内核2.6之后硬件文件名可自动实时产生, 不需要手动建立设备.不过在某些特定情况下需要手动处理设备文件, 如服务被chroot到特定目录下.

chroot 是更改当前运行进程及其子进程的明显根目录的操作。 在这种修改过的环境中运行的程序无法访问该环境目录树之外的文件和命令。 这个修改后的环境称为 chroot jail。

mknod 设备文件名 [bcp] [Major] [Minor]
选项与参数:
设备种类:
    b : 设置设备名称为一个外接存储设备文件, 如磁盘等.
    p : 设置设备名称为一个FIFO文件

mknod /dev/vda10 b 252 10
ll /dev/vda10
mknod /tmp/testpipe p
ll /tmp/testpipe

xfs_admin修改XFS文件系统的UUID与Label name
注意在挂载前修改, 负责需要卸载后才能更改.

xfs_admin [-lu] [-L label] [-U uuid] 设备文件名
选项与参数:
-L : 设置这个设备的Label name
-l : 列出这个设备的label name
-u : 列出该设备的uuid
-U : 设置该设备的UUID

xfs_admin -L vbird_xfs /dev/vda4
xfs_admin -l /dev/vda4
mount Label=vbird_xfs /data/xfs
# 利用uuidgen产生新uuid来设置/dev/vda4, 并测试挂载
umount /dev/vda4
uuidgen #产生新的UUID
xfs_admin -u /dev/vda4
xfs_admin -U "" /dev/vda4
mount UUID="" /data/xfs

使用UUID来挂载的关键, 因为你没有办法设置在所有的Linux系统中, 文件名一定都会是/dev/vda

tune2fs修改ext4的label name与uuid

tune2fs [-l] [-L Label] [-U uuid] 设备文件名
选项与参数:

dumpe2fs -h /dev/vda5 | grep name
tune2fs -L vbird_ext4 /dev/vda5
dumpe2fs -h /dev/vda5 | grep name
mount LABEL=vbird_ext4 /data/ext4

设置启动挂载[ 重点 ]


系统在启动时自动挂载文件系统.

启动挂载/etc/fstab及/etc/mtab


/etc/fstab : 系统在启动前会查询该文件内容进行自动挂载.
/etc/mtab : 实际文件系统的挂载.

挂载前需知:

  • 根目录必须挂载, 而且一定要先于其他挂载点被挂载进来.
  • 挂载点架构需遵循FHS
  • 卸载时保证工作目录不在挂载点内

查看/etc/fstab的内容:

[root@kuaicdn ~]# cat /etc/fstab
# Devcie        Mount point    filesystem    parameters    dump     fsck
UUID=6e615d41-1941-45ef-a398-27d641ebbb74 /                       xfs     defaults        0 0
UUID=30fec928-14ec-4c64-b829-f754df889eef /boot                   xfs     defaults        0 0
UUID=E0F7-209C          /boot/efi               vfat    umask=0077,shortname=winnt 0 0
/srv/loopdev        /data/file         xfs    defaults,loop        0 0

字段介绍:

  • 设备名/UUID/LABEL NAME
    • 设备名如/dev/sda
    • UUID名称如UUID=””
    • LABEL名称如LABEL=xxx
  • 挂载点
  • 文件系统类型
  • 文件系统参数 | 参数 | 内容意义 | | —- | —- | | async/sync | 设置磁盘是否以异步方式运行,默认为async | | auto/noauto | 执行mount -a时, 文件系统是否主动测试挂载, 默认为auto | | rw/ro | 文件系统只读/读写 | | exec/noexec | 文件系统是否可执行 | | user/nouser
    允许, 不允许一般用户挂载 | 默认为nouser | | suid/nosuid
    具有/不具有suid权限 | | | defaults | rw,suid, dev,exec,auto,nouser,async参数的集合 |
  • 能否被dump备份命令作用: 0即可
  • 是否以fsck检验扇区 : 0

/etc/fstab是启动时的配置文件, 实际文件系统的挂载是记录到/etc/mtab与/proc/mounts这两个文件中.
/etc/fstab输入的数据错误导致无法顺利启动进入单人维护模式, 只读下无法修改/etc/fstab的解决方案:



特殊设备loop挂载(镜像文件不刻录就挂载使用)


可以使用文件作为磁盘, 可以将光盘镜像文件挂载.

挂载CD/DVD镜像文件
通过loop设置直接挂载镜像文件:

ll -h xxx.iso
mkdir /data/centos_dvd
mount -o loop xxx.iso /data/centos_dvd
df /data/centos_dvd
ll /data/centos_dvd
umount /data/centos_dvd

所以镜像文件内容可以被修改, 需要使用MD5码进行验证.

建立大文件以制作loop设备文件
当系统磁盘没有剩余容量时, 可以建立大文件用于格式化挂载测试.

建立大型文件:

dd if=/dev/zero of=/srv/loopdev bs=1M count=512
ll -h /srv/loopdev

大型文件的格式化:
默认xfs不能格式化文件, 需要加上特殊的参数

mkfs.xfs -f /srv/loopdev
blkid /srv/loopdev

挂载:

mount -o loop UUID=xxx /mnt
df /mnt

Linux主机可以建立虚拟机, Linux使用Xen软件与loop device的文件类型来进行根目录的挂载, 非常有用,

自动挂载:

nano /etc/fstab
# /srv/loopdev /data/file defaults,loop 0 0
umount /mnt
mkdir -p /data/file
mount -a
df /data/file

内存交换分区之创建


内存不足时将内存中的数据拿到硬盘中暂时存放的内存交换分区.

建立内存交换分区的方式:

  • 设置一个内存交换分区
  • 建立一个虚拟内存的文件

使用物理分区创建内存交换分区


  1. 分区: 使用gdisk在磁盘中划分一个分区给系统作为内存交换分区, 需要设置system ID为8200
  2. 格式化: mkswap设备文件名
  3. 使用: swapon 设备文件名
  4. 观察: free与swapon -s观察内存的使用量.
gdisk /dev/vda
partprobe
lsblk
mkswap /dev/vda6
blkid /dev/vda6
free
swapon -s
cat /etc/fstab
# UUID=xxx    swap     swap defaults 0 0

使用文件创建内存交换分区


  1. 使用dd在/tmp下面建立一个128M的文件

    dd if=/dev/zero of=/tmp/swap bs=1M count=128
    ll -h /tmp/swap
    
  2. 使用mkswap将/tmp/swap文件格式化内存交换文件格式

    mkswap /tmp/swap
    
  3. 使用swapon来讲/tmp/swap启动

    swapon /tmp/swap
    swapon -s
    
  4. 使用swapoff关闭swap file, 并设置自动启动

    nano /etc/fstab
    # /tmp/swap swap swap defaults 0 0
    # 不舍用UUID. 系统金辉查询区块设备不会查询文件.
    swapoff /tmp/swap
    swapon -s
    swapon -a
    swapon -s
    

文件系统的特殊观察与操作

磁盘空间之浪费问题


磁盘在格式化文件系统时, 超级区块, 区块对照表等数据都会浪费磁盘容量.

来看一个小文件导致大量磁盘容量浪费的例子:

[root@kuaicdn tmp]# ll -sh
总用量 129M
4.0K -rw-r--r--  1 root root    8 10月 16 16:33 1.txt
4.0K -rw-r--r--  2 root root    4 10月 25 15:34 2.txt
   0 drwxr-xr-x  3 root root   17 10月 16 14:46 asserts
 36K -rw-r--r--  1 root root  36K 10月 25 16:17 CentOS7_init_passwd
4.0K -r--r-----  1 root root 2.5K 7月   1 14:59 Centos-7.repo
4.0K -rw-r--r--. 2 root root  451 6月  10 2014 crontab
   0 lrwxrwxrwx  1 root root   12 10月 29 20:21 crontab2 -> /etc/crontab
4.0K -rw-r--r--  2 root root    4 10月 25 15:34 hard_link
332K -rw-r--r--  1 root root 331K 10月 25 16:39 lsof.rpm
   0 lrwxrwxrwx  1 root root    5 10月 25 15:35 soft_link -> 2.txt
   0 drwxr-xr-x  3 root root   21 10月 16 16:03 src
128M -rw-r--r--  1 root root 128M 10月 30 15:11 swap
   0 drwx------  3 root root   17 10月 29 17:22 systemd-private-45272bdc843f49c6906df3a1fa32f919-chronyd.service-o9HYZe
   0 drwx------  3 root root   17 10月 29 17:22 systemd-private-45272bdc843f49c6906df3a1fa32f919-httpd.service-PYaxre
   0 drwx------  3 root root   17 10月 29 17:22 systemd-private-45272bdc843f49c6906df3a1fa32f919-mariadb.service-iyucGt
   0 drwx------  3 root root   17 10月  8 15:27 systemd-private-8b82fbffac4d42dd9f509668146dac45-chronyd.service-shTbqW
   0 drwx------  3 root root   17 10月  8 15:27 systemd-private-8b82fbffac4d42dd9f509668146dac45-httpd.service-DgaBjZ
   0 drwx------  3 root root   17 10月  8 15:27 systemd-private-8b82fbffac4d42dd9f509668146dac45-mariadb.service-le6B2h
   0 drwx------  3 root root   17 10月  9 11:52 systemd-private-8c281668171e4b4fa9e5c3365ea61206-chronyd.service-jpjYpC
   0 drwx------  3 root root   17 10月  9 11:52 systemd-private-8c281668171e4b4fa9e5c3365ea61206-httpd.service-jb2PcZ
   0 drwx------  3 root root   17 10月  9 11:52 systemd-private-8c281668171e4b4fa9e5c3365ea61206-mariadb.service-0GcXtF
   0 drwxr-xr-x  3 root root   21 10月 16 14:48 target
   0 drwxr-xr-x  3 root root   18 10月 29 20:04 test

可以看到, 容量很小的文件也占用了4KB的容量大小(数据区块最小为4K)

利用GNU的parted进行分区操作


parted的好处就是兼容gpt与mbr分区, 在一条命令行上可以完成磁盘的分区

parted [设备] [命令 [参数] ]
选项与参数:
    新增分区: mkpart [primary|logical|Extended] [ext4|vfat|xfs] 开始 结束
  显示分区: print
  删除分区: rm [partition]

磁盘分区格式的修改会损坏分区, 不要乱进行操作.

parted /dev/sda mklabel gpt

建立分区:

parted /dev/vda print
parted /dev/vda mkpart primary fat32 36.0GB 36.5GB
partprobe
lsblk /dev/vda7
mkfs -t vfat /dev/vda7
blkid /dev/vda7
nano /etc/fstab
mkdir /data/win
mount -a
df /data/win

重点


  • 一个可以被挂载的数据通常被称为[文件系统]而不是硬盘分区.
  • 基本上Linux的传统文件系统为ext2, 该文件系统内的信息主要有:
    • 超级区块 : 记录此文件系统的整体信息, 包括inode/区块的总量, 使用量, 剩余量, 以及文件系统的格式与相关信息等.
    • inode : 记录文件的属性. 一个文件占用一个inode, 同时记录此文件的数据所在的区块号码
    • 数据区块 : 实际记录文件的内容, 若文件太大会占用多个数据区块.
  • ext2文件系统的数据存取为索引式文件系统
  • 需要碎片整理的原因就是文件写入的数据区块太过离散, 此时文件读取的性能会变得很差, 可以通过碎片整理将一个文件所属的区块集合在一起.
  • ext2文件系统主要有: 引导扇区, 超级区块, inode对照表, 区块对照表, inode表, 数据区块等六大部分.
  • 数据区块是用来放置文件内容数据的地方, 在ext2文件系统内所支持的区块大小有1K, 2K, 4K三种.
  • inode记录文件的属性/权限等数据, 其它重要特性为: 每个indoe大小均固定, 有128/256字节两种基本容量. 每个文件仅会占用一个inode而已, 因此文件系统能够建立的文件数量与inode的数量有关.
  • 文件的数据区块在记录文件的实际数据, 目录的数据区块则在记录该目录下面文件名与其inode号码的对照表.
  • 日志式文件系统会多出一块记录区, 随机记载文件系统的主要活动, 可加快系统恢复时间
  • Linux文件系统为增加性能, 会让内存作为磁盘高速缓存
  • 硬链接就是多了一个文件名对该inode号码的链接而已.
  • 符号链接类似Windows的快捷方式
  • 磁盘的使用必需经过: 分区, 格式化与挂载, 分别常用的命令为: gdisk, mkfs, mount3个命令.
  • 启动自动挂载可参考/etc/fstab设置, 设置完毕需要使用mount -a测试语法是否正确.