第七章 Linux磁盘与文件系统管理
7.1 Linux文件系统
7.1.1 磁盘组成与分区
文件系统建立在磁盘上
整块磁盘的组成主要有:
(1)圆形的碟片,主要记录数据的部分
(2)机械手臂,与在机械手臂上的磁头,可擦写碟片上的数据
(3)主轴马达,可以转动碟片,让机械手臂上的磁头在碟片上读写数据
数据存储于读取的重点在碟片,碟片的物理组成:
(1)扇区,是最小的物理存储单位,目前有512B和4KB两种格式
(2)将扇区组成一个圆,就是柱面
(3)最小分区单位,早期是柱面,现在是扇区,每个扇区有号码,像自己的 座位号一样
(4)磁盘分区表,主要有两种格式,一种是限制较多的MBR分区表,一种是较新且限制较少的GPT分区表
(5)MBR分区表中,第一个扇区最重要,里面有:主引导记录MBR(446B)和分区表(64B)
(6)GPT分区表,除了分区数量扩充较多之外,支持的磁盘容量也可以超过2T
物理磁盘的文件名:/dev/sd[a-p]
虚拟磁盘的文件名:/dev/vd[a-p]
/dev/sd[a-p][1-128]
-----是物理磁盘的文件名
/dev/vd[a-p][1-128]
-----是虚拟磁盘的文件名
7.1.2 文件系统特性
格式化:
磁盘分区完毕,需要进行格式化,之后操作系统才能使用这个文件系统。
每种操作系统设置的文件属性/权限不同,为了存放这些文件所需的数据,需要将分区进行格式化,以成为操作系统能使用的文件系统格式。
每种操作系统能够使用的文件系统并不相同。
一个可被挂载的数据,就是一个文件系统,而非一个分区。
文件系统通常将权限与属性放置到inode中,至于实际数据则放置到数据区块中。
(1)超级区块:记录此文件系统的整体信息,包括inode与数据区块的总量、使用量、剩余量,以及文件系统的格式与相关信息等
(2)inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的区块号码
(3)数据区块:实际记录文件的内容,若文件太大,会占多个区块
碎片整理:
需要碎片整理的原因就是文件写入的区块太过于离散,此时文件读取的性能将会变得很差所致。这时候可以通过碎片整理将同一个文件所属的区块集合在一起,这样数据的读取比较容易。
索引式文件系统如ext2
不怎么需要碎片整理,但像U盘等FAT
格式的文件系统需要是不是整理下碎片。
7.1.3 Linux的ext2文件系统(inode)
文件系统中,inode的内容在记录文件的权限与相关属性,数据区块在记录文件的实际内容。
文件系统一开始就将inode与数据区块规划好了,除非重新格式化,或者利用resize2fs
等命令修改其大小,否则inode和数据区块固定好后就不再动了。
ext2
文件系统格式化的时候基本上是区分为多个区块群组,每个区块群组都有独立的inode、数据区块、超级区块系统。一群一群的管理。
文件系统最前面有一个启动扇区,这个启动扇区可以安装启动引导程序。这样就能够将不同的启动引导程序安装到别的文件系统最前端,而不用覆盖一整块磁盘唯一的MBR
,这样才能制作出多重引导的环境。
每一个区块群组的六个主要内容:
(1)数据区块
- ext2中支持的区块大小:1K、2K、4K。格式化时区块的大小确定下来。
- 每个区块都有编号,方便inode记录。
- 区块大小差异,会导致该文件系统能够支持的最大磁盘容量和最大单一文件容量并不相同。
- 每个区块内最多只能够放置一个文件的数据,文件过大就占多个区块,文件过小,那么单一区块中剩下的磁盘空间浪费
(2)inode table (inode表)
inode记录的内容:
- 该文件的读写属性(rwx)
- 该文件的拥有者与用户组(owner、group)
- 该文件的大小
- 该文件建立或状态改变的时间(ctime)
- 最近一次的读取时间(atime)
- 最近修改的时间(mtime)
- 定义文件特性的表示(flag),如SetUID
- 该文件真正内容的指向(pointer)
inode的特点:
- 每个inode大小固定为128B,新的ext4和xfs可设置为256B
- 每个文件仅会占用一个inode
- 承上,
- 文件系统能够建立的文件数量与inode数量有关
- 系统读取文件时,要先找到inode,分析inode所记录的权限与用户是否符合,若符合才能够读取区块的内容
(3)超级区块 Superblock
记录整个文件系统相关信息的地方,没有超级区块就没有文件系统,其记录的主要信息:
- 数据区块与inode的总量
- 未使用与已使用的inode与数据区块数量
- 数据区块与inode的大小(block为1k、2k、4k,inode为128B或256B)
- 文件系统的挂载时间、最近一次写入数据的时间、最近一次检验磁盘的时间等文件系统的相关信息;
- 一个有效位数值,若此文件系统已被挂载,则有效位为0,若未被挂载,有效位为1
其他信息:
- 超级区块的大小一般为1024B。
- 每个文件系统仅有一个超级区块,但是每个区块群组都可能含有超级区块,主要是作为第一个区块群组内超级区块的备份,方便后面快速恢复。
- 能用
dumpe2fs
来观察
(4)文件系统描述说明 Filesystem Description
这个区段,可以:
- 描述每个区块群组的开始与结束的区块
- 说明每个区段(超级区块、对照表、inode对照表、数据区块)分别介于哪一个区块之间
- 这部分也能用
dumpe2fs
来观察
(5)区块对照表 block bitmap
- 记录使用和未使用的区块,便于选择空块记录新文件的数据
- 删除文件时,要将该区块号码的标志修改成【未使用中】
(6)inode对照表 inode bitmap
记录使用和未使用的inode
(7)dumpe2fs 查询ext系列超级区块信息的命令
xfs文件系统暂时无法使用该命令查询
dumpe2fs [-bh] 设备文件名
-h 仅列出superblock数据,不列出其他区段内容
blkid 可以显示出当前系统被格式化的设备
7.1.4 与目录树的关系
ls -li 观察目录内的文件所占的inode号码
7.1.5 ext2/ext3/ext4文件存取 与 日志式文件系统的功能
ext2/ext3/ext4文件存取 :
(1)先看目录属性,是否具备w和x,具备才有可能新增;
(2)根据inode对照表找到没有使用的inode号码,将新文件的权限属性写入inode;
(3)根据区块对照表找到没有使用的区块,将文件内容写入,并更新inode的区块指向数据;
(4)更新inode对照表和区块对照表,并更新超级区块内容。
日志式文件系统:
为了记录和查找数据不一致状态,使用日志文件系统。
1(预备)当要写入一个文件时,先在日志记录区块中记录某文件准备写入的信息;
2(实际写入)开始写入文件的权限和数据;开始更新metadata的数据;
3(结束)完成数据与metadata更新后,在日志记录记录区块中完成该文件的记录。
7.1.6 Linux文件系统的运行
系统将一个文件加载到内存中,如果这个文件未被修改过,标记为clean,如果修改了,标记为dirty。系统会不定时地将dirty文件写回磁盘中。
调用sync
能强制系统将dirty文件写回磁盘。
正常关机会自动调用sync
保存文件。
突然断电、宕机等异常关机,可能导致文件系统损坏(磁盘没坏)。
7.1.7 挂载点的意义
每个文件系统都有独立的inode、区块、超级区块等信息。
这个文件系统要能够连接到目录树才能被使用。
挂载点:/ 和 /boot 和 /home
。
xfs文件系统最顶层的目录inode一般是128号。
根目录下的.
和..
与根目录是相同的东西。
7.1.8 其他Linux支持的文件系统与VFS
ls -l /lib/modules/$(uname -r)/kernel/fs 查看你的Linux支持的文件系统种类
cat /proc/filesystems 查看系统当前已加载到内存中支持的文件系统
整个Linux识别的文件系统其实都是VFS在进行管理,VFS是内核的一个功能,虚拟文件系统选择。
7.1.9 XFS文件系统简介
取代ext4,成为新宠,不在于性能多优秀,而在于文件系统的恢复速度和创建速度快,格式化比ext系列快。
xfs文件系统,在数据分布上,分为3块,数据区,文件系统活动登录区,实时运行区。
xfs的inode和区块,是动态产生的,并非一开始就格式化完成配置的,所以格式化操作贼快。
xfs_info 挂载点 | 设备文件名
xfs_info /dev/vda2 观察这个文件系统
df -T /boot 找出/boot这个挂载点下的文件系统的超级区块记录
7.2 文件系统的简单操作
7.2.1 磁盘与目录的容量
df 列出文件系统的整体磁盘使用量
df [-ahikHTm] [目录或文件名]
-a 列出所有文件系统
-k 以kb容量显示各文件系统
-m 以mb容量显示各文件系统
-h 以容易阅读的GB、Mb、Kb格式自行显示
-i 不用磁盘容量,而以inode数量来显示
df
df -h
df -h /etc 会显示这个目录或文件所在磁盘分区的容量
du 查看文件系统的磁盘使用量(常用在查看目录所占磁盘空间)
du [-ahskm] 文件或目录名称
-s 仅列出总量,而不列出每个类别的目录占用容量(含子目录容量)
/proc是活在内存中的挂载点,所以不占用硬盘容量。
7.2.2 硬链接与符号链接 ln
ln 已有文件 新文件 建立已有文件与新文件的硬链接
硬链接一般来说不会增加新的开销,磁盘空间与inode数目不会改变,就是在新文件所在目录的区块中多写入一个指向实际inode节点的inode编号。
删除一个,另一个还在,还能找回数据。
硬链接 不能跨文件系统、不能链接目录。
ln -s 已有文件 新文件 建立软链接
建立一个新的文件,快捷方式,会占用inode和区块。
ln [-sf] 源文件 目标文件
-s 如果不加任何参数就是硬链接;加-s就是符号链接
-f 如果目标文件存在时,就主动将目标文件删除后再建立
7.3 磁盘的分区、格式化、检验与挂载
磁盘管理,新增一块磁盘,需要做的所有事情。
7.3.1 观察磁盘分区的状态
lsblk [-dfimpt] [device]
-i 使用ASCII的字符输出
-p 列出该设备的完整文件名,而不要去掉前导目录
lsblk 列出本系统下所有磁盘信息,与磁盘内的分区信息
blkid 可以列出设备的UUID等参数,UUID是全局唯一标识符
parted device_name print
parted /dev/vda print 列出/dev/vda磁盘的相关信息
7.3.2 磁盘分区
MBR分区表使用fdisk分区,GPT分区表使用gdisk分区。
新增分区:
gdisk /dev/sda 进入磁盘分区的操作区
?
n
p
w
更新内核:
改变分区后,并不会立刻更新内核,可以重启生效,但也可以输入:
partprobe [-s] 更新Linux内核的分区表信息
查看当前分区
lsblk /dev/sda
或者:
cat /proc/partitions 查看内核的分区记录
删除分区:
gdisk /dev/sda
d
千万不能删除正在使用中的分区,可以先卸载,再删除,否则内核很奇怪。
7.3.3 磁盘格式化
xfs:
mkfs.xfs 设备名称 以默认参数格式化
mkfs.xfs /dev/sda4 格式化成xfs文件系统
partprobe -s 更新内核中的分区信息
blkid /dev/sda4 查看这个文件系统
grep 'processor' /proc/cpuinfo 查看当前到底有多少个CPU可以用
ext4:
mkfs.ext4 [-b size][-L label] 设备名称
mkfs.ext4 /dev/sda5
dumpe2fs -h /dev/sda5
7.3.4 文件系统检验
xfs:
xfs_repair [-fnd] 设备名称
-f 后面的设备其实是个文件而不是实体设备
-n 单纯检查并不修改文件系统中的任何数据
-d 通常用在单人维护模式下面,针对根目录进行检查与修复的操作,很危险!不要随便用
xfs_repair /dev/sda4 检查一下刚刚建立的文件系统
xfs_repair /dev/centos/home 检查一下某个原本就有的文件系统,会出错,可卸载后再处理
Linux中,根目录无法被卸载。
如果根目录有问题,进入单人维护或恢复模式,通过-d选项来处理。
ext4:
fsck.ext4 [-pf] [-b 超级区块] 设备名称
dumpe2fs -h /dev/sda5 | grep 'Blocks per group' 找出/dev/sda5的另一块超级区块
fsck.ext4 -b 32768 /dev/sda5 以这块超级区块为准,检查/dev/sda5文件系统
fsck.ext4 /dev/sda5 若文件系统正常,不进入强制检查,会告诉你系统没问题
fsck.ext4 -f /dev/sda5 强制检查/dev/sda5
所有这些被检查的硬盘分区务必不可挂载到系统上,必须得在卸载状态才能检查
7.3.5 文件系统挂载与卸载
mount -a
mount [-l]
mount [-t 文件系统] LABEL='' 挂载点
mount [-t 文件系统] UUID='' 挂载点 推荐的方式!!!
mount [-t 文件系统] 设备文件名 挂载点
将/dev/sda4 挂载到/data/xfs:
blkid /dev/sda4 查看/dev/sda4的UUID
mkdir -p /data/xfs 建立挂载点目录,-p递归创建子文件夹
mount UUID="da4c0459-2ef4-4f2a-baa9-0331955768fd" /data/xfs
df /data/xfs
出现:
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/sda4 1038336 32992 1005344 4% /data/xfs
将/dev/sda5 挂载到/data/ext4:
blkid /dev/sda5
mkdir /data/ext4
mount UUID="94014304-4331-45cb-ac94-e567008e720e" /data/ext4
df /data/ext4
出现:
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/sda5 999320 2564 927944 1% /data/ext4
重新挂载根目录:
mount -o remount,rw,auto /
在符号链接不能使用的时候,可以使用额外挂载某个目录的方法:
mkdir /data/var 新建挂载点
mount --bind /var /data/var 将/var挂载到/data/var
ls -lid /var /data/var 显示两个目录
69 drwxr-xr-x. 20 root root 282 4月 29 21:44 /data/var
69 drwxr-xr-x. 20 root root 282 4月 29 21:44 /var
内容完全一样,因为本来就是挂载目录
umount [-fn] 设备文件名或挂载点
-f 强制卸载
-l 立刻卸载文件系统,比-f还强
-n 不更新/etc/mtab情况下卸载
需要离开该文件系统的挂载点,才能卸载这个挂载点,否则,系统认为你正在使用这个文件系统。
7.3.6 磁盘/文件系统参数自定义
Linux上的设备也用文件来表示,用文件代表设备,通过文件的主要设备代码major、次要设备代码minor数值来替代。
mknod 设备文件名 [bcp] [Major] [Minor]
b 设置设备名称成为一个外接存储设备文件,如磁盘等
c 设置设备名称成为一个外接输入设备文件,如键盘鼠标等
p 设置设备名称成为一个FIFO文件
创建一个磁盘:
ll /dev/sda* 查看/dev/sda的major和minor 分别为8和1-5
mknod /dev/sda10 b 8 10 创建一个磁盘10
ll /dev/sda10
rm /dev/sda10 测试完就删了吧
创建一个FIFO:
mknod /tmp/testpipe p
ll /tmp/testpipe
rm /tmp/testpipe 测试完就删了吧
xfs_admin [-lu] [-L label] [-U uuid] 文件设备名
-l 列出这个设备的label name;
-u 列出这个设备的UUID
-L 设置这个设备的Label name
-U 设置这个设备的UUID
xfs_admin -L vbird_xfs /dev/sda4 设置/dev/sda4的Label name
xfs_admin -l /dev/sda4 查看/dev/sda4的Label name
利用Label name挂载:
mount LABEL=vbird_xfs /data/xfs 通过Label name进行挂载
umount /dev/sda4 卸载备用
利用UUID挂载:
uuidgen 可以产生新的UUID:
b9297c33-1376-4eab-8d25-98196d01c822
xfs_admin -u /dev/sda4 显示/dev/sda4的UUID
UUID = da4c0459-2ef4-4f2a-baa9-0331955768fd
xfs_admin -U b9297c33-1376-4eab-8d25-98196d01c822 /dev/sda4 设置UUID
mount UUID=b9297c33-1376-4eab-8d25-98196d01c822 /data/xfs 挂载
ext4:
tune2fs [-l] [-L Label] [-U uuid] 设备文件名
-l 类似 dumpe2fs -h 的功能,将superblock中的数据读出来
-L 修改Label name
-U 修改UUID
dumpe2fs -h /dev/sda5 | grep name 查看Label name
tune2fs -L vbird_ext4 /dev/sda5 设置Label name
mount LABEL=vbird_ext4 /data/ext4 注意此处LABEL全大写
7.4 设置启动挂载
7.4.1 启动挂载/etc/fstab 及 /etc/mtab
cat /etc/fstab 查看文件内容,显示的字段如下:非常重要
[设备/UUID/LABEL] [挂载点] [文件系统] [文件系统参数] [dump] [fsck]
设置每次启动都将/dev/sda4 自动挂载到/data/xfs:
先查看/dev/sda4的UUID:
blkid /dev/sda4
或
xfs_admin -u /dev/sda4
得到:
UUID = b9297c33-1376-4eab-8d25-98196d01c822
nano /etc/fstab 打开文件,并写入下面一行内容
UUID="b9297c33-1376-4eab-8d25-98196d01c822" /data/xfs xfs defaults 0 0
这里务必要注意,等号两端一定不能出现多余空格,也不能缺少引号
在linux中,nano的保存源和退出: 如果你要保存所做的修改,按下Ctrl+O。
想要退出,按下Ctrl+X。
df 检查/dev/sda4是否已经挂载
umount /dev/sda4 如果已经被挂载,那么赶紧卸载
测试一下刚刚写入/etc/fstab的语法有没有错误,这一点很重要!!!错了可能无法开机,务必要测试!!!
mount -a 这里不能报错,什么都不输出才行
df /data/xfs 这里挂载点要存在
万一不幸出错:
mount -n -o remount,rw /
7.4.2 特殊设备loop挂载(镜像文件不刻录就挂载使用)
挂载镜像文件:
mkdir /data/centos_dvd
mount -o loop /tmp/CentOS.iso /data/centos_dvd 挂载镜像文件
df /data/centos_dvd
ll /data/centos_dvd
umount /data/centos_dvd
建立大文件并格式化后挂载:
dd if=/dev/zero of=/srv/loopdev bs=1M count=512 在/srv/loopdev建立了一个空文件
mkfs.xfs -f /srv/loopdev 格式化文件,必须-f
blkid /srv/loopdev 查看是否成功了
mount -o loop UUID="35d45a93-315a-444e-9337-285c0f7bac02" /mnt 暂时性挂载
永久挂载:
mkdir /data/file 新建一个目录作为挂载点
cat /etc/fstab 将启动挂载命令写入文件
/srv/loopdev /data/file xfs defaults,loop 0 0
umount /mnt
mount -a 查验命令是否有效
df /data/file
7.5 内存交换分区swap的创建
swap分区:
以前内存很小,就将内存中的暂时不用的数据拿到硬盘中暂时存放,这块存放内存中数据的硬盘空间就是swap内存交换分区。
安装系统时,一定需要的两个硬盘分区:一个是根目录,一个是swap分区。
swap只有在物理内存不足的时候才会被使用到。
7.5.1 使用物理分区创建内存交换分区
1.磁盘分区
gdisk /dev/sda
n
+512M
8200
w
partprobe -s
lsblk
2.开始创建swap格式
mkswap /dev/sda6
blkid /dev/sda6
3.开始观察与加载查看
free 查看当前系统内存使用情况,与交换分区使用情况
swapon /dev/sda6 将其设置为交换分区
free 这次能看到swap增加了不少
swapon -s 查看当前使用的内存交换分区设备有哪些
4.持久化
blkid /dev/sta6 得到UUID
nano /etc/fstab
UUID="c716c895-6286-45f2-8906-bc106bc5dcff" swap swap defaults 0 0
mount -a
7.5.2 使用文件创建内存交换文件
dd if=/dev/zero of=/tmp/swap bs=1M count=128 创建一个128M的文件/tmp/swap
mkswap /tmp/swap 将文件格式化为内存交换文件的文件格式,要特别小心,写错可能会让系统挂掉!!!
swapon /tmp/swap 使用swapon将/tmp/swap启动
swapon -s 查看当前所有的swap分区
nano /etc/fstab
/tmp/swap swap swap defaults 0 0 此处务必不能使用UUID,系统会找不到文件的UUID,只会找区块的UUID
swapoff /tmp/swap /dev/sda6 关闭这两个swap分区或文件
swapon -s 查看是否关闭成功
swapon -a 让所有的都生效
swapon -s 查看是否生效成功
7.6 文件系统的特殊观察与操作
7.6.1 磁盘空间之浪费问题
大磁盘、小磁盘、文件容量损耗
7.6.2 利用GNU的parted进行分区操作
parted [设备] [命令[参数]]
parted /dev/sda print 查看/dev/sda系列
parted /dev/sda mkpart primary fat32 36.0GB 36.5GB 新建分区,这个36.0GB是抄的上一个分区的End
parted /dev/sda print 再次查看
partprobe -s 让它生效
lsblk /dev/sda7 要确保它真的存在
blkid /dev/sda7 查询UUID
nano /etc/fstab
UUID="DD87-2ABC" /data/win vfat defaults 0 0
mkdir /data/win
mount -a
df /data/win
如果单纯操控gpt文件系统,还是用gdisk最好。
但是如果要写个脚本,让分区全部一口气建立,parted就十分有效,因为parted不需要和用户互动,这就是它最大的好处。