在Linux中分区磁盘
1. 概述
在 Linux 中对磁盘进行分区通常是安装系统之前的第一步。在我们可以创建任何文件之前,文件系统必须存在。同样,除非磁盘上有分区,否则我们无法创建文件系统。
**分区用于将原始存储空间划分为块(片)。**这提供了组织和托管文件系统的方法。除此之外,分区还有助于隔离文件系统故障。
在本教程中,我们将讨论 Linux 中磁盘分区的工具和过程。首先,我们将简要讨论磁盘类型和引导模式。其次,我们将介绍分区示例,使用parted和 LVM 分区。最后,我们将总结讨论的主题。
2. 磁盘类型和工具
有关磁盘如何分区的信息存储在磁盘上。这通常称为分区表 。此表中的条目定义磁盘上的分区开始和结束的位置。此表的格式有时被视为磁盘类型。
2.1. MBR 和 GPT
MBR (主引导记录)和GPT (GUID 分区表)是使用最广泛的分区表。与 GPT 相比,MBR 是一个旧标准并且有一些限制。
**在具有 32 位条目的 MBR 方案中,我们只能拥有 2 TB 的最大磁盘大小。**此外,只允许四个主分区。但是,我们可以使用进一步划分为逻辑分区的扩展分区来克服这个限制。
除了分区条目,MBR 还包含一个写入驱动器初始扇区的引导加载程序。
然而,GPT 不包含引导加载程序,最多可以有 128 个分区(128 位条目)。因此,大多数现代计算机都预先配置了 GPT 磁盘。不过,GPT 确实支持 MBR 部分以实现向后兼容性。
2.2. BIOS 和 UEFI
BIOS (基本输入输出系统)是执行硬件初始化并从 MBR 加载引导加载程序的低级软件。BIOS 逐渐被UEFI (统一可扩展固件接口)取代。尽管如此,大多数新系统都支持两者。
**UEFI 不是从 MBR 加载引导加载程序,而是使用来自EFI System Partition的 efi映像。**使用 UEFI 和 GPT,我们可以获得大磁盘支持。
在某些 Linux 系统中,可以使用带有 GPT 磁盘的 BIOS 引导模式。
2.3. 分区工具
过去,要对 MBR 磁盘进行分区,使用fdisk 工具。但是,在新的 Linux 系统中,fdisk也可以理解 GPT 格式。
然而,在本文中,我们将重点关注parted 工具。parted 工具较新,可以同时理解 GPT 和 MBR 布局。此外,由于它在脚本和自动化方面的可用性,它也被认为是 Linux 中磁盘分区的更好选择。
3. 使用parted工具
我们将使用具有多个硬盘驱动器的系统。现在让我们启动一个终端并列出可用的硬盘:
$ lsblk -e7
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 99,5G 0 part /
sdb 8:16 0 976,6G 0 disk
sdc 8:32 0 3,8T 0 disk
我们使用带有选项*-e7*的lsblk 命令来排除循环设备(设备编号 7)。
在这个系统中,我们总共有三个磁盘。sda驱动器是具有三个分区的 Linux 系统驱动器。但是,驱动器sdb和sdc没有分区表。
3.1. 选择设备
由于sda是系统驱动器,我们将在分区示例中使用sdb和sdc。
现在让我们启动parted的程序并选择sdb驱动器:
# parted
GNU Parted 3.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)
在交互模式下,所有parted命令在*(parted)提示符下一次发出一个。请注意,parted默认使用/dev/sda*驱动器。
在提交任何分区更改之前,请始终检查是否选择了正确的驱动器:
(parted) select /dev/sdb
Using /dev/sdb
(parted)
**要更改目标设备,我们使用 select命令。**此外,我们还可以使用特定的设备启动parted的程序:
(parted) quit
# parted /dev/sdb
GNU Parted 3.3
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) q
#
正如我们所见,命令可以缩写。例如,可以使用q代替quit。
3.2. 获取分区信息
我们现在将看到,如何列出分区信息:
# parted /dev/sda
GNU Parted 3.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 107GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 538MB 537MB primary fat32 boot
2 539MB 107GB 107GB extended
5 539MB 107GB 107GB logical ext4
(parted)
在这里,我们使用了print命令来显示有关sda驱动器的信息。我们可以看到分区表是MBR( msdos ) 。此外,磁盘大小(默认情况下)以字节为单位报告。
现在让我们尝试一些其他单位:
# parted /dev/sda unit s print unit chs print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 1050623s 1048576s primary fat32 boot
2 1052670s 209713151s 208660482s extended
5 1052672s 209713151s 208660480s logical ext4
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 411206,69,1
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 411206,255,2. Each cylinder is 261kB.
Partition Table: msdos
Disk Flags:
Number Start End Type File system Flags
1 4,4,0 2060,11,1 primary fat32 boot
2 2064,15,0 411202,65,1 extended
5 2064,16,0 411202,65,1 logical ext4
使用unit命令,我们可以更改用于报告大小和开始/结束标记的单位。例如,我们现在使用了s (扇区)和chs(气缸盖扇区)。此外,我们可以在命令行模式下链接多个命令。
3.3. 创建分区
现在让我们看看如何使用parted工具进行磁盘分区:
# parted -s /dev/sdb mklabel gpt
# parted -s /dev/sdb mkpart primary fat32 0% 512MiB
# parted -s /dev/sdb mkpart primary linux-swap 1048576s 16GiB
# parted -s /dev/sdb mkpart primary ext4 16GiB 40%
# parted -s /dev/sdb mkpart primary ext4 40% 60%
# parted -s /dev/sdb mkpart primary ext4 60% 100%
# parted -s /dev/sdb name 1 EFI-Boot
# parted -s /dev/sdb name 2 Swap
# parted -s /dev/sdb name 3 root
# parted -s /dev/sdb name 4 /opt
# parted -s /dev/sdb name 5 /home
# parted -s /dev/sdb set 1 esp on
mklabel 命令设置 分区表类型。而且,最常见的选择是gpt 和 msdos (MBR) 。特别是,我们必须在对磁盘进行分区之前进行设置。
-s 选项在脚本中很有用,可以抑制来自parted命令的大多数警告。
**要在所选磁盘上创建分区,我们可以使用 mkpart 命令。**该语法需要分区类型、文件系统类型、开始和结束参数。
在 GPT 磁盘上,没有扩展分区。因此,我们可以将所有分区指定为主分区。
mkpart命令中的开始和结束参数允许使用不同的单位。例如,我们使用百分比、精确的扇区计数和大小作为单位。此外,我们还可以在单个命令调用中混合这些单元。我们还根据预期用途设置了分区名称。
此外,我们在第一个分区上设置了esp(EFI 系统分区)标志。在 GPT 磁盘上,esp标志是引导标志的别名。通常,在 Linux 系统上,此分区挂载在*/boot/efi*上。我们可以找到更多关于如何在 Linux 上挂载文件系统的 细节。
让我们验证我们对sdb驱动器所做的更改:
# parted /dev/sdb unit GiB print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 977GiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 0,00GiB 0,50GiB 0,50GiB EFI-Boot boot, esp
2 0,50GiB 16,0GiB 15,5GiB Swap swap
3 16,0GiB 391GiB 375GiB root
4 391GiB 586GiB 195GiB /opt
5 586GiB 977GiB 391GiB /home
3.4. 修改分区
让我们回到终端,对我们的分区方案进行一些更改:
# parted -s /dev/sdb rm 5
# parted -s /dev/sdb resizepart 4 70%
# parted -s /dev/sdb mkpart primary ext4 70% 100%
# parted -s /dev/sdb name 5 /home
我们想扩展 /opt,但这会导致重叠。因此,我们删除了*/home* 以调整 /opt 分区的大小。
要调整分区大小,我们只能更改分区的结束 参数。 使用 resizepart命令,我们可以扩展或收缩分区。 让我们再次验证我们的更改:
# parted /dev/sdb unit GiB print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 977GiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 0,00GiB 0,50GiB 0,50GiB EFI-Boot boot, esp
2 0,50GiB 16,0GiB 15,5GiB Swap swap
3 16,0GiB 391GiB 375GiB root
4 391GiB 684GiB 293GiB /opt
5 684GiB 977GiB 293GiB /home
4. 使用 LVM 进行分区
LVM(逻辑卷管理)是 Linux 中磁盘分区的另一种方法。**LVM 提供了更高级别的抽象,能够汇集物理存储。**因此,当需求发生变化时,可以实现灵活性和动态调整大小。
物理卷 ( pv ) 是 LVM 中最低级别的抽象。我们可以将整个物理磁盘或分区标记为物理卷。然后,它可以用于池化。
卷组 ( vg ) 是物理卷之后的下一个抽象级别。一个卷组可以汇集多个物理卷,将它们的存储容量组合在一个逻辑单元下。
逻辑卷 ( lv ) 是 LVM 抽象的最高层。因此,用户和应用程序像任何标准分区一样使用逻辑卷。我们可以在一个卷组中有多个逻辑卷。
4.1. 创建物理卷
我们现在将使用一些 LVM 命令来创建和监控卷。事实上,我们将使用来自sdb 和整个磁盘 sdc的相同分区。
现在让我们切换到终端并选择设备进行物理卷准备:
# lvmdiskscan
/dev/sdb1 [ 511,00 MiB]
/dev/sdb2 [ 15,50 GiB]
/dev/sdb3 [ 374,62 GiB]
/dev/sdb4 [ <292,97 GiB]
/dev/sdb5 [ <292,97 GiB]
/dev/sdc [ 3,81 TiB]
1 disk
5 partitions
0 LVM physical volume whole disks
0 LVM physical volumes
**lvmdiskscan 命令可以扫描设备、分区和物理卷。**不过请注意,此命令的输出可能很详尽,并且可能包括其他设备类型。我们可以通过文件lvm.conf 来控制它。例如,在我们的系统中,循环设备和sda驱动器被过滤掉了。
现在我们有一个完整的磁盘和五个可用分区,我们可以将它们标记为 LVM 物理卷。
现在让我们看看如何将设备标记为物理卷:
# pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created.
# pvcreate /dev/sdb1
Physical volume "/dev/sdb1" successfully created.
# pvcreate /dev/sdb2
Physical volume "/dev/sdb2" successfully created.
# pvcreate /dev/sdb3
Physical volume "/dev/sdb3" successfully created.
**pvcreate 命令可以将分区或整个磁盘标记为物理卷。**我们确实看到了一些警告,因为某些分区上有文件系统。请注意,此操作可能会破坏这些设备上的数据。
现在让我们验证我们所做的更改:
# lvmdiskscan
/dev/sdb1 [ 511,00 MiB] LVM physical volume
/dev/sdb2 [ 15,50 GiB] LVM physical volume
/dev/sdb3 [ 374,62 GiB] LVM physical volume
/dev/sdb4 [ <292,97 GiB]
/dev/sdb5 [ <292,97 GiB]
/dev/sdc [ 3,81 TiB] LVM physical volume
0 disks
2 partitions
1 LVM physical volume whole disk
3 LVM physical volumes
# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb1 lvm2 --- 511,00m 511,00m
/dev/sdb2 lvm2 --- 15,50g 15,50g
/dev/sdb3 lvm2 --- 374,62g 374,62g
/dev/sdc lvm2 --- 3,81t 3,81t
lvmdiskscan命令现在可以正确报告我们所做的更改*。*此外,我们可以使用pvs 命令汇总所有物理卷,包括它们对卷组的分配。
4.2. 创建卷组
现在让我们通过选择物理卷来创建一些卷组:
# vgcreate VG_Projects /dev/sdb1 /dev/sdb2
Volume group "VG_Projects" successfully created
# vgcreate VG_Databases /dev/sdb3 /dev/sdc
Volume group "VG_Databases" successfully created
使用 vgcreate 命令,我们创建了两个卷组。卷组可以包括来自不同设备的物理卷。
让我们再次验证我们的更改:
# vgs
VG #PV #LV #SN Attr VSize VFree
VG_Databases 2 0 0 wz--n- 4,18t 4,18t
VG_Projects 2 0 0 wz--n- 15,99g 15,99g
# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb1 VG_Projects lvm2 a-- 508,00m 508,00m
/dev/sdb2 VG_Projects lvm2 a-- <15,50g <15,50g
/dev/sdb3 VG_Databases lvm2 a-- 374,62g 374,62g
/dev/sdc VG_Databases lvm2 a-- 3,81t 3,81t
**使用vgs 命令,我们可以获得所有卷组的摘要。**现在我们可以看到卷组报告了各自的容量。此外,我们还可以看到,现在pvs 命令报告了正确的物理卷到卷组的映射。
4.3. 创建逻辑卷
最后,我们可以在卷组中创建一些逻辑卷:
# lvcreate -L 8G -n ProjectA VG_Projects
Logical volume "ProjectA" created.
# lvcreate -l 100%FREE -n ProjectB VG_Projects
Logical volume "ProjectB" created.
# lvcreate -l 30%VG -n DatabaseA VG_Databases
Logical volume "DatabaseA" created.
# lvcreate -l 50%FREE -n DatabaseB VG_Databases
Logical volume "DatabaseB" created.
**使用 lvcreate 命令,我们创建了四个逻辑卷。**固定大小可以与 -L 选项一起使用。但是,使用 -l 选项,我们可以以百分比指定大小。
例如,30%VG 将使用 30% 的卷组容量,而 50%FREE将使用卷组上 50% 的剩余空间。
让我们回到终端并验证更改:
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
DatabaseA VG_Databases -wi-a----- 1,25t
DatabaseB VG_Databases -wi-a----- 1,46t
ProjectA VG_Projects -wi-a----- 8,00g
ProjectB VG_Projects -wi-a----- 7,99g
使用lvs 命令,我们可以看到我们创建的逻辑卷。
4.4. 修改逻辑卷和卷组
逻辑卷可以作为*/dev/VolumeGroup/LogicalVolume或/dev/mapper/VolumeGroup-LogicalVolume 访问*。 要扩展/减少卷组,我们可以使用 vgextend / vgreduce 命令。同样,要扩展/缩小逻辑卷,我们可以使用 lvextend / lvreduce 命令。
现在让我们做一些修改:
# vgreduce VG_Databases /dev/sdb3
Removed "/dev/sdb3" from volume group "VG_Databases"
blogdemo@itcodingman:~# vgs
VG #PV #LV #SN Attr VSize VFree
VG_Databases 1 2 0 wz--n- 3,81t <1,10t
VG_Projects 2 2 0 wz--n- 15,99g 0
blogdemo@itcodingman:~# vgextend VG_Projects /dev/sdb3
Volume group "VG_Projects" successfully extended
blogdemo@itcodingman:~# vgs
VG #PV #LV #SN Attr VSize VFree
VG_Databases 1 2 0 wz--n- 3,81t <1,10t
VG_Projects 3 2 0 wz--n- 390,61g 374,62g
blogdemo@itcodingman:~# lvextend -L +5G /dev/VG_Projects/ProjectA
Size of logical volume VG_Projects/ProjectA changed from 8,00 GiB (2048 extents) to 13,00 GiB (3328 extents).
Logical volume VG_Projects/ProjectA successfully resized.
blogdemo@itcodingman:~# lvreduce -L -2G /dev/VG_Projects/ProjectB
WARNING: Reducing active and open logical volume to 5,99 GiB.
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce VG_Projects/ProjectB? [y/n]: y
Size of logical volume VG_Projects/ProjectB changed from 7,99 GiB (2046 extents) to 5,99 GiB (1534 extents).
Logical volume VG_Projects/ProjectB successfully resized.
blogdemo@itcodingman:~# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
DatabaseA VG_Databases -wi-ao---- 1,25t
DatabaseB VG_Databases -wi-ao---- 1,46t
ProjectA VG_Projects -wi-ao---- 13,00g
ProjectB VG_Projects -wi-ao---- 5,99g
现在我们通过删除*/dev/sdb3减少了VG_Databases并将其添加到VG_Projects*。此外,我们扩展了ProjectA并减少了ProjectB。
**如果减少逻辑卷会导致数据丢失,我们应该特别小心。**但是,在此示例中,所有修改都是在文件系统处于活动状态时完成的,并且没有数据丢失。