Skip to main content

第7章 使用 RAID 与 LVM 磁盘阵列技术

章节简述

在学习了第 6 章关于磁盘设备分区、格式化和挂载的知识后,本章将深入探讨常用 RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)技术方案的特性。通过实际部署RAID 10 和RAID 5+备份盘等方案,我们将直观地展示RAID 的强大效果,从而满足生产环境中对磁盘 IO 速率和数据冗余备份的需求。此外,考虑到用户可能会动态调整存储资源,本章还将介绍 LVM(Logical Volume Manager,逻辑卷管理器)的部署、扩容、缩容、快照以及卸载、删除的相关知识。相信读者在学完本章内容后,可以在企业级生产环境中灵活运用 RAID 和 LVM 来满足对存储资源的高级管理需求。

7.1 RAID

在过去较长的一段时间,CPU 的处理性能保持着高速增长。2024 年,Intel 公司发布了酷睿 i9-14900KS 处理器芯片,让家用电脑达到了 24 核心 32 线程,大核频率最高可达 6.2GHz。而更早些时候,AMD 公司也推出了 Threadripper(线程撕裂者)处理器 7980X,家用电脑自此也可以轻松驾驭 64 核心 128 线程的处理器小怪兽了。但与此同时,磁盘设备的性能提升却不是很大,逐渐成为当代计算机整体性能的瓶颈。而且,由于磁盘设备需要进行持续、频繁、大量的 IO 操作,相较于其他设备,其损坏概率也大幅增加,重要数据丢失的概率也随之加大。

磁盘设备是计算机中较容易出现故障的元器件之一,加之其需要存储数据的特殊性质, 不能像 CPU、内存、电源甚至主板那样在出现故障后更换新的就好,因此在生产环境中一定要未雨绸缪,提前做好数据的冗余及异地备份等工作。

1988 年,美国加州大学伯克利分校首次提出并定义了 RAID 技术的概念。RAID 技术通过把多个磁盘设备组合成一个容量更大、安全性更好的磁盘阵列,并将数据切割成多个区段后分别存放在各个不同的物理磁盘设备上,然后利用分散读写技术来提升磁盘阵列整体的性能,同时通过不同的冗余策略,将重要数据以不同方式分布在多个物理磁盘设备上,从而实现数据冗余备份效果。

任何事物都有它的两面性。RAID 技术确实具有非常好的数据冗余备份功能,但是它也相应地提高了成本支出。就像原本我们只有一个电话本,但为了避免遗失,我们把联系人号码信息写成了两份,自然要为此多买一个电话本,这也就相应地增大了成本支出。RAID 技术诞生旨在提升数据可靠性、可用性和存储性能,而与数据本身的价值相比,现代企业更看重的是RAID 技术所具备的冗余备份机制以及带来的磁盘吞吐量的提升。也就是说,RAID 不仅降低了磁盘设备损坏后丢失数据的概率,还提升了磁盘设备的读写速率,因此在绝大多数运营商或大中型企业中得到了广泛部署和应用。

出于成本和技术方面的考虑,需要针对不同的需求在数据可靠性及读写性能上作出权衡, 制定出满足各自需求的不同方案。目前已有的 RAID 磁盘阵列的方案至少有十几种,而刘遄老师接下来会详细讲解 RAID 0、RAID 1、RAID 5 与 RAID 10 这 4 种最常见的方案。表 7-1 对这 4 种方案进行了比较,其中 n 代表磁盘总数。

表 7-1 RAID 0、1、5、10 方案技术对比

RAID级别最少磁盘可用容量读写性能安全性特点
02nn追求最大容量和速率,任何一块磁盘损 坏,数据将全部异常
12n/2n追求最大安全性,只要阵列组中有一块 磁盘可用,数据就不受影响
53n-1n-1在控制成本的前提下,追求磁盘的最大容量、速率及安全性,允许有一块磁盘 异常,且数据不受影响
104n/2n/2综合 RAID 1 和 RAID 0 的优点,追求磁盘的速率和安全性,允许有一半磁盘异常(不可发生在同一阵列中),且数 据不受影响

1. RAID 0

RAID 0 技术把多块物理磁盘设备(至少两块)通过硬件或软件方式串联在一起,组成一个大的卷组,并将数据依次写入各个物理磁盘中。这样一来,在最理想的状态下,磁盘设备的读写性能会提升数倍,但是若任意一块磁盘发生故障,将导致整个系统的数据都受到破坏。通俗来说,RAID 0 技术能够有效地提升磁盘数据的吞吐速率,但是不具备数据备份和错误修复能力。如图 7-1 所示,数据被分别写入到不同的磁盘设备中,即磁盘 A 和磁盘 B 设备会分别保存数据资料,最终实现提升读取、写入速率的效果。

图7-1 RAID 0技术示意图

2. RAID 1

尽管RAID 0 技术提升了磁盘设备的读写速率,但它是将数据依次写入各个物理磁盘中。也就是说,它的数据是分开存放的,其中任何一块磁盘发生故障都会损坏整个系统的数据。因此,如果生产环境对磁盘设备的读写速率没有要求,而是希望增加数据的安全性时,就需要用到 RAID 1 技术了。

在图 7-2 所示的 RAID 1 技术示意图中可以看出,它是把两块以上的磁盘设备进行绑定, 在写入数据时,是将数据同时写入到多块磁盘设备上(可以将其视为数据的镜像或备份)。当其中某一块磁盘发生故障后,会立即自动以“冗余镜像数据自动接替”的方式来恢复数据的正常使用。

考虑到在进行写入操作时因磁盘切换带来的开销,因此 RAID 1 的速率会比 RAID 0 有微弱的降低。但在读取数据的时候,操作系统能够分别从两块磁盘中读取信息,因此理论读取速率的峰值是磁盘数量的倍数。另外,平时只要保证有一块磁盘稳定运行,数据就不会出现损坏的情况,可靠性较高。

图7-2 RAID 1技术示意图

RAID 1 技术虽然十分注重数据的安全性,但是因为是在多块磁盘设备中写入了相同的数据,因此磁盘设备的利用率得以下降。从理论上来说,图 7-2 所示的磁盘空间的真实可用率只有 50%,由 3 块磁盘设备组成的 RAID 1 磁盘阵列的可用率只有 33%左右;以此类推。而且,由于需要把数据同时写入两块以上的磁盘设备,这无疑也在一定程度上增大了系统计算功能的负载。

那么,有没有一种 RAID 方案既考虑到了磁盘设备的读写速率和数据安全性,还兼顾了成本问题呢?实际上,单从数据安全和成本问题上来讲,就不可能在保持原有磁盘设备的利用率且还不增加新设备的情况下,能大幅提升数据的安全性。刘遄老师也没有必要忽悠各位读者,下面将要讲解的 RAID 5 技术虽然在理论上兼顾了三者(读写速率、数据安全性、成本),但实际上更像是对这三者的“相互妥协”。

3. RAID 5

如图 7-3 所示,RAID 5 技术是把磁盘设备的数据奇偶校验信息保存到其他磁盘设备中。在 RAID 5 磁盘阵列中,数据的奇偶校验信息不是单独保存到某一块磁盘中,而是存储到除自身以外的其他每一块磁盘设备上。这样的好处是,其中任何一块设备损坏后不至于出现致命缺陷。图 7-3 中Parity 部分存放的就是数据的奇偶校验信息。换句话说,就是RAID 5 技术实际上没有备份磁盘中的真实数据,而是当磁盘设备出现问题后通过奇偶校验信息来尝试重建损坏的数据。RAID 这样的技术特性“妥协”地兼顾了磁盘设备的读写速率、数据安全性与存储成本问题。

图7-3 RAID5技术示意图

RAID 5 最少由 3 块磁盘组成,使用的是磁盘条带化(Disk Striping)技术。相较于RAID 1 技术,好处就在于保存的是奇偶校验信息而不是完全一样的文件内容,所以当重复写入某个文件时,RAID 5 级别的磁盘阵列组只需要对应一个奇偶校验信息就可以,因此效率更高,存储成本也会随之降低。

4. RAID 10

RAID 5 技术是出于磁盘设备的成本问题对读写速率和数据的安全性有了一定的妥协,但是大部分企业更在乎的是数据本身的价值而非磁盘价格,因此在生产环境中主要使用 RAID 10 技术。

顾名思义,RAID 10 技术是 RAID 1+RAID 0 技术的一个“组合体”。如图 7-4 所示,RAID 10技术需要至少 4 块磁盘来组建,其中先分别两两制作成 RAID 1 磁盘阵列,以保证数据的安全性;然后再对两个 RAID 1 磁盘阵列实施 RAID 0 技术,进一步提高磁盘设备的读写速率。从理论上来讲,只要损坏的不是同一阵列中的所有磁盘,那么最多可以损坏 50%的磁盘设备而不丢失数据。由于 RAID 10 技术继承了 RAID 0 的高读写速率和 RAID 1 的数据安全性,在不考虑成本的情况下 RAID 10 的性能也超过了 RAID 5,因此当前成为广泛使用的一种存储技术。

图7-4 RAID 10技术示意图

Tips :
由于RAID 10 是由 RAID 1 和RAID 0 组成的,因此正确的叫法是“RAID 一零”,而不是“RAID 十”。

仔细查看图 7-4 可以发现,RAID 10 是先对信息进行分割,然后再两两一组制作镜像。也就是先将 RAID 1 作为最低级别的组合,然后再使用RAID 0 技术将 RAID 1 磁盘阵列组合到一起,将它们视为“一整块”磁盘。而RAID 01 则相反,它是先将磁盘分为两组,然后使用 RAID 0 作为最低级别的组合,再将这两组 RAID 0 磁盘通过 RAID 1 技术组合到一起。

RAID 10 技术和RAID 01 技术的区别非常明显。在 RAID 10 中,任何一块磁盘损坏都不会影响到数据安全性,其余磁盘均会正常运作。但在 RAID 01 中,只要有任何一块磁盘损坏, 最低级别的RAID 0 磁盘阵列马上会停止运作,这可能造成严重隐患。所以 RAID 10 远比 RAID 01 常见,很多主板甚至不支持 RAID 01。

7.1.1 部署磁盘阵列

在具备了第 6 章的磁盘设备管理基础之后,再来部署 RAID 和 LVM 就变得十分轻松了。首先,需要在虚拟机中添加 4 块磁盘设备来制作一个 RAID 10 磁盘阵列,如图 7-5 所示。这里不再详述添加磁盘的步骤,大家自己操作就行。记得要用 SCSI 或 SATA 接口类型的磁盘, 大小默认 20GB 就可以。

这几块磁盘设备是模拟出来的,不需要特意去买几块真实的物理磁盘插到电脑上。需要注意的是,一定要记得在关闭系统之后,再在虚拟机中添加磁盘设备,否则可能会因为计算机架构的不同而导致虚拟机系统无法识别新添加的磁盘设备。

图7-5 添加四块硬盘设备

在当前的生产环境中,服务器一般都配备 RAID 阵列卡。尽管服务器的价格越来越便宜, 但是我们没有必要为了做一个实验而单独购买一台服务器,而是学会使用 mdadm 命令在Linux 系统中创建和管理软件 RAID 磁盘阵列,而且它涉及的理论知识和操作过程与生产环境中的完全一致。

mdadm命令用于创建、调整、监控和管理RAID设备,英文全称为“multiple devices admin”,语法格式为“mdadm 参数 硬盘名称”。

mdadm 命令的常用参数及作用如表 7-2 所示。

表 7-2 mdadm 命令的常用参数及作用

参数作用
-a自动检测设备名称
-n指定设备数量
-l指定 RAID 级别
-C创建新的 RAID 阵列
-v显示详细创建过程信息
-f模拟设备损坏
-r移除设备
-Q查看摘要信息
-D查看详细信息
-S停止 RAID 磁盘阵列

接下来,使用 mdadm 命令创建RAID 10,名称为/dev/md0。

第 6 章讲到,udev 是 Linux 系统内核中用来给硬件命名的服务,其命名规则也非常简单。通过命名规则可以猜测到第二个 SCSI 存储设备的名称会是/dev/sdb,然后依此类推。使用磁盘设备来部署 RAID 磁盘阵列很像将几位同学组成一个班级,但总不能将班级命名为/dev/sdbcde 吧。尽管这样可以一眼看出它是由哪些元素组成的,但不利于记忆和阅读。更何况如果使用 10、50、100 个磁盘来部署 RAID 磁盘阵列呢?

在VMware Workstation 17 中,虚拟机重启后系统盘可能会被错误识别,导致磁盘名称混乱。请务必确认/dev/sdb、/dev/sdc、/dev/sdd 和/dev/sde 为新添加的磁盘(可使用下面的命令进行确认),方可顺利完成实验。如果/dev/sda 不是首系统盘,请重启虚拟机系统。

root@linuxprobe:~# ls -l /dev/sd*
brw-rw----. 1 root disk 8, 0 Mar 17 21:15 /dev/sda
brw-rw----. 1 root disk 8, 1 Mar 17 21:15 /dev/sda1
brw-rw----. 1 root disk 8, 2 Mar 17 21:15 /dev/sda2
brw-rw----. 1 root disk 8, 3 Mar 17 21:15 /dev/sda3
brw-rw----. 1 root disk 8, 16 Mar 17 21:15 /dev/sdb
brw-rw----. 1 root disk 8, 32 Mar 17 21:15 /dev/sdc
brw-rw----. 1 root disk 8, 48 Mar 17 21:15 /dev/sdd
brw-rw----. 1 root disk 8, 64 Mar 17 21:15 /dev/sde

此时,就需要使用 mdadm 中的参数了。其中,-C 参数表示创建一个RAID 阵列;-v 参数显示创建的过程,同时在后面追加一个设备名称/dev/md0,这样/dev/md0 就是创建后的 RAID 磁盘阵列的名称;-n 4 参数表示使用 4 块磁盘来部署这个RAID 磁盘阵列;而-l 10 参数则表示 RAID 10 方案;最后再加上 4 块磁盘设备的名称就搞定了。

root@linuxprobe:~# mdadm -Cv /dev/md0 -n 4 -l 10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to n2
mdadm: layout defaults to n2
mdadm: chunk size defaults to 512K
mdadm: size set to 20954112K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

初始化过程大约需要 1min,其间可以用-D 参数进行查看。也可以用-Q 参数查看简要信息:

root@linuxprobe:~# mdadm -Q /dev/md0
/dev/md0: 39.97GiB raid10 4 devices, 0 spares. Use mdadm --detail for more detail.

同学们可能会好奇,为什么 4 块 20GB 大小的磁盘组成的磁盘阵列组,可用空间只有39.97GB 呢?

这里不得不提到 RAID 10 技术的原理。它通过两两一组磁盘组成的 RAID 1 磁盘阵列保证了数据的可靠性,其中每一份数据都会被保存两次,因此导致磁盘存在 50%的使用率和 50%的冗余率。这样一来,80GB 的磁盘容量也就只有一半了。

等两三分钟后,把制作好的RAID 磁盘阵列格式化为 Ext4 格式:

root@linuxprobe:~# mkfs.ext4 /dev/md0
mke2fs 1.47.1 (20-May-2024)
Creating filesystem with 10477056 4k blocks and 2621440 inodes
Filesystem UUID: 3bec5133-ecb1-4102-a10e-5c22208a76a1
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done

随后,创建挂载点,将磁盘设备进行挂载操作:

root@linuxprobe:~# mkdir /RAID
root@linuxprobe:~# mount /dev/md0 /RAID
root@linuxprobe:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 3.7G 13G 23% /
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 84K 1.9G 1% /dev/shm
efivarfs 256K 56K 196K 23% /sys/firmware/efi/efivars
tmpfs 776M 9.7M 767M 2% /run
tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
/dev/sr0 6.5G 6.5G 0 100% /media/cdrom
/dev/sda2 960M 272M 689M 29% /boot
/dev/sda1 599M 8.3M 591M 2% /boot/efi
tmpfs 388M 128K 388M 1% /run/user/0
/dev/md0 40G 24K 38G 1% /RAID

再来查看/dev/md0 磁盘阵列设备的详细信息,确认RAID 级别(Raid Level)、阵列大小(Array Size)和总磁盘数(Total Devices)都是否正确:

root@linuxprobe:~# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Mar 17 21:56:00 2025
Raid Level : raid10
Array Size : 41908224 (39.97 GiB 42.91 GB)
Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Mon Mar 17 22:02:18 2025
State : clean
Active Devices : 4
Working Devices : 4
Failed Devices : 0
Spare Devices : 0

Layout : near=2
Chunk Size : 512K

Consistency Policy : resync

Name : linuxprobe.com:0 (local to host linuxprobe.com)
UUID : 568d1322:33f4dd42:78d1f692:5ded8f34
Events : 17

Number Major Minor RaidDevice State
0 8 16 0 active sync set-A /dev/sdb
1 8 32 1 active sync set-B /dev/sdc
2 8 48 2 active sync set-A /dev/sdd
3 8 64 3 active sync set-B /dev/sde

如果想让创建好的 RAID 磁盘阵列能够一直提供服务,不会因每次的重启操作而取消, 那么一定要记得将信息添加到/etc/fstab 文件中,这样可以确保在每次重启后 RAID 磁盘阵列都是有效的。

root@linuxprobe:~# echo "/dev/md0 /RAID ext4 defaults 0 0" >> /etc/fstab
root@linuxprobe:~# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Mar 12 19:35:26 2025
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=408f4a3d-a4d3-4a44-bb23-6988cdbd10bf / xfs defaults 0 0
UUID=4cf8ecae-bcb6-4b1e-8001-968b33643a8a /boot xfs defaults 0 0
UUID=1FB8-9199 /boot/efi vfat umask=0077,shortname=winnt 0 2
UUID=d936c726-45a7-4ca2-8932-c54f84a3d787 none swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/md0 /RAID ext4 defaults 0 0

7.1.2 损坏磁盘阵列及修复

之所以在生产环境中部署 RAID 10 磁盘阵列,就是为了提高存储设备的 IO 速率及数据的安全性,但因为我们的磁盘设备是在虚拟机中模拟出来的,所以对于 IO 速率的改善可能并不直观。下面决定给同学们讲解一下 RAID 磁盘阵列损坏后的处理方法,以确保大家在步入运维岗位后不会因为磁盘阵列损坏而手忙脚乱。

在确认有一块物理磁盘设备出现损坏而不能再继续正常使用后,应该使用 mdadm 命令将其移除,然后查看 RAID 磁盘阵列的状态。可以发现状态已经改变:

root@linuxprobe:~# mdadm /dev/md0 -f /dev/sdb
mdadm: set /dev/sdb faulty in /dev/md0
root@linuxprobe:~# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Mar 17 21:56:00 2025
Raid Level : raid10
Array Size : 41908224 (39.97 GiB 42.91 GB)
Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Mon Mar 17 22:15:25 2025
State : clean, degraded
Active Devices : 3
Working Devices : 3
Failed Devices : 1
Spare Devices : 0

Layout : near=2
Chunk Size : 512K

Consistency Policy : resync

Name : linuxprobe.com:0 (local to host linuxprobe.com)
UUID : 568d1322:33f4dd42:78d1f692:5ded8f34
Events : 19

Number Major Minor RaidDevice State
- 0 0 0 removed
1 8 32 1 active sync set-B /dev/sdc
2 8 48 2 active sync set-A /dev/sdd
3 8 64 3 active sync set-B /dev/sde

0 8 16 - faulty /dev/sdb

刚刚使用的-f 参数是让磁盘模拟损坏的效果。为了能够彻底地将故障盘移除,还要再执行一步操作:

root@linuxprobe:~# mdadm /dev/md0 -r /dev/sdb
mdadm: hot removed /dev/sdb from /dev/md0

在RAID 10 级别的磁盘阵列中,当 RAID 1 磁盘阵列中存在一个故障盘时并不影响 RAID 10 磁盘阵列的使用。当购买了新的磁盘设备后再使用 mdadm 命令予以替换即可,在此期间可以在/RAID 目录中正常地创建或删除文件。由于我们是在虚拟机中模拟磁盘,所以先重启系统,然后再把新的磁盘添加到 RAID 磁盘阵列中。

更换磁盘后再次使用-a 参数进行添加操作,系统默认会自动开始数据的同步工作。使用-D 参数即可看到整个过程和进度(用百分比表示):

root@linuxprobe:~# mdadm /dev/md0 -a /dev/sdb
mdadm: added /dev/sdb
root@linuxprobe:~# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Mar 17 21:56:00 2025
Raid Level : raid10
Array Size : 41908224 (39.97 GiB 42.91 GB)
Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Mon Mar 17 22:16:27 2025
State : clean, degraded, recovering
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1

Layout : near=2
Chunk Size : 512K

Consistency Policy : resync

Rebuild Status : 29% complete

Name : linuxprobe.com:0 (local to host linuxprobe.com)
UUID : 568d1322:33f4dd42:78d1f692:5ded8f34
Events : 26

Number Major Minor RaidDevice State
4 8 16 0 spare rebuilding /dev/sdb
1 8 32 1 active sync set-B /dev/sdc
2 8 48 2 active sync set-A /dev/sdd
3 8 64 3 active sync set-B /dev/sde

这时可能会有同学举手提问了:“老师,我们公司机房的阵列卡上有 30 多块磁盘呢,就算知道/dev/sdb 磁盘发生了故障,我也不知道该替换哪一块啊,要是错拔了好设备那就麻烦了。”其实不用担心,因为一旦磁盘发生故障,服务器上相应的指示灯会变成红灯(或者变成一直闪烁的黄灯),如图 7-6 所示。

图7-6 磁盘阵列信号灯

7.1.3 磁盘阵列+备份盘

RAID 10 磁盘阵列中最多允许 50%的磁盘设备发生故障,但是存在这样一种极端情况, 即同一 RAID 1 磁盘阵列中的磁盘设备若全部损坏,也会导致数据丢失。换句话说,在 RAID 10 磁盘阵列中,如果 RAID 1 中的某一块磁盘出现了故障,而我们在前往修复的路途中, 恰巧该 RAID 1 磁盘阵列中的另一块磁盘设备也出现故障,那么数据就彻底丢失了。刘遄老师可真不是乌鸦嘴,这种 RAID 1 磁盘阵列中的磁盘设备同时损坏的情况还真被我的学生遇到过。

在这样的情况下,该怎么办呢?其实,完全可以使用 RAID 备份盘技术来预防这类事故。该技术的核心理念就是准备一块足够大的磁盘,这块磁盘平时处于闲置状态,一旦 RAID 磁盘阵列中有磁盘出现故障,则会马上自动顶替上去。这样很棒吧!

为了避免多个实验之间相互发生冲突,我们需要保证每个实验的相对独立性,为此需要大家自行将虚拟机还原到最初始的状态。另外,由于刚才已经演示了 RAID 10 磁盘阵列的部署方法,现在来看一下RAID 5 的部署效果。部署RAID 5 磁盘阵列时,至少需要用到 3 块磁盘,还需要再加一块备份盘(也叫热备盘),所以总计需要在虚拟机中模拟 4 块磁盘设备,如图 7-7 所示。

图7-7 重置虚拟机后,再添加四块硬盘设备

现在创建一个 RAID 5 磁盘阵列+备份盘。在下面的命令中,参数-n 3 表示创建这个 RAID 5 磁盘阵列所需的磁盘数,参数-l 5 表示 RAID 的级别,而参数-x 1 则表示有一块备份盘。当查看/dev/md0(即 RAID 5 磁盘阵列的名称)磁盘阵列时,就能看到有一块备份盘在等待中了。

root@linuxprobe:~# mdadm -Cv /dev/md0 -n 3 -l 5 -x 1 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 512K
mdadm: size set to 20954112K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
root@linuxprobe:~# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Mar 17 22:22:57 2025
Raid Level : raid5
Array Size : 41908224 (39.97 GiB 42.91 GB)
Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
Raid Devices : 3
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Mon Mar 17 22:24:43 2025
State : clean
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1

Layout : left-symmetric
Chunk Size : 512K

Consistency Policy : resync

Name : linuxprobe.com:0 (local to host linuxprobe.com)
UUID : ae39f666:bae02cb8:45ba71d7:51223d5d
Events : 18

Number Major Minor RaidDevice State
0 8 16 0 active sync /dev/sdb
1 8 32 1 active sync /dev/sdc
4 8 48 2 active sync /dev/sdd

3 8 64 - spare /dev/sde

现在将部署好的 RAID 5 磁盘阵列格式化为Ext4 文件格式,然后挂载到目录上,之后就能使用了:

root@linuxprobe:~# mkfs.ext4 /dev/md0
mke2fs 1.47.1 (20-May-2024)
Creating filesystem with 10477056 4k blocks and 2621440 inodes
Filesystem UUID: 9c111651-c594-4458-96ec-364d27d28ec9
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done
root@linuxprobe:~# mkdir /RAID
root@linuxprobe:~# echo "/dev/md0 /RAID ext4 defaults 0 0" >> /etc/fstab

RHEL 10 系统的/etc/fstab 文件修改后,不能直接使用 mount -a 命令进行自动挂载, 需要先同步给系统才行。

root@linuxprobe:~# systemctl daemon-reload
root@linuxprobe:~# mount -a

由 3 块容量均为 20GB 的磁盘组成的 RAID 5 磁盘阵列,其可用空间为(n - 1)× 个磁盘容量,即(3 - 1)×20GB = 40GB。热备盘的空间不计算进来,它平时就是在“睡觉”,只有在意外出现时才会开始工作。

root@linuxprobe:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 3.7G 13G 23% /
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 84K 1.9G 1% /dev/shm
efivarfs 256K 56K 196K 23% /sys/firmware/efi/efivars
tmpfs 776M 9.7M 767M 2% /run
tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
/dev/sda2 960M 272M 689M 29% /boot
/dev/sr0 6.5G 6.5G 0 100% /media/cdrom
/dev/sda1 599M 8.3M 591M 2% /boot/efi
tmpfs 388M 124K 388M 1% /run/user/0
/dev/md0 40G 24K 38G 1% /RAID

最后是见证奇迹的时刻!我们再次把磁盘设备/dev/sdb 移出磁盘阵列,然后迅速查看

/dev/md0 磁盘阵列的状态,可以看到备份盘已经自动顶替上去并开始了数据同步。RAID 中的这种备份盘技术非常实用,可以在保证 RAID 磁盘阵列数据安全性的基础上进一步提高数据可靠性。所以,如果公司不差钱的话,还是买上一块备份盘以防万一吧。

root@linuxprobe:~# mdadm /dev/md0 -f /dev/sdb
mdadm: set /dev/sdb faulty in /dev/md0
root@linuxprobe:~# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Mar 17 22:22:57 2025
Raid Level : raid5
Array Size : 41908224 (39.97 GiB 42.91 GB)
Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
Raid Devices : 3
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Mon Mar 17 22:32:18 2025
State : clean
Active Devices : 3
Working Devices : 3
Failed Devices : 1
Spare Devices : 0

Layout : left-symmetric
Chunk Size : 512K

Consistency Policy : resync

Name : linuxprobe.com:0 (local to host linuxprobe.com)
UUID : ae39f666:bae02cb8:45ba71d7:51223d5d
Events : 37

Number Major Minor RaidDevice State
3 8 64 0 active sync /dev/sde
1 8 32 1 active sync /dev/sdc
4 8 48 2 active sync /dev/sdd

0 8 16 - faulty /dev/sdb

是不是感觉很有意思呢?考虑到篇幅限制,我们一直没有复制、粘贴/RAID 目录中文件的信息,有兴趣的同学可以自己动手试一下。里面的文件内容非常安全,不会出现丢失的情况。如果后面想再添加一块热备盘进来,使用-a 参数就可以了。

7.1.4 删除磁盘阵列

在生产环境中,RAID 磁盘阵列部署后一般不会被轻易停用。但万一赶上了,还是要知道怎么将磁盘阵列删除。前面那种 RAID 5+热备盘损坏的情况比较复杂,所以以这种情况为例进行讲解是再好不过了。

首先,将 RAID 磁盘阵列卸载并停止:

root@linuxprobe:~# umount /dev/md0
umount: /dev/md0: not mounted.
root@linuxprobe:~# mdadm -S /dev/md0
mdadm: stopped /dev/md0

由于各个成员盘中还保存有数据,如果有居心不良的黑客此时重新使用它们创建 RAID, 则就有可能将数据恢复出来。保险起见,先向这些原先的成员盘中填充全零的数据块,确保将残留数据全部覆盖掉:

root@linuxprobe:~# mdadm --zero-superblock /dev/sdb
root@linuxprobe:~# mdadm --zero-superblock /dev/sdc
root@linuxprobe:~# mdadm --zero-superblock /dev/sdd
root@linuxprobe:~# mdadm --zero-superblock /dev/sde

然后,就看不到任何跟/dev/md0 设备相关的信息了:

root@linuxprobe:~# mdadm -D /dev/md0
mdadm: cannot open /dev/md0: No such file or directory
root@linuxprobe:~# ls -l /dev/md0
ls: cannot access '/dev/md0': No such file or directory

最后,删除/etc/fstab 文件中的挂载信息,大功告成!

root@linuxprobe:~# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Mar 12 19:35:26 2025
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=408f4a3d-a4d3-4a44-bb23-6988cdbd10bf / xfs defaults 0 0
UUID=4cf8ecae-bcb6-4b1e-8001-968b33643a8a /boot xfs defaults 0 0
UUID=1FB8-9199 /boot/efi vfat umask=0077,shortname=winnt 0 2
UUID=d936c726-45a7-4ca2-8932-c54f84a3d787 none swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0

7.2 LVM

前面学习的磁盘设备管理技术虽然能够有效地提高磁盘设备的 IO 速率以及数据的安全性,但是在磁盘分好区或者部署为 RAID 磁盘阵列之后,再想修改磁盘分区大小就不容易了。换句话说,当用户想要随着实际需求的变化调整磁盘分区的大小时,会受到磁盘“灵活性” 的限制。这时就需要用到另外一项非常普及的磁盘设备资源管理技术了—逻辑卷管理器(Logical Volume Manager,LVM)。LVM 允许用户对磁盘资源进行动态调整。

LVM 是Linux 系统用于对磁盘分区进行管理的一种机制,理论性较强,其创建初衷是解决磁盘设备在创建分区后不易修改分区大小的缺陷。尽管对传统的磁盘分区进行强制扩容或缩容从理论上来讲是可行的,但是却可能造成数据的丢失。而 LVM 技术是在磁盘分区和文件系统之间添加了一个逻辑层,它提供了一个抽象的卷组,可以把多块磁盘进行卷组合并。这样一来,用户不必关心物理磁盘设备的底层架构和布局,就能够实现对磁盘分区的动态调整。LVM 的技术架构如图 7-8 所示。

图7-8 逻辑卷管理器的技术结构

为了帮助大家理解,我们来看一个“吃货”的例子。比如小明家想吃馒头,但是面粉不够了,于是妈妈从隔壁老王家、老李家、老张家分别借来一些面粉,准备蒸馒头吃。首先需要把这些面粉(物理卷[Physical Volume,PV])揉成一个大面团(卷组[Volume Group],VG),然后再把这个大面团分割成一个个小馒头(逻辑卷[Logical Volume,LV]),而且每个小馒头的重量必须是每勺面粉(基本单元[Physical Extent,PE])的倍数。

在日常的使用中,如果卷组(VG)的剩余容量不足,可以随时将新的物理卷(PV)加入到里面,不断地扩容。由于担心同学们还是不理解,这里准备了一张逻辑卷管理器的使用流程示意图,如图 7-9 所示。

图7-9 逻辑卷管理器使用流程图

物理卷处于 LVM 中的最底层,可以将其理解为物理磁盘、磁盘分区或者 RAID 磁盘阵列。卷组建立在物理卷之上,一个卷组能够包含多个物理卷,而且在卷组创建之后也可以继续向其中添加新的物理卷。逻辑卷是用卷组中空闲的资源建立的,并且逻辑卷在建立后能够动态地扩展或缩小空间。这就是 LVM 的核心理念。

7.2.1 部署逻辑卷

一般而言,在生产环境中,很难在初始阶段就能精确预估每个磁盘分区在后续的使用需求,因此经常会出现分区容量不够使用的情况。比如,伴随着业务量的增加,用于存放交易记录的数据库目录的体积也随之增加;因为分析并记录用户的行为从而导致日志目录的体积不断变大,这些都会导致原有的磁盘分区在使用上捉襟见肘。此外,还存在对较大的磁盘分区进行精简缩容的情况。

我们可以通过部署 LVM 来解决上述问题。在部署时,需要逐个配置物理卷、卷组和逻辑卷,常用的部署命令如表 7-3 所示。

表 7-3 常用的 LVM 部署命令

功能/命令物理卷管理卷组管理逻辑卷管理
扫描pvscanvgscanlvscan
建立pvcreatevgcreatelvcreate
显示pvdisplayvgdisplaylvdisplay
删除pvremovevgremovelvremove
扩展vgextendlvextend
缩小vgreducelvreduce

为了避免多个实验之间相互发生冲突,请大家自行将虚拟机还原到初始状态,并重新添加两块新磁盘设备,如图 7-10 所示。然后开机。

图7-10 在虚拟机中添加两块新的硬盘设备

在虚拟机中添加两块新磁盘设备,是为了更好地演示 LVM 理念中用户无须关心底层物理磁盘设备的特性。我们先对这两块新磁盘进行创建物理卷的操作,可以将该操作简单理解为让磁盘设备支持 LVM 技术,或者理解为将磁盘设备加入 LVM 能够管理和使用的硬件资源池内,然后对这两块磁盘进行卷组合并,卷组的名称允许用户自定义。接下来,根据需求把合并后的卷组切割出一个约为 150MB 的逻辑卷设备,最后把这个逻辑卷设备格式化为 Ext4 文件系统后挂载使用。下文将对每一个步骤进行简单的描述。

第 1 步:让新添加的两块磁盘设备支持 LVM 技术。

root@linuxprobe:~# pvcreate /dev/sdb /dev/sdc
Physical volume "/dev/sdb" successfully created.
Physical volume "/dev/sdc" successfully created.

第 2 步:把两块磁盘设备加入 storage 卷组,然后查看卷组的状态。

root@linuxprobe:~# vgcreate storage /dev/sdb /dev/sdc
Volume group "storage" successfully created
root@linuxprobe:~# vgdisplay
--- Volume group ---
VG Name storage
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 39.99 GiB
PE Size 4.00 MiB
Total PE 10238
Alloc PE / Size 0 / 0
Free PE / Size 10238 / 39.99 GiB
VG UUID M9xB4b-sydm-G6tZ-K00e-RO45-iqL2-4bRlw1
………………省略部分输出信息………………

第 3 步:切割出一个约为 150MB 的逻辑卷设备。

这里需要注意切割单位的问题。在对逻辑卷进行切割时有两种计量单位。第一种是以容量为单位,使用的参数为-L。例如,使用-L 150M 生成一个大小为 150MB 的逻辑卷。另外一种是以基本单元的个数为单位,使用的参数为-l。每个基本单元的大小默认为 4MB。例如, 使用-l 37 可以生成一个大小为 37×4MB=148MB 的逻辑卷。

root@linuxprobe:~# lvcreate -n vo -l 37 storage
Logical volume "vo" created.
root@linuxprobe:~# lvdisplay
--- Logical volume ---
LV Path /dev/storage/vo
LV Name vo
VG Name storage
LV UUID 9Tuv9a-FjmN-Cbye-CqC6-709V-zJMh-MQ9iIr
LV Write Access read/write
LV Creation host, time linuxprobe.com, 2025-03-18 01:15:48 +0800
LV Status available
# open 0
LV Size 148.00 MiB
Current LE 37
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
………………省略部分输出信息………………

第 4 步:把生成的逻辑卷进行格式化,然后挂载使用。

Linux 系统会把 LVM 中的逻辑卷设备存放在/dev 设备目录中(实际上就是个快捷方式),同时会以卷组的名称来建立一个目录,其中保存了逻辑卷的设备映射文件(即/dev/卷组名称/逻辑卷名称)。

root@linuxprobe:~# mkfs.ext4 /dev/storage/vo 
mke2fs 1.47.1 (20-May-2024)
Creating filesystem with 151552 1k blocks and 37848 inodes
Filesystem UUID: c5b6efaf-0b25-4ad2-81ac-afb8bc0c99a9
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

root@linuxprobe:~# mkdir /linuxprobe
root@linuxprobe:~# mount /dev/storage/vo /linuxprobe

对了,如果使用了逻辑卷管理器,则不建议使用 XFS 文件系统,因为 XFS 文件系统自身就可以使用 xfs_growfs 命令进行磁盘扩容。这虽然没有 LVM 灵活,但起码也够用。我们在实测阶段发现,在有一些服务器上,XFS 与 LVM 的兼容性并不好。

第 5 步:查看挂载状态,并写入配置文件,使其永久生效。

root@linuxprobe:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 3.7G 13G 23% /
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 84K 1.9G 1% /dev/shm
efivarfs 256K 56K 196K 23% /sys/firmware/efi/efivars
tmpfs 776M 9.7M 767M 2% /run
tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
/dev/sda2 960M 272M 689M 29% /boot
/dev/sr0 6.5G 6.5G 0 100% /media/cdrom
/dev/sda1 599M 8.3M 591M 2% /boot/efi
tmpfs 388M 124K 388M 1% /run/user/0
/dev/mapper/storage-vo 134M 14K 123M 1% /linuxprobe
root@linuxprobe:~# echo "/dev/storage/vo /linuxprobe ext4 defaults 0 0" >> /etc/fstab
root@linuxprobe:~# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Mar 12 19:35:26 2025
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=408f4a3d-a4d3-4a44-bb23-6988cdbd10bf / xfs defaults 0 0
UUID=4cf8ecae-bcb6-4b1e-8001-968b33643a8a /boot xfs defaults 0 0
UUID=1FB8-9199 /boot/efi vfat umask=0077,shortname=winnt 0 2
UUID=d936c726-45a7-4ca2-8932-c54f84a3d787 none swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/storage/vo /linuxprobe ext4 defaults 0 0

Tips :

细心的同学应该又发现了一个小问题:刚才明明写的是148MB,怎么这里只有140MB 了呢? 这是因为硬件厂商在标识容量时,采用的换算标准是 1GB=1000MB、1MB=1000KB、1KB= 1000B;而计算机系统在识别和计算存储容量时,遵循的是二进制算法,即 1GB= 1024MB、

1MB=1024KB、1KB=1024B,因此有 3%左右的“缩水”是正常情况。

7.2.2 扩容逻辑卷

在前面的实验中,卷组是由两块磁盘设备共同组成的。用户在使用存储设备时感知不到设备底层的架构和布局,更不用关心底层是由多少块磁盘组成的,只要卷组中有足够的资源, 就可以一直为逻辑卷扩容。扩容前请一定要记得卸载设备和挂载点之间的关联。

root@linuxprobe:~# umount /linuxprobe

第 1 步:把上一个实验中的逻辑卷vo 扩展至 290MB。

root@linuxprobe:~# lvextend -L 290M /dev/storage/vo
Rounding size to boundary between physical extents: 292.00 MiB.
Size of logical volume storage/vo changed from 148.00 MiB (37 extents) to 292.00 MiB (73 extents).
Logical volume storage/vo successfully resized.

第 2 步:检查磁盘的完整性,确认目录结构、内容和文件内容没有丢失。一般情况下没有报错,表示运行正常。

root@linuxprobe:~# e2fsck -f /dev/storage/vo
e2fsck 1.47.1 (20-May-2024)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/37848 files (0.0% non-contiguous), 15165/151552 blocks

第 3 步:重置设备在系统中的容量。刚刚是对 LV(逻辑卷)设备进行了扩容操作,但系统内核还没有同步到这部分新修改的信息,需要手动进行同步。****

root@linuxprobe:~# resize2fs /dev/storage/vo
resize2fs 1.47.1 (20-May-2024)
Resizing the filesystem on /dev/storage/vo to 299008 (1k) blocks.
The filesystem on /dev/storage/vo is now 299008 (1k) blocks long.

第 4 步:重新挂载磁盘设备并查看挂载状态。

root@linuxprobe:~# systemctl daemon-reload
root@linuxprobe:~# mount -a
root@linuxprobe:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 3.7G 13G 23% /
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 84K 1.9G 1% /dev/shm
efivarfs 256K 56K 196K 23% /sys/firmware/efi/efivars
tmpfs 776M 9.7M 767M 2% /run
tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
/dev/sda2 960M 272M 689M 29% /boot
/dev/sr0 6.5G 6.5G 0 100% /media/cdrom
/dev/sda1 599M 8.3M 591M 2% /boot/efi
tmpfs 388M 124K 388M 1% /run/user/0
/dev/mapper/storage-vo 268M 14K 250M 1% /linuxprobe

7.2.3 缩小逻辑卷

相较于扩容逻辑卷,在对逻辑卷进行缩容操作时,数据丢失的风险更大。所以在生产环境中执行相应操作时,一定要提前备份好数据。另外,Linux 系统规定,在对 LVM 逻辑卷进行缩容操作之前,要先检查文件系统的完整性(当然这也是为了保证数据的安全)。在执行缩容操作前记得先把文件系统卸载掉。

root@linuxprobe:~# umount /linuxprobe

第 1 步:检查文件系统的完整性。

root@linuxprobe:~# e2fsck -f /dev/storage/vo
e2fsck 1.47.1 (20-May-2024)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/73704 files (0.0% non-contiguous), 24683/299008 blocks

第 2 步:通知系统内核将逻辑卷 vo 的容量减小到 120MB。

root@linuxprobe:~# resize2fs /dev/storage/vo 120M
resize2fs 1.47.1 (20-May-2024)
Resizing the filesystem on /dev/storage/vo to 122880 (1k) blocks.
The filesystem on /dev/storage/vo is now 122880 (1k) blocks long.

咦?缩容的步骤跟扩容的步骤不一样啊。缩容操作为什么是先通知系统内核设备的容量要改变成 120MB,然后再正式进行缩容操作呢?举个例子大家就明白了。小强是一名初中生,开学后看到班里有位同学文了身,他感觉很酷,自己也想文身但又怕被家里责骂,于是他回家后就说:“妈妈,我文身了。”如果妈妈的反应很平和,那么他就可以放心大胆地去文身了。如果妈妈强烈不同意,他马上就哈哈一笑:“逗你玩呢。”这样他就不会挨打了。

缩容操作也是同样的道理,先通知系统内核自己想缩小逻辑卷,如果在执行 resize2fs

命令后系统没有报错,再正式操作。

第 3 步:将 LV 逻辑卷的容量修改为 120MB。

root@linuxprobe:~# lvreduce -L 120M /dev/storage/vo
File system ext4 found on storage/vo.
File system size (120.00 MiB) is equal to the requested size (120.00 MiB).
File system reduce is not needed, skipping.
Size of logical volume storage/vo changed from 292.00 MiB (73 extents) to 120.00 MiB (30 extents).
Logical volume storage/vo successfully resized.

使用lvreduce 命令正式缩小文件系统容量时,大小一定要跟之前申报的保持一致,说好的是 120MB,差 1MB、1KB,甚至差 1B 都不行。小明好不容易说服妈妈同意纹一只小猫咪了,结果纹了只下山虎,那最后还是免不了挨一顿打(缩容失败)。

第 4 步:重新挂载文件系统并查看系统状态。

root@linuxprobe:~# mount -a
root@linuxprobe:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 17G 3.7G 13G 23% /
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 84K 1.9G 1% /dev/shm
efivarfs 256K 56K 196K 23% /sys/firmware/efi/efivars
tmpfs 776M 9.7M 767M 2% /run
tmpfs 1.0M 0 1.0M 0% /run/credentials/systemd-journald.service
/dev/sda2 960M 272M 689M 29% /boot
/dev/sr0 6.5G 6.5G 0 100% /media/cdrom
/dev/sda1 599M 8.3M 591M 2% /boot/efi
tmpfs 388M 124K 388M 1% /run/user/0
/dev/mapper/storage-vo 108M 14K 99M 1% /linuxprobe

7.2.4 逻辑卷快照

LVM 还具备有“逻辑卷快照”功能,该功能类似于虚拟机软件的还原时间点功能。例如, 对某一个逻辑卷设备做一次快照,如果日后发现数据被改错了,就可以利用之前做好的逻辑卷快照进行覆盖还原。LVM 的逻辑卷快照功能有两个特点:

逻辑卷快照的容量必须等同于逻辑卷的容量;

逻辑卷快照仅一次有效,一旦执行还原操作后则会被立即自动删除。

在正式操作前,先看看VG(卷组)中的容量是否够用:

root@linuxprobe:~# vgdisplay
--- Volume group ---
VG Name storage
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 2
Act PV 2
VG Size 39.99 GiB
PE Size 4.00 MiB
Total PE 10238
Alloc PE / Size 30 / 120.00 MiB
Free PE / Size 10208 / <39.88 GiB
VG UUID M9xB4b-sydm-G6tZ-K00e-RO45-iqL2-4bRlw1
………………省略部分输出信息………………

通过卷组的输出信息可以清晰看到,卷组中已经使用了 120MB 的容量,空闲容量还有39.88GB。接下来用重定向往逻辑卷设备挂载的目录中写入一个文件。

root@linuxprobe:~# echo "Welcome to Linuxprobe.com" > /linuxprobe/readme.txt
root@linuxprobe:~# ls -l /linuxprobe
total 13
drwx------. 2 root root 12288 Mar 18 01:16 lost+found
-rw-r--r--. 1 root root 26 Mar 18 01:43 readme.txt

第 1 步:使用-s 参数生成一个逻辑卷快照,使用-L 参数指定切割的大小,需要与要做快照的设备容量保持一致。另外,还需要在命令后面写上是针对哪个逻辑卷执行的快照操作, 稍后数据也会还原到这个相应的设备上。

root@linuxprobe:~# lvcreate -L 120M -s -n SNAP /dev/storage/vo
Logical volume "SNAP" created.
root@linuxprobe:~# lvdisplay
--- Logical volume ---
LV Path /dev/storage/SNAP
LV Name SNAP
VG Name storage
LV UUID XsCyvN-NiXP-M6tD-CfXk-TCQU-PSbQ-eYHaV2
LV Write Access read/write
LV Creation host, time linuxprobe.com, 2025-03-18 01:43:57 +0800
LV snapshot status active destination for vo
LV Status available
# open 0
LV Size 120.00 MiB
Current LE 30
COW-table size 120.00 MiB
COW-table LE 30
Allocated to snapshot 0.01%
Snapshot chunk size 4.00 KiB
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:5
………………省略部分输出信息………………

第 2 步:在逻辑卷挂载的目录中创建一个 100MB 的垃圾文件,然后再查看逻辑卷快照的状态。可以发现存储空间的占用量上升了。

root@linuxprobe:~# dd if=/dev/zero of=/linuxprobe/files count=1 bs=100M
1+0 records in
1+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.461243 s, 227 MB/s
root@linuxprobe:~# lvdisplay
--- Logical volume ---
LV Path /dev/storage/SNAP
LV Name SNAP
VG Name storage
LV UUID XsCyvN-NiXP-M6tD-CfXk-TCQU-PSbQ-eYHaV2
LV Write Access read/write
LV Creation host, time linuxprobe.com, 2025-03-18 01:43:57 +0800
LV snapshot status active destination for vo
LV Status available
# open 0
LV Size 120.00 MiB
Current LE 30
COW-table size 120.00 MiB
COW-table LE 30
Allocated to snapshot 67.28%
Snapshot chunk size 4.00 KiB
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:5
………………省略部分输出信息………………

第 3 步:为了校验逻辑卷快照的效果,需要对逻辑卷进行快照还原操作。在此之前记得先卸载掉逻辑卷设备与目录的挂载。

lvconvert 命令用于管理逻辑卷快照,语法格式为“lvconvert [参数] 逻辑卷快照名称”。使用lvconvert 命令能自动恢复逻辑卷快照,在早期的 RHEL/CentOS 5 版本中要写全

格式:--mergesnapshot,而从 RHEL 6 一直到 RHEL 10,已经允许用户只输入--merge

参数进行操作了,系统会自动分辨设备的类型。

root@linuxprobe:~# umount /linuxprobe
root@linuxprobe:~# lvconvert --merge /dev/storage/SNAP
Merging of volume storage/SNAP started.
storage/vo: Merged: 100.00%

第 4 步:逻辑卷快照会被自动删除掉,并且刚才在对逻辑卷设备执行快照操作后创建出来的 100MB 的垃圾文件也被清除了。

root@linuxprobe:~# mount -a
root@linuxprobe:~# cd /linuxprobe
root@linuxprobe:/linuxprobe# ls
lost+found readme.txt
root@linuxprobe:/linuxprobe# cat readme.txt
Welcome to Linuxprobe.com

7.2.5 删除逻辑卷

当生产环境中想要重新部署 LVM 或者不再需要使用 LVM 时,则需要执行 LVM 的删除操作。为此,需要提前备份好重要的数据信息,然后依次删除逻辑卷、卷组、物理卷设备, 这个顺序不可颠倒。

第 1 步:取消逻辑卷与目录的挂载关联,删除配置文件中永久生效的设备参数。

root@linuxprobe:/linuxprobe# cd ~
root@linuxprobe:~# umount /linuxprobe
root@linuxprobe:~# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Jul 21 05:03:40 2020
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel-root / xfs defaults 0 0
UUID=2db66eb4-d9c1-4522-8fab-ac074cd3ea0b /boot xfs defaults 0 0
/dev/mapper/rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0

第 2 步:删除逻辑卷设备,需要输入 y 来确认操作。

root@linuxprobe:~# lvremove /dev/storage/vo 
Do you really want to remove active logical volume storage/vo? [y/n]: y
Logical volume "vo" successfully removed.

第 3 步:删除卷组,此处只写卷组名称即可,不需要设备的绝对路径。

root@linuxprobe:~# vgremove storage
Volume group "storage" successfully removed

第 4 步:删除物理卷设备。

root@linuxprobe:~# pvremove /dev/sdb /dev/sdc
Labels on physical volume "/dev/sdb" successfully wiped.
Labels on physical volume "/dev/sdc" successfully wiped.

在上述操作执行完毕之后,再执行 lvdisplay、vgdisplay、pvdisplay 命令查看LVM 的信息时,就不会再看到相关信息了(前提是上述步骤的操作是正确的)。干净利落!

复习题

  1. RAID 技术主要是为了解决什么问题?

    答:RAID 技术主要是解决存储设备的 IO 速率问题及数据的冗余备份问题。

  2. RAID 0 和RAID 5 哪个更安全?

    答:RAID 0 没有数据冗余功能,因此 RAID 5 更安全。

  3. 假设使用4 块磁盘来部署 RAID 10 方案,外加一块备份盘,最多允许几块磁盘同时损坏呢?

    答:最多允许 5 块磁盘设备中的 3 块设备同时损坏。

  4. RAID 0 加热备盘的方案可行吗?

    答:坚决不可行,因为RAID 0 中任何一块数据盘损坏后,数据均永久丢失,没有恢复的机会。

  5. 位于 LVM 最底层的是物理卷还是卷组?

    答:位于最底层的是物理卷,然后再通过物理卷组成卷组。

  6. LVM 对逻辑卷的扩容和缩容操作有何异同点呢?

    答:扩容和缩容操作都需要先取消逻辑卷与目录的挂载关联;扩容操作是先扩容后检查文件系统完整性,而缩容操作为了保证数据的安全,需要先检查文件系统完整性再缩容。

  7. LVM 的逻辑卷快照能使用几次?

    答:只可使用一次,而且使用后即自动删除。

  8. LVM 的删除顺序是怎么样的?

    答:依次移除逻辑卷、卷组和物理卷。

  9. LVM 也是由多块磁盘组成的,是否有冗余备份效果?

    答:不仅没有冗余备份效果,而且底层任何一块磁盘损坏,都会造成数据丢失。

  10. 能否同时使用 RAID 和 LVM?

    答:如果有需求,可以这样做,但记得要先创建RAID,然后在此基础上做 LVM。