Contents

在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 系统驱动器。但是,驱动器sdbsdc没有分区表。

3.1. 选择设备

由于sda是系统驱动器,我们将在分区示例中使用sdbsdc

现在让我们启动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

**如果减少逻辑卷会导致数据丢失,我们应该特别小心。**但是,在此示例中,所有修改都是在文件系统处于活动状态时完成的,并且没有数据丢失。