1.一切从 “/” 开始
Linux 系统中的一切文件都是从“根”目录(/)开始,并按照文件系统层次标准(FHS)采用倒树状结构来存放文件,以及定义了常见目录的用途。
另外,Linux 系统中的文件和目录名称是严格区分大小写的。例如,root、rOOt、Root、rooT 均代表不同的目录,并且文件名称中不得包含斜杠(/)。Linux 系统中的文件存储结构如图所示。
在 Linux 系统中,最常见的目录以及所对应的存放内容如表所示:
在 Linux 系统中另外还有一个重要的概念—路径。路径指的是如何定位到某个文件,分为绝对路径与相对路径。绝对路径指的是从根目录(/)开始写起的文件或目录名称,而相对路径则指的是相对于当前路径的写法。
2.物理设备的命名规则
在 Linux 系统中一切都是文件,硬件设备也不例外。既然是文件,就必须有文件名称。系统内核中的 udev 设备管理器会自动把硬件名称规范起来,目的是让用户通过设备文件的名字可以猜出设备大致的属性以及分区信息等;这对于陌生的设备来说特别方便。另外,udev设备管理器的服务会一直以守护进程的形式运行并侦听内核发出的信号来管理/dev 目录下的设备文件。Linux 系统中常见的硬件设备及其文件名称如表所示。
由于现在的 IDE 设备已经很少见了,所以一般的硬盘设备都是以“/dev/sd”开头。而一台主机上可以有多块硬盘,因此系统采用 a~z 来代表 26 块不同的硬盘(默认从 a 开始分配),而且硬盘的分区编号也很有讲究:
➢ 主分区或扩展分区的编号从 1 开始,到 4 结束;
➢ 逻辑分区从编号 5 开始。
国内很多 Linux 培训讲师以及很多知名 Linux 图书在讲到设备和分区名称时,总会讲错两个知识点。第一个知识点是设备名称的理解错误。很多培训讲师和 Linux 技术图书中会提到,如/dev/sda 表示主板上第一个插槽上的存储设备,学员或读者在实践操作的时候会发现果然如此,因此也就对这条理论知识更加深信不疑。但真相不是这样的,/dev 目录中 sda 设备之所以是 a,并不是由插槽决定的,而是由系统内核的识别顺序来决定的,而恰巧很多主板的插槽顺序就是系统内核的识别顺序,因此才会被命名为/dev/sda。大家以后在使用 iSCSI 网络存储设备时就会发现,明明主板上第二个插槽是空着的,但系统却能识别到/dev/sdb 这个设备—就是这个道理。
第二个知识点是对分区名称的理解错误。很多 Linux 培训讲师会告诉学员,分区的编号代表分区的个数。比如 sda3 表示这是设备上的第 3 个分区,而学员在做实验的时候确实也会得出这样的结果。但是这个理论知识是错误的,因为分区的数字编码不一定是强制顺延下来的,也有可能是手工指定的。因此 sda3 只能表示是编号为 3 的分区,而不能判断 sda 设备上已经存在了 3 个分区。
在填了这两个“坑”之后,再来分析一下/dev/sda5 这个设备文件名称包含哪些信息:
首先,/dev/目录中保存的应当是硬件设备文件;其次,sd 表示的是存储设备;然后,a表示系统中同类接口中第一个被识别到的设备;最后,5 表示这个设备是一个逻辑分区。一言以蔽之,“/dev/sda5”表示的就是“这是系统中第一块被识别到的硬件设备中分区编号为 5 的逻辑分区的设备文件”。主分区、扩展分区、逻辑分区可以像图示那样来规划:
注:所谓扩展分区,严格地讲它不是一个实际意义的分区,而仅仅是一个指向其他分区的指针,这种指针结构将形成一个单向链表。因此扩展分区自身不能存储数据,用户需要在其指向的对应分区(称之为逻辑分区)上进行操作。
若购买了一台云主机,还会看到类似于/dev/vda、/dev/vdb 这样的设备。这种以 vd 开头的设备叫作 Virtio 设备,简单来说就是一种虚拟化设备。像 KVM、Xen 这种虚拟机监控器(Hypervisor)默认就都是这种设备。
3 .文件系统与数据资料
Linux 系统支持数十种文件系统,而最常见的文件系统如下所示。
➢ Ext2:最早可追溯到 1993 年,是 Linux 系统的第一个商业级文件系统,它基本沿袭了 UNIX 文件系统的设计标准。但由于不包含日志读写功能,数据丢失的可能性很大,因此大家能不用就不用,或者顶多建议用于 SD 存储卡或 U 盘。
➢ Ext3:是一款日志文件系统,它会把整个硬盘的每个写入动作的细节都预先记录下来,然后再进行实际操作,以便在发生异常宕机后能回溯追踪到被中断的部分。Ext3 能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。然而,当硬盘容量较大时,所需的修复时间也会很长,而且也不能 100%地保证资料不会丢失。
➢ Ext4:Ext3 的改进版本,作为 RHEL 6 系统中默认的文件管理系统,它支持的存储容量高达 1EB(1EB=1,073,741,824GB),且能够有无限多的子目录。另外,Ext4 文件系统能够批量分配 block(块),从而极大地提高了读写效率。现在很多主流服务器也会使用 Ext4 文件系统。
➢ XFS:是一种高性能的日志文件系统,而且是 RHEL 7/8 中默认的文件管理系统。它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只需花费极低的计算和存储性能。它支持的最大存储容量为 18EB,这几乎满足了所有需求。
在拿到一块新的硬盘存储设备后,先需要分区,然后再格式化文件系统,最后才能挂载并正常使用。硬盘的分区操作取决于您的需求和硬盘大小;也可以选择不进行分区,但是必须对硬盘进行格式化处理。
日常需要保存在硬盘中的数据实在太多了,因此 Linux 系统中有一个名为 super block 的“硬盘地图”。Linux 并不是把文件内容直接写入到这个“硬盘地图”里面,而是在里面记录着整个文件系统的信息。因为如果把所有的文件内容都写入到这里面,它的体积将变得非常大,而且文件内容的查询与写入速度也会变得很慢。Linux 只是把每个文件的权限与属性记录在 inode 中,而且每个文件占用一个独立的 inode 表格,该表格的大小默认为 128 字节,里面记录着如下信息:
➢ 该文件的访问权限(read、write、execute);
➢ 该文件的所有者与所属组(owner、group);
➢ 该文件的大小(size);
➢ 该文件的创建或内容修改时间(Ctime);
➢ 该文件的最后一次访问时间(Atime);
➢ 该文件的修改时间(Mtime);
➢ 文件的特殊权限(SUID、SGID、SBIT);
➢ 该文件的真实数据地址(point)。
而文件的实际内容则保存在 block 块中(大小一般是 1KB、2KB 或 4KB),一个 inode 的默认大小仅为 128 字节,记录一个 block 则消耗 4 字节。当文件的 inode 被写满后,Linux 系统会自动分配出一个 block,专门用于像 inode 那样记录其他 block 块的信息,这样把各个 block块的内容串到一起,就能够让用户读到完整的文件内容了。对于存储文件内容的 block 块,有下面两种常见的情况(以 4KB 大小的 block 为例进行说明)。
➢ 情况 1:文件很小(1KB),但依然会占用一个 block,因此会潜在地浪费 3KB。
➢ 情况 2:文件很大(5KB),那么会占用两个 block(5KB−4KB 后剩下的 1KB 也要占
用一个 block)。
计算机系统在发展过程中产生了众多的文件系统,为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux 内核中的软件层为用户程序提供了一个虚拟文件系统(Virtual File System,VFS)接口,这样用户实际上在操作文件时就是统一对这个虚拟文件系统进行操作了。图示为VFS 的架构示意图。从中可见,实际文件系统在 VFS 下隐藏了自己的特性和细节,这样用户在日常使用时会觉得“文件系统都是一样的”,也就可以随意使用各种命令在任何文件系统中进行各种操作了(比如使用 cp 命令来复制文件)。
VFS 也有点像一个翻译官。我们不需要知道对方的情况,只要告诉 VFS 想进行的操作是什么,它就会自动判断对方能够听得懂什么指令,然后翻译并交代下去。这可以让用户不用操心这些“小事情”,专注于自己的操作。
4 .挂载硬件设备
什么是挂载?——当用户需要使用硬盘设备或分区中的数据时,需要先将其与一个已存在的目录文件进行关联,而这个关联动作就是“挂载”
(1)mount 命令
mount 命令用于挂载文件系统。
语法格式:mount 文件系统 挂载目录
mount 命令中可用的参数及作用如表所示。挂载是在使用硬件设备前所执行的最后一步操作。只需使用mount 命令把硬盘设备或分区与一个目录文件进行关联,然后就能在这个目录中看到硬件设备中的数据了。对于比较新的 Linux 系统来讲,一般不需要使用-t 参数来指定文件系统的类型,Linux 系统会自动进行判断。而 mount 中的-a 参数则厉害了,它会在执行后自动检查/etc/fstab文件中有无被疏漏挂载的设备文件,如果有,则进行自动挂载操作。
例如,要把设备/dev/sdb2 挂载到/backup 目录,只需要在 mount 命令中填写设备与挂载目
录参数就行,系统会自动判断要挂载文件的类型,命令如下:
[root@linuxprobe ~]# mount /dev/sda1 /backup
提示:如果不知道自己可以使用哪个设备挂在,可以使用可以用 lsblk 命令以树状图的形式列举
一下。 lsblk 命令用于查看已挂载的磁盘的空间使用情况,英文全称为“list block id”,输入该命
令后按回车键执行即可。
[root@linuxprobe ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─rhel-root 253:0 0 17.5G 0 lvm /
└─rhel-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 3.5G 0 rom /media/cdrom
从上面的结果可以看出,当前可以使用sda1设备练习挂载操作,目前sda1挂载在boot下
挂载完成后可以在使用lsblk命令查看结果:
[root@linuxprobe ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /backup
└─sda2 8:2 0 19.5G 0 part
├─rhel-root 253:0 0 17.5G 0 lvm /
└─rhel-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 3.5G 0 rom /media/cdrom
如果在工作中要挂载一块网络存储设备,该设备的名字可能会变来变去,这样再写为sdb 就不太合适了。这时推荐用 UUID(Universally Unique Identifier,通用唯一识别码)进行挂载操作。UUID 是一串用于标识每块独立硬盘的字符串,具有唯一性及稳定性,特别适合用来挂载网络设备。那么,怎么才能得知独立硬盘的 UUID 呢?答案是使用 blkid命令。
blkid 命令用于显示设备的属性信息,英文全称为“block id”,语法格式为“blkid [设备名]”。使用 blkid 命令来查询设备 UUID 的示例如下:
[root@linuxprobe ~]# blkid
/dev/sr0: UUID="2014-05-07-03-58-46-00" LABEL="RHEL-7.0 Server.x86_64" TYPE="iso9660" PTTYPE="dos"
/dev/sda1: UUID="2951a864-c3d4-4877-af8c-4e896fbb7761" TYPE="xfs"
/dev/sda2: UUID="Aub2IG-3hln-5IKA-g4dY-uRf9-B5R7-DiQDiu" TYPE="LVM2_member"
/dev/mapper/rhel-root: UUID="7e464519-28d0-4e12-80ca-e3d31f39085d" TYPE="xfs"
/dev/mapper/rhel-swap: UUID="7658bbc6-3640-4267-83fe-9df2ba0f3ba9" TYPE="swap"
有了设备的 UUID 值之后,就可以用它挂载网络设备了:
[root@linuxprobe~]# mount UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /backup
虽然按照上面的方法执行 mount 命令后就能立即使用文件系统了,但系统在重启后挂载就会失效,也就是说需要每次开机后都手动挂载一下。这肯定不是我们想要的效果,如果想让硬件设备和目录永久地进行自动关联,就必须把挂载信息按照指定的填写格式“设备文件 挂载目录 格式类型 权限选项 是否备份 是否自检”(各字段的意义见表)写入到/etc/fstab 文件中。这个文件中包含着挂载所需的诸多信息项目,一旦配置好之后就能一劳永逸了。
如果想将文件系统为 Ext4 的硬件设备/dev/sdb2 在开机后自动挂载到/backup 目录上,并保持默认权限且无须开机自检,就需要在/etc/fstab 文件中写入下面的信息,这样在系统重启后也会成功挂载。
[root@linuxprobe~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 4 10:38:44 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /backup xfs defaults 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
由于后面需要使用系统镜像制作 Yum/DNF 软件仓库,我们提前把光盘设备挂载到/media/cdrom 目录中。光盘设备的文件系统格式是 iso9660:
[root@linuxprobe~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 4 10:38:44 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /backup xfs defaults 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
写入到/etc/fstab 文件中的设备信息并不会立即生效,需要使用 mount -a 参数进行自动挂载:
[root@linuxprobe~]# mount -a
(2)df 命令
df 命令用于查看已挂载的磁盘空间使用情况,英文全称为“disk free”,语法格式为“df -h”。
如果想查看当前系统中设备的挂载情况,非常推荐大家试试 df 命令。它不仅能够列出系统中正在使用的设备有哪些,还可以用-h 参数便捷地对存储容量进行“进位”操作。例如,在遇到 10240K 的时候会自动进位写成 10M,非常方便我们的阅读。
[root@linuxprobe~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 969M 0 969M 0% /dev
tmpfs 984M 0 984M 0% /dev/shm
tmpfs 984M 18M 966M 2% /run
tmpfs 984M 0 984M 0% /sys/fs/cgroup
/dev/mapper/rhel-root 17G 3.9G 14G 23% /
/dev/sda1 1014M 152M 863M 15% /boot
/dev/sdb2 480M 20M 460M 4% /backup
tmpfs 197M 16K 197M 1% /run/user/42
tmpfs 197M 3.5M 194M 2% /run/user/0
/dev/sr0 6.7G 6.7G 0 100% /media/cdrom
(3)umount 命令
挂载文件系统的目的是为了使用硬件资源,而卸载文件系统则意味不再使用硬件的设备资源。既然挂载操作就是把硬件设备与目录两者进行关联的动作,那么卸载操作只需要说明想要取消关联的设备文件或挂载目录的其中一项即可,一般不需要加其他额外的参数。
umount 命令用于卸载设备或文件系统,英文全称为“un mount”。
语法格式:umount [设备文件/挂载目录]
[root@linuxprobe ~]# umount /dev/sda1
[root@linuxprobe ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─rhel-root 253:0 0 17.5G 0 lvm /
└─rhel-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 3.5G 0 rom /media/cdrom
如果我们当前就处于设备所挂载的目录,系统会提示该设备繁忙,此时只需要退出到其他目录后再尝试一次就行:
[root@linuxprobe~]# cd /media/cdrom/
[root@linuxprobe cdrom]# umount /dev/cdrom
umount: /media/cdrom: target is busy.
[root@linuxprobe cdrom]# cd~
[root@linuxprobe~]# umount /dev/cdrom
小技巧:如果系统中硬盘特别多,分区特别多,我们都不知道它们是否有被使用,又或者是做了些什么。此时,就可以用 lsblk 命令以树状图的形式列举一下了。
lsblk 命令用于查看已挂载的磁盘的空间使用情况,英文全称为“list block id”,输入该命令后按回车键执行即可。
[root@linuxprobe ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─rhel-root 253:0 0 17.5G 0 lvm /
└─rhel-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 3.5G 0 rom /media/cdrom
5.添加硬盘设备
添加硬盘设备的操作思路:首先需要在虚拟机中模拟添加入一块新的硬盘存储设备,然后再进行分区、格式化、挂载等操作,最后通过检查系统的挂载状态并真实地使用硬盘来验证硬盘设备是否成功添加。
鉴于我们不需要为了做这个实验而特意买一块真实的硬盘,而是通过虚拟机软件进行硬件模拟,因此这再次体现出了使用虚拟机软件的好处。具体的操作步骤如下:
1)首先把虚拟机系统关机,稍等几分钟会自动返回到虚拟机管理主界面,然后单击“编辑虚拟机设置”选项,在弹出的界面中单击“添加”按钮,新增一块硬件设备。
2)选择想要添加的硬件类型为“硬盘”,然后单击“下一步”按钮就可以了。
3)选择虚拟硬盘的类型为 SATA,并单击“下一步”按钮。这样虚拟机中的设备名称过一会儿后应该为/dev/sdb。
4)选中“创建新虚拟磁盘”单选按钮(而不是其他选项),再次单击“下一步”按钮。
5)将“最大磁盘大小”设置为默认的 20GB。这个数值是限制这台虚拟机所使用的最大硬盘空间,而不是立即将其填满,因此默认 20GB 就很合适了。单击“下一步”按钮。
6)设置磁盘文件的文件名和保存位置(这里采用默认设置即可,无须修改),直接单击“完成”按钮。
7)将新硬盘添加好后就可以看到设备信息了。这里不需要做任何修改,直接单击“确定”按钮后就可以启虚拟机了。
在虚拟机中模拟添加了硬盘设备后就应该能看到抽象后的硬盘设备文件了。按照前文讲解的 udev 服务命名规则,第二个被识别的 SATA 设备应该会被保存为/dev/sdb,这个就是硬盘设备文件了。
[root@linuxprobe ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─rhel-root 253:0 0 17.5G 0 lvm /
└─rhel-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
sr0 11:0 1 3.5G 0 rom /media/cdrom
但在开始使用该硬盘之前还需要进行分区操作,例如从中取出一个 2GB 的分区设备以供后面的操作使用。
5.1 fdisk 命令
fdisk 命令用于新建、修改及删除磁盘的分区表信息,英文全称为“format disk”。
语法格式:fdisk 磁盘名称
在 Linux 系统中,管理硬盘设备最常用的方法就当属 fdisk 命令了。它提供了集添加、删除、转换分区等功能于一身的“一站式分区服务”。不过与前面讲解的直接写到命令后面的参数不同,这条命令的参数是交互式的一问一答的形式,因此在管理硬盘设备时特别方便,可以根据需求动态调整。
首先使用 fdisk 命令来尝试管理/dev/sdb 硬盘设备。在看到提示信息后输入参数 p 来查看硬盘设备内已有的分区信息,其中包括了硬盘的容量大小、扇区个数等信息:
[root@linuxprobe ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x29b6fd9c.
Command (m for help): p
Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x29b6fd9c
输入参数 n 尝试添加新的分区。系统会要求用户是选择继续输入参数 p 来创建主分区,还是输入参数 e 来创建扩展分区。这里输入参数 p 来创建一个主分区:
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
在确认创建一个主分区后,系统要求用户先输入主分区的编号。在前文得知,主分区的编号范围是 1~4,因此这里输入默认的 1 就可以了。接下来系统会提示定义起始的扇区位置,这不需要改动,敲击回车键保留默认设置即可,系统会自动计算出最靠前的空闲扇区的位置。最后,系统会要求定义分区的结束扇区位置,这其实就是要去定义整个分区的大小是多少。我们不用去计算扇区的个数,只需要输入+2G 即可创建出一个容量为 2GB的硬盘分区。
Partition number (1-4, default 1): 1
First sector (2048-41943039, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +2G
Partition 1 of type Linux and of size 2 GiB is set
再次使用参数 p 来查看硬盘设备中的分区信息。果然就能看到一个名称为/dev/sdb1、起始扇区位置为 2048、结束扇区位置为 4196351 的主分区了。这时千万不要直接关闭窗口,而应该敲击参数 w 后按回车键,这样分区信息才是真正地写入成功。
Command (m for help): p
Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x29b6fd9c
Device Boot Start End Blocks Id System
/dev/sdb1 2048 4196351 2097152 83 Linux
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
分区信息中第 6 个字段的 Id 值是一个编码,用于标识该分区的作用,可帮助用户快速了解该分区的作用,一般没必要修改。使用 l 参数查看一下磁盘编码都有哪些,然后在后面进行 SWAP 操作时再修改:
[root@linuxprobe ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): l
0 Empty 24 NEC DOS 81 Minix / old Lin bf Solaris
1 FAT12 27 Hidden NTFS Win 82 Linux swap / So c1 DRDOS/sec (FAT-
2 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT-
3 XENIX usr 3c PartitionMagic 84 OS/2 hidden C: c6 DRDOS/sec (FAT-
4 FAT16 <32M 40 Venix 80286 85 Linux extended c7 Syrinx
5 Extended 41 PPC PReP Boot 86 NTFS volume set da Non-FS data
6 FAT16 42 SFS 87 NTFS volume set db CP/M / CTOS / .
7 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux plaintext de Dell Utility
8 AIX 4e QNX4.x 2nd part 8e Linux LVM df BootIt
9 AIX bootable 4f QNX4.x 3rd part 93 Amoeba e1 DOS access
a OS/2 Boot Manag 50 OnTrack DM 94 Amoeba BBT e3 DOS R/O
b W95 FAT32 51 OnTrack DM6 Aux 9f BSD/OS e4 SpeedStor
c W95 FAT32 (LBA) 52 CP/M a0 IBM Thinkpad hi eb BeOS fs
e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a5 FreeBSD ee GPT
f W95 Ext'd (LBA) 54 OnTrackDM6 a6 OpenBSD ef EFI (FAT-12/16/
10 OPUS 55 EZ-Drive a7 NeXTSTEP f0 Linux/PA-RISC b
11 Hidden FAT12 56 Golden Bow a8 Darwin UFS f1 SpeedStor
12 Compaq diagnost 5c Priam Edisk a9 NetBSD f4 SpeedStor
14 Hidden FAT16 <3 61 SpeedStor ab Darwin boot f2 DOS secondary
16 Hidden FAT16 63 GNU HURD or Sys af HFS / HFS+ fb VMware VMFS
17 Hidden HPFS/NTF 64 Novell Netware b7 BSDI fs fc VMware VMKCORE
18 AST SmartSleep 65 Novell Netware b8 BSDI swap fd Linux raid auto
1b Hidden W95 FAT3 70 DiskSecure Mult bb Boot Wizard hid fe LANstep
1c Hidden W95 FAT3 75 PC/IX be Solaris boot ff BBT
1e Hidden W95 FAT1 80 Old Minix
在上述步骤执行完毕之后,Linux 系统会自动把这个硬盘主分区抽象成/dev/sdb1 设备文件。可以使用 file 命令查看该文件的属性,但有些时候系统并没有自动把分区信息同步给 Linux 内核,而且这种情况似乎还比较常见(但不能算作严重的 bug)。可以输入 partprobe 命令手动将分区信息同步到内核,而且一般推荐连续两次执行该命令,效果会更好。如果使用这个命令都无法解决问题,那么就重启计算机,一定会有用的。
[root@linuxprobe ~]# file /dev/sdb1
/dev/sdb1: block special (此处实际已经更新到内核中了,为了演示执行两次partprobe命令)
[root@linuxprobe ~]# partprobe
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
[root@linuxprobe ~]# partprobe
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
[root@linuxprobe ~]# file /dev/sdb1
/dev/sdb1: block special
如果硬件存储设备没有进行格式化,则 Linux 系统无法得知怎么在其上写入数据。因此,在对存储设备进行分区后还需要进行格式化操作。在 Linux 系统中用于格式化操作的命令是mkfs。这条命令很有意思,因为在 Shell 终端中输入 mkfs 名后再敲击两下用于补齐命令的 Tab键,会有如下所示的效果:
[root@linuxprobe ~]# mkfs
mkfs mkfs.cramfs mkfs.ext3 mkfs.fat mkfs.msdos mkfs.xfs
mkfs.btrfs mkfs.ext2 mkfs.ext4 mkfs.minix mkfs.vfat
这个 mkfs 命令很贴心地把常用的文件系统名称用后缀的方式保存成了多个命令文件,用起来也非常简单—mkfs.文件类型名称。例如要将分区为 XFS 的文件系统进行格式化,则命令应为 mkfs.xfs /dev/sdb1。
[root@linuxprobe ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1 isize=256 agcount=4, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0
data = bsize=4096 blocks=524288, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
终于完成了存储设备的分区和格式化操作,接下来就是要来挂载并使用存储设备了。与之相关的步骤也非常简单:首先是创建一个用于挂载设备的挂载点目录;然后使用 mount命令将存储设备与挂载点进行关联;最后使用 df -h 命令来查看挂载状态和硬盘使用量信息。
[root@linuxprobe ~]# mkdir /newFS
[root@linuxprobe ~]# mount /dev/sdb1 /newFS
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 18G 2.9G 15G 17% /
devtmpfs 985M 0 985M 0% /dev
tmpfs 994M 140K 994M 1% /dev/shm
tmpfs 994M 8.8M 986M 1% /run
tmpfs 994M 0 994M 0% /sys/fs/cgroup
/dev/sr0 3.5G 3.5G 0 100% /media/cdrom
/dev/sda1 497M 119M 379M 24% /boot
/dev/sdb1 2.0G 33M 2.0G 2% /newFS
5.2 du 命令
du 命令用查看分区或目录所占用的磁盘容量大小,简单来说,该命令就是用来查看一个或多个文件占用了多大的硬盘空间。英文全称为“disk usage”。
语法格式:du -sh 目录名称
在 Linux 系统中可以使用 du -sh /*命令来查看在 Linux 系统根目录下所有一级目录分别占用的空间大小,在 1s 之内就能找到哪个目录占用的空间最多:
[root@linuxprobe ~]# du -sh /*
0 /backup
4.0K /backup.acl
0 /bin
93M /boot
140K /dev
33M /etc
36K /home
0 /lib
0 /lib64
3.6G /media
0 /mnt
0 /newFS
0 /opt
0 /proc
4.9M /root
8.8M /run
0 /sbin
0 /srv
0 /sys
52K /tmp
2.8G /usr
77M /var
先从某些目录中复制过来一批文件,然后查看这些文件总共占用了多大的容量:
[root@linuxprobe ~]# cp -rf /etc/* /newFS
[root@linuxprobe ~]# ls /newFS/
abrt hosts pulse
adjtime hosts.allow purple
aliases hosts.deny qemu-ga
...
[root@linuxprobe ~]# du -sh /newFS
33M /newFS
前面在讲解 mount 命令时提到,使用 mount 命令挂载的设备文件会在系统下一次重启的时候失效。如果想让这个设备文件的挂载永久有效,则需要把挂载的信息写入配置文件中:
[root@linuxprobe ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 4 10:38:44 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /boot xfs defaults 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb1 /newFS xfs defaults 0 0
6.添加交换分区
交换(SWAP)分区是一种通过在硬盘中预先划分一定的空间,然后把内存中暂时不常用的数据临时存放到硬盘中,以便腾出物理内存空间让更活跃的程序服务来使用的技术,其设计目的是为了解决真实物理内存不足的问题。通俗来讲就是让硬盘帮内存分担压力。但由于交换分区毕竟是通过硬盘设备读写数据的,速度肯定要比物理内存慢,所以只有当真实的物理内存耗尽后才会调用交换分区的资源。
交换分区的创建过程与前文讲到的挂载并使用存储设备的过程非常相似。在对/dev/sdb存储设备进行分区操作前,有必要先说一下交换分区的划分建议:在生产环境中,交换分区的大小一般为真实物理内存的 1.5~2 倍。为了让大家更明显地感受交换分区空间的变化,这里取出一个大小为 5GB 的主分区作为交换分区资源:
[root@linuxprobe ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): p
Partition number (2-4, default 2):
First sector (4196352-41943039, default 4196352):
Using default value 4196352
Last sector, +sectors or +size{K,M,G} (4196352-41943039, default 41943039): +5G
Partition 2 of type Linux and of size 5 GiB is set
在上面的操作结束后,我们就得到了一个容量为 5GB 的新分区。然后尝试修改硬盘的标识码,这里将其改成 82(Linux swap)以方便以后知道它的作用:
Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'
Command (m for help): p
Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x29b6fd9c
Device Boot Start End Blocks Id System
/dev/sdb1 2048 4196351 2097152 83 Linux
/dev/sdb2 4196352 14682111 5242880 82 Linux swap / Solaris
敲击 w 参数退出分区表编辑工具:
Command (m for help): w
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.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
下面来看一下两个与交换分区相关的简单命令。
mkswap 命令用于对新设备进行交换分区格式化,英文全称为“make swap”。
语法格式:mkswap 设备名称
[root@linuxprobe ~]# mkswap /dev/sdb2
/dev/sdb2: No such file or directory(这里是内核没有更新新加的分区)
[root@linuxprobe ~]# partprobe
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
[root@linuxprobe ~]# partprobe
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0 has been opened read-only.
[root@linuxprobe ~]# mkswap /dev/sdb2
Setting up swapspace version 1, size = 5242876 KiB
no label, UUID=a73dc740-1b44-4e77-9d6f-01fe16d830b7
swapon 命令把准备好的 SWAP 硬盘设备正式挂载到系统中。可以使用 free -m 命令查看交换分区的大小变化(由 2047MB 增加到 7167MB):
[root@linuxprobe ~]# free -m
total used free shared buffers cached
Mem: 1987 1283 704 9 3 303
-/+ buffers/cache: 976 1011
Swap: 2047 0 2047
[root@linuxprobe ~]# swapon /dev/sdb2
[root@linuxprobe ~]# free -m
total used free shared buffers cached
Mem: 1987 1287 700 9 3 303
-/+ buffers/cache: 980 1007
Swap: 7167 0 7167
为了能够让新的交换分区设备在重启后依然生效,需要按照下面的格式将相关信息写入配置文件中,并记得保存:
[root@linuxprobe ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 4 10:38:44 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /boot xfs defaults 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb1 /newFS xfs defaults 0 0
/dev/sdb2 swap swap defaults 0 0
7. 磁盘容量配额
本书在前面曾经讲到,Linux 系统的设计初衷就是让许多人一起使用并执行各自的任务,从而成为多用户、多任务的操作系统。但是,硬件资源是固定且有限的,如果某些用户不断地在 Linux 系统上创建文件或者存放电影,硬盘空间总有一天会被占满。针对这种情况,root管理员就需要使用磁盘容量配额服务来限制某位用户或某个用户组针对特定文件夹可以使用的最大硬盘空间或最大文件个数,一旦达到这个最大值就不再允许继续使用。可以使用 quota技术进行磁盘容量配额管理,从而限制用户的硬盘可用容量或所能创建的最大文件个数。quota技术还有软限制和硬限制的功能。
➢ 软限制:当达到软限制时会提示用户,但仍允许用户在限定的额度内继续使用。
➢ 硬限制:当达到硬限制时会提示用户,且强制终止用户的操作。
RHEL 7 (RHEL 8 )系统中已经安装了quota 磁盘容量配额服务程序包,但存储设备却默认没有开启对quota 的支持,此时需要手动编辑配置文件,让RHEL 7 系统中的/boot 目录能够支持quota磁盘配额技术。另外,对于学习过早期的Linux 系统,或者具有RHEL 6 系统使用经验的读者来说,这里需要特别注意。早期的Linux 系统要想让硬盘设备支持quota 磁盘容量配额服务,使用的是usrquota 参数,而RHEL 7 系统使用的则是uquota 参数。在重启系统后使用mount命令查看,即可发现/boot 目录已经支持quota 磁盘配额技术了:
[root@linuxprobe ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 4 10:38:44 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=2951a864-c3d4-4877-af8c-4e896fbb7761 /boot xfs defaults,uquota 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb1 /newFS xfs defaults 0 0
/dev/sdb2 swap swap defaults 0 0
然后reboot重启系统,在使用mount命令查看/boot目录,发现已经支持usrquota。
[root@linuxprobe ~]# mount | grep boot
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,usrquota)
[root@linuxprobe ~]#
接下来创建一个用于检查quota 磁盘容量配额效果的用户tom,并针对/boot 目录增加其他人的写权限,保证用户能够正常写入数据:
[root@linuxprobe ~]# useradd tom
[root@linuxprobe ~]# chmod -Rf o+w /boot
7.1 xfs_quota 命令
xfs_quota 命令用于管理设备的磁盘容量配额。
语法格式:xfs_quota [参数] 配额 文件系统
这是一个专门针对 XFS 文件系统来管理 quota 磁盘容量配额服务而设计的命令。其中,-c 参数用于以参数的形式设置要执行的命令;-x 参数是专家模式,让运维人员能够对 quota服务进行更多复杂的配置。接下来使用 xfs_quota 命令来设置用户 tom 对/boot 目录的 quota 磁盘容量配额。具体的限额控制包括:硬盘使用量的软限制和硬限制分别为 3MB 和 6MB;创建文件数量的软限制和硬限制分别为 3 个和 6 个。
[root@linuxprobe ~]# xfs_quota -x -c 'limit bsoft=3m bhard=6m isoft=3 ihard=6 tom' /boot
[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
Blocks
User ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 95152 0 0 00 [--------]
tom 0 3072 6144 00 [--------]
上面所使用的参数分为两组,分别是 isoft/ihard 与 bsoft/bhard,在 Linux 系统中每个文件都会使用一个独立的 inode 信息块来保存属性信息,一个文件对应一个 inode 信息块,所以 isoft 和 ihard 就是通过限制系统最大使用的 inode个数来限制了文件数量。bsoft 和 bhard 则是代表文件所占用的 block 大小,也就是文件占用的最大容量的总统计。
soft 是软限制,超过该限制后也只是将操作记录写到日志中,不对用户行为进行限制。而 hard 是硬限制,一旦超过系统就会马上禁止,用户再也不能创建或新占任何的硬盘容量。
当配置好上述各种软硬限制后,尝试切换到一个普通用户,然后分别尝试创建一个体积为 5MB 和 8MB 的文件。可以发现,在创建 8MB 的文件时受到了系统限制:
[root@linuxprobe ~]# su - tom
[tom@linuxprobe ~]$ cd /boot/
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=5M count=1
1+0 records in
1+0 records out
5242880 bytes (5.2 MB) copied, 0.0055048 s, 952 MB/s
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
dd: error writing ‘/boot/tom’: Disk quota exceeded
1+0 records in
0+0 records out
6291456 bytes (6.3 MB) copied, 0.00935969 s, 672 MB/s
7.2 edquota 命令
edquota 命令用于管理系统的磁盘配额,英文全称为“edit quota”。
语法格式:edquota [参数] 用户名
在为用户设置了 quota 磁盘容量配额限制后,可以使用 edquota 命令按需修改限额的数值。各个参数的作用如下所示:
edquota 命令会调用 Vi 或 Vim 编辑器来让 root 管理员修改要限制的具体细节,记得用wq 保存退出。下面把用户 tom 的硬盘使用量的硬限额从 5MB 提升到 8MB:
[tom@linuxprobe boot]$ exit
logout
[root@linuxprobe ~]# edquota -u tom
Disk quotas for user tom (uid 10000):
Filesystem blocks soft hard inodes soft hard
/dev/sda1 6144 3072 8192 1 3 6
[root@linuxprobe ~]# su - tom
Last login: Thu Nov 14 17:29:26 CST 2024 on pts/0
[tom@linuxprobe ~]$ cd /boot
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
1+0 records in
1+0 records out
8388608 bytes (8.4 MB) copied, 0.0104711 s, 801 MB/s
8. 软硬方式链接
在Windows 系统中,快捷方式就是指向原始文件的一个链接文件,可以让用户从不同的位置来访问原始的文件;原文件一旦被删除或剪切到其他地方后,会导致链接文件失效。但是,这个看似简单的东西在Linux 系统中可不太一样。
在 Linux 系统中存在硬链接和软连接两种文件。
硬链接(hard link):可以将它理解为一个“指向原始文件inode 的指针”,系统不为它分配独立的inode 和文件。所以,硬链接文件与原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的inode 连接数就会增加1;而且只有当该文件的inode 连接数为0 时,才算彻底将它删除。换言之,由于硬链接实际上是指向原文件inode 的指针,因此即便原始文件被删除,依然可以通过硬链接文件来访问。需要注意的是,由于技术的局限性,我们不能跨分区对目录文件进行
链接。
软链接(也称为符号链接[symbolic link]):仅仅包含所链接文件的路径名,因此能链接目录文件,也可以跨越文件系统进行链接。但是,当原始文件被删除后,链接文件也将失效,从这一点上来说与Windows 系统中的“快捷方式”具有一样的性质。
ln 命令
ln 命令用于创建链接文件,格式为“ln [选项] 目标”,其可用的参数以及作用如表所示。在使用 ln 命令时,是否添加-s 参数,将创建出性质不同的两种“快捷方式”。因此如果没有扎实的理论知识和实践经验做铺垫,尽管能够成功完成实验,但永远不会明白为什么会成功。 为了更好地理解软链接、硬链接的不同性质,接下来创建一个类似于 Windows 系统中快捷方式的软链接。这样,当原始文件被删除后,就无法读取新建的链接文件了。
[root@localhost ~]# echo "Welcome to linuxprobe.com" > readme.txt
[root@localhost ~]# ln -s readme.txt readit.txt
[root@localhost ~]# cat readme.txt
Welcome to linuxprobe.com
[root@localhost ~]# ls -l readme.txt
-rw-r--r--. 1 root root 26 Nov 14 21:05 readme.txt
[root@localhost ~]# rm -f readme.txt
[root@localhost ~]# cat readit.txt
cat: readit.txt: No such file or directory
接下来针对一个原始文件创建一个硬链接,即相当于针对原始文件的硬盘存储位置创建了一个指针,这样一来,新创建的这个硬链接就不再依赖于原始文件的名称等信息,也不会因为原始文件的删除而导致无法读取。同时可以看到创建硬链接后,原始文件的硬盘链接数量增加到了 2。
[root@localhost ~]# echo "Welcome to linuxprobe.com" > readme.txt
[root@localhost ~]# ln readme.txt readit.txt
[root@localhost ~]# cat readme.txt
Welcome to linuxprobe.com
[root@localhost ~]# cat readit.txt
Welcome to linuxprobe.com
[root@localhost ~]# ls -l readme.txt
-rw-r--r--. 2 root root 26 Nov 14 21:13 readme.txt
[root@localhost ~]# rm -f readme.txt
[root@localhost ~]# cat readit.txt
Welcome to linuxprobe.com
[root@localhost ~]# ls -l readit.txt
-rw-r--r--. 1 root root 26 Nov 14 21:13 readit.txt
[root@localhost ~]# rm -f readit.txt
[root@localhost ~]# cat readit.txt
cat: readit.txt: No such file or directory
[root@localhost ~]# ls -l readit.txt
ls: cannot access readit.txt: No such file or directory
以上操作删除掉原文件后,新创建的文件依然可以使用,如果继续删除新建的文件,则会彻底删掉。
9. VDO(虚拟数据优化) --RHEL 8 系统可实践
VDO(Virtual Data Optimize,虚拟数据优化)是一种通过压缩或删除存储设备上的数据来优化存储空间的技术。VDO 是红帽公司收购了 Permabit 公司后获取的新技术,并与2019-2020 年前后,多次在 RHEL 7.5/7.6/7.7 上进行测试,最终随 RHEL 8 系统正式公布。VDO技术的关键就是对硬盘内原有的数据进行删重操作,它有点类似于我们平时使用的网盘服务,在第一次正常上传文件时速度特别慢,在第二次上传相同的文件时仅作为一个数据指针,几乎可以达到“秒传”的效果,无须再多占用一份空间,也不用再漫长等待。除了删重操作,VDO 技术还可以对日志和数据库进行自动压缩,进一步减少存储浪费的情况。VDO 针对各种类型文件的压缩效果如表所示。
VDO 技术支持本地存储和远程存储,可以作为本地文件系统、iSCSI 或 Ceph 存储下的附加存储层使用。红帽公司在 VDO 介绍页面中提到,在部署虚拟机或容器时,建议采用逻辑存储与物理存储为 10∶1 的比例进行配置,即 1TB 物理存储对应 10TB 逻辑存储;而部署对象存储时 (例如使用 Ceph)则采用逻辑存储与物理存储为 3∶1 的比例进行配置,即使用 1TB物理存储对应 3TB 逻辑存储。 简而言之,VDO 技术能省空间!
有两种特殊情况需要提前讲一下。其一,公司服务器上已有的 dm-crypt 之类的技术是可以与 VDO 技术兼容的,但记得要先对卷进行加密再使用 VDO。因为加密会使重复的数据变得有所不同,因此删重操作无法实现。要始终记得把加密层放到 VDO 之下,如图所示。
其二,VDO 技术不可叠加使用,1TB 的物理存储提升成 10TB 的逻辑存储没问题,但是再用 10TB 翻成 100TB 就不行了。左脚踩右脚,真的没法飞起来。
练习使用VDO:
把虚拟机关闭,添加一块容量为 20GB 的新 SATA 硬盘进来,开机后就能看到这块名称为/dev/sdc 的新硬盘了:
[root@linuxprobe~]# ls -l /dev/sdc
brw-rw----. 1 root disk 8, 32 Jan 6 22:26 /dev/sdc
RHEL/CentOS 8 系统中默认已经启用了 VDO 技术。VDO 技术现在是红帽公司自己的技术,兼容性自然没得说。如果您所用的系统没有安装 VDO 的话也不要着急,用 dnf 命令即可完成安装:
[root@linuxprobe~]# dnf install kmod-kvdo vdo
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use
subscription-manager to register.
Last metadata expiration check: 0:01:56 ago on Wed 06 Jan 2021 10:37:19 PM CST.
Package kmod-kvdo-6.2.0.293-50.el8.x86_64 is already installed.
Package vdo-6.2.0.293-10.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
首先,创建一个全新的 VDO 卷。
新添加进来的物理设备就是使用 vdo 命令来管理的,其中 name 参数代表新的设备卷的名称;device 参数代表由哪块磁盘进行制作;vdoLogicalSize 参数代表制作后的设备大小。依据红帽公司推荐的原则,20GB 硬盘将翻成 200GB 的逻辑存储:
[root@linuxprobe~]# vdo create --name=storage --device=/dev/sdc --vdoLogicalSize=200G
Creating VDO storage
Starting VDO storage
Starting compression on VDO storage
VDO instance 0 volume is ready at /dev/mapper/storage
注:Linux 命令行严格区别大小写,vdoLogicalSize 参数中的 L 与 S 字母必须大写。
在创建成功后,使用 status 参数查看新建卷的概述信息:
[root@linuxprobe~]# vdo status --name=storage
VDO status:
Date: '2024-11-14 22:51:33+08:00'
Node: linuxprobe.com
Kernel module:
Loaded: true
Name: kvdo
Version information:
kvdo version: 6.2.0.293
Configuration:
File: /etc/vdoconf.yml
Last modified: '2024-11-14 22:49:33'
VDOs:
storage:
Acknowledgement threads: 1
Activate: enabled
Bio rotation interval: 64
Bio submission threads: 4
Block map cache size: 128M
Block map period: 16380
Block size: 4096
CPU-work threads: 2
Compression: enabled
Configured write policy: auto
Deduplication: enabled
………………省略部分输出信息………………
有上可见,在输出信息中包含了 VDO 卷创建的时间、主机名、版本、是否压缩(Compression)
及是否删重(Deduplication)等关键信息。
接下来,对新建卷进行格式化操作并挂载使用。
新建的 VDO 卷设备会被乖乖地存放在/dev/mapper 目录下,并以设备名称命名,对它操作就行。另外,挂载前可以用 udevadm settle 命令对设备进行一次刷新操作,避免刚才的配置没有生效:
[root@linuxprobe~]# mkfs.xfs /dev/mapper/storage
meta-data=/dev/mapper/storage isize=512 agcount=4, agsize=13107200 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1
data = bsize=4096 blocks=52428800, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=25600, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@linuxprobe~]# udevadm settle
[root@linuxprobe~]# mkdir /storage
[root@linuxprobe~]# mount /dev/mapper/storage /storage
如果想查看设备的实际使用情况,使用 vdostats 命令即可。human-readable 参数的作用是将存储容量自动进位,以人们更易读的方式输出(比如,显示 20G 而不是 20971520K):
[root@linuxprobe~]# vdostats --human-readable
Device Size Used Available Use% Space saving%
/dev/mapper/storage 20.0G 4.0G 16.0G 20% 99%
这里显示的 Size 是实际物理存储的空间大小(即 20.0GB 是硬盘的大小),如果想看逻辑存储空间,可以使用 df 命令进行查看:
[root@linuxprobe~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 969M 0 969M 0% /dev
tmpfs 984M 0 984M 0% /dev/shm
tmpfs 984M 9.6M 974M 1% /run
tmpfs 984M 0 984M 0% /sys/fs/cgroup
/dev/mapper/rhel-root 17G 3.9G 14G 23% /
/dev/sr0 6.7G 6.7G 0 100% /media/cdrom
/dev/sda1 1014M 152M 863M 15% /boot
tmpfs 197M 16K 197M 1% /run/user/42
tmpfs 197M 3.5M 194M 2% /run/user/0
/dev/sdb1 2.0G 47M 2.0G 3% /newFS
/dev/mapper/storage 200G 2.4G 198G 2% /storage
随便复制一个大文件过来,看看占用了多少容量,以及空间节省率(Space saving)是多少:
[root@linuxprobe~]# ls -lh /media/cdrom/images/install.img
-r--r--r--. 1 root root 448M Apr 4 2019 /media/cdrom/images/install.img
[root@linuxprobe~]# cp /media/cdrom/images/install.img /storage/
[root@linuxprobe~]# ls -lh /storage/install.img
-r--r--r--. 1 root root 448M Jan 6 23:06 /storage/install.img
[root@linuxprobe~]# vdostats --human-readable
Device Size Used Available Use% Space saving%
/dev/mapper/storage 20.0G 4.4G 15.6G 22% 18%
效果不明显,再复制一份相同的文件过来,看看这次占用了多少空间:
[root@linuxprobe~]# cp /media/cdrom/images/install.img /storage/rhel.img
[root@linuxprobe~]# vdostats --human-readable
Device Size Used Available Use% Space saving%
/dev/mapper/storage 20.0G 4.5G 15.5G 22% 55%
原先 448MB 的文件这次只占用了不到 100MB 的容量,空间节省率也从 18%提升到了 55%。当然这还仅仅是两次操作而已,好处就已经如此明显了。
最后,将设备设置成永久挂载生效,一直提供服务。
VDO 设备卷在创建后会一直存在,但需要手动编辑/etc/fstab 文件后才能在下一次重启后自动挂载生效,为我们所用。对于这种逻辑存储设备,其实不太建议使用/dev/mapper/storage作为设备名进行挂载。不如试试前面所说的 UUID :
[root@linuxprobe~]# blkid /dev/mapper/storage
/dev/mapper/storage: UUID="cd4e9f12-e16a-415c-ae76-8de069076713" TYPE="xfs"
打开/etc/fstab 文件,把对应的字段填写完整。建议再加上_netdev 参数,表示等系统及网络都启动后再挂载 VDO 设备卷,以保证万无一失。
[root@linuxprobe~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Jul 21 05:03:40 2020
#
# Accessible filesystems, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and blkid(8) for more info.
#
# After editing, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults,uquota 1 2
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb1 /newFS xfs defaults 0 0
/dev/sdb2 swap swap defaults 0 0
UUID=cd4e9f12-e16a-415c-ae76-8de069076713 /storage xfs def
aults,_netdev 0 0