记一次云主机硬盘扩容操作

由于在折腾青龙面板+XDD的时候配置了一套 Golang 的环境,导致为数不多的硬盘空间被吃干净了(没错,剩余量就是这么少)。考虑到机器还会用很长一段时间,所以决定增加一块硬盘对机器进行扩容。

增加硬盘

在阿里云页面购买了硬盘并挂载到 ecs 实例上之后,在系统中出现了一个新的设备——/dev/vdb,表明新增的是一块 virtio 磁盘,和我们常见的 sd* 不同,sd* 表示的是 SCSI 类型的设备。

1
2
ls /dev
... vda vda1 vdb ...

确认磁盘信息

通过 ls 查看代表硬件的文件还是比较粗糙的办法,而且无法查看关于硬件的更详细的内容。
对于磁盘类的设备,可以通过 lshw -C disk 查看硬盘信息和通过 fdisk -l 来查看各个分区信息。

  • 使用 lshw 查看硬盘信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ lshw -C disk
*-virtio1
description: Virtual I/O device
physical id: 0
bus info: virtio@1
logical name: /dev/vda
size: 20GiB (21GB)
capabilities: partitioned partitioned:dos
configuration: driver=virtio_blk logicalsectorsize=512 sectorsize=512 signature=13be70fb
*-virtio4
description: Virtual I/O device
physical id: 0
bus info: virtio@4
logical name: /dev/vdb
size: 100GiB (107GB)
capabilities: partitioned partitioned:dos
configuration: driver=virtio_blk logicalsectorsize=512 sectorsize=512 signature=2681d385
  • 使用 fdisk 查看硬盘分区信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ fdisk -l
Disk /dev/vda: 20 GiB, 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
Disklabel type: dos
Disk identifier: 0x13be70fb

Device Boot Start End Sectors Size Id Type
/dev/vda1 * 2048 41940991 41938944 20G 83 Linux

Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

分区和格式化

在着手分区之前,首先最重要的是确定分区方案。

分区方案

我的这台阿里云 ecs 自带的硬盘是 20G 的“高效云盘”(估计就是一般的 HDD),这次发生硬盘空间不足主要是 home 目录和 var 目录,所以本次扩容+迁移的主要目标也是这两个目录。

参考 n 个经典 linux 分区方案,另外一个可以纳入考虑的是 swap 分区,使用 free -h 查看当前系统中内存的使用情况,可以看到本机物理内存只有 2G,加之之前在运行 docker 的时候忘记开了性能限制,脚本逻辑导致机器内存吃满导致 ssh 都登录不上的情况,所以适当添加虚拟内存 swap 分区在本次是一个可取的方案。

1
2
3
4
❯ free -h
total used free shared buff/cache available
Mem: 1.8Gi 648Mi 204Mi 2.0Mi 1.0Gi 1.0Gi
Swap: 0B 0B 0B

由于添加的是一个 100G 的硬盘,所以我决定的分配方案为:

序号 挂载点 大小 拓展分区
0 swap 16G
1 /var 20G
2 /home 64G
总合 100G

因为 swap 分区的灵活性比较强,所以单独划分一个主分区给它,以备不时之需的时候划分用作其他用途(虽然分配 16G 对于这台机器来说着实是绰绰有余了)。

而 var 和 home 分区意义上都属于是数据区,所以可以放在一起,由一个逻辑拓展分区分出来。

以上只是我自己不成熟的理解,如果看到这篇文章的大佬有更好的见解,希望可以在评论区给予指导,谢谢!

分区操作

为了以防万一,即使系统中没有使用 swap 分区,也手动显式地关闭一下 swap 功能。

1
2
❯ swapoff -a  # 关闭所有的 swap
❯ swapoff /dev/xxx # 关闭某个 swap 分区

如之前所说,添加的是一块 virtio 类型磁盘,所以显示的是/dev/vdb,使用 fdisk 对磁盘分区,分区具体步骤在下面,如果太长了看不下去,可以直接跳到 格式化操作。分区操作我尽量加入注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
❯ fdisk /dev/vdb

Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p # 查看当前硬盘分区结构
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 209715199 209713152 100G 83 Linux

Command (m for help): d # 删除分区,因为原来只有一个分区,所以默认删除了第一个分区
Selected partition 1
Partition 1 has been deleted.

Command (m for help): p # 再次查看分区结构,显示已经没有分区
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Command (m for help): n # (new)新建分区,提示要选择分区类型,主分区或者逻辑分区。
Partition type # 逻辑分区也是一种主分区,占用一个主分区名额。
p primary (0 primary, 0 extended, 4 free) # 主分区一共只能有4个。
e extended (container for logical partitions)
Select (default p): p # 选择新建一个主分区
Partition number (1-4, default 1): # 直接<回车>使用默认给的1号分区号
First sector (2048-209715199, default 2048): # 直接回车使用起始扇区
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-209715199, default 209715199): +16G # 输入“+16G”表示分配16G的空间

Created a new partition 1 of type 'Linux' and of size 16 GiB.
Partition #1 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: Y # 移除原有分区标志

The signature will be removed by a write command.

Command (m for help): t # 输入t表示修改分区类型
Selected partition 1 # 因为当前只有一个分区,所以fdisk默认选择了这个
Hex code (type L to list all codes): 82 # 输入82,表示swap分区的id类型
Changed type of partition 'Linux' to 'Linux swap / Solaris'.

Command (m for help): p # 查看当前分区表
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 33556479 33554432 16G 82 Linux swap / Solaris

Filesystem/RAID signature on partition 1 will be wiped.

Command (m for help): n # 新建分区
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): e # 新建拓展分区
Partition number (2-4, default 2): # 直接回车使用默认起始扇区
First sector (33556480-209715199, default 33556480): # 直接回车使用默认结束扇区
Last sector, +/-sectors or +/-size{K,M,G,T,P} (33556480-209715199, default 209715199):

Created a new partition 2 of type 'Extended' and of size 84 GiB.

Command (m for help): p # 查看当前分区表
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 33556479 33554432 16G 82 Linux swap / Solaris
/dev/vdb2 33556480 209715199 176158720 84G 5 Extended

Filesystem/RAID signature on partition 1 will be wiped.

Command (m for help): n # 新建分区
All space for primary partitions is in use. # fdisk提示目前所有空间都被主分区使用了
Adding logical partition 5 # 所以在拓展分区中添加逻辑分区
First sector (33558528-209715199, default 33558528): # 直接回车使用默认起始扇区
Last sector, +/-sectors or +/-size{K,M,G,T,P} (33558528-209715199, default 209715199): +20G # 输入“+20G”表示限制当前分区大小20G

Created a new partition 5 of type 'Linux' and of size 20 GiB.

Command (m for help): p # 查看当前分区表
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 33556479 33554432 16G 82 Linux swap / Solaris
/dev/vdb2 33556480 209715199 176158720 84G 5 Extended
/dev/vdb5 33558528 75501567 41943040 20G 83 Linux

Filesystem/RAID signature on partition 1 will be wiped.

Command (m for help): n # 新建分区
All space for primary partitions is in use. # fdisk提示目前所有空间都被主分区使用了
Adding logical partition 6 # 所以在拓展分区中添加逻辑分区
First sector (75503616-209715199, default 75503616): # 直接回车使用默认起始扇区
Last sector, +/-sectors or +/-size{K,M,G,T,P} (75503616-209715199, default 209715199): # 直接回车使用默认结束扇区,使用所有剩余空间新建分区

Created a new partition 6 of type 'Linux' and of size 64 GiB.

Command (m for help): p # 查看当前分区表
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 33556479 33554432 16G 82 Linux swap / Solaris
/dev/vdb2 33556480 209715199 176158720 84G 5 Extended
/dev/vdb5 33558528 75501567 41943040 20G 83 Linux
/dev/vdb6 75503616 209715199 134211584 64G 83 Linux

Filesystem/RAID signature on partition 1 will be wiped.

Command (m for help): w # (write)写入改动,使得分区表生效
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

退出后使用fdisk -l查看分区结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
❯ fdisk -l
Disk /dev/vda: 20 GiB, 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
Disklabel type: dos
Disk identifier: 0x13be70fb

Device Boot Start End Sectors Size Id Type
/dev/vda1 * 2048 41940991 41938944 20G 83 Linux

Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 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
Disklabel type: dos
Disk identifier: 0x2681d385

Device Boot Start End Sectors Size Id Type
/dev/vdb1 2048 33556479 33554432 16G 82 Linux swap / Solaris
/dev/vdb2 33556480 209715199 176158720 84G 5 Extended
/dev/vdb5 33558528 75501567 41943040 20G 83 Linux
/dev/vdb6 75503616 209715199 134211584 64G 83 Linux

使用 lsblk 查看块硬件信息。

1
2
3
4
5
6
7
8
9
❯ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 20G 0 disk
└─vda1 252:1 0 20G 0 part /
vdb 252:16 0 100G 0 disk
├─vdb1 252:17 0 16G 0 part [SWAP]
├─vdb2 252:18 0 1K 0 part
├─vdb5 252:21 0 20G 0 part
└─vdb6 252:22 0 64G 0 part

格式化

swap 分区

格式化 swap 分区可以使用 mkswap。这里需要注意的是,swap 分区需要在分区的时候给分区 ID 注册为 82,这样在系统启动的时候才可以正常挂载分区为 swap(具体步骤在 分区

1
2
3
4
5
6
7
8
❯ mkswap /dev/vdb1  # 格式化为 swap
Setting up swapspace version 1, size = 16 GiB (17179865088 bytes)
no label, UUID=220e512a-12a9-4a92-9668-24268004d8ab
❯ swapon /dev/vdb1 # 启用 swap 分区
❯ free -h # 查看 swap 启用情况
total used free shared buff/cache available
Mem: 1.8Gi 652Mi 201Mi 2.0Mi 1.0Gi 1.0Gi
Swap: 15Gi 0B 15Gi

swapon 是手动执行挂载 swap 的操作,关机重启会丢失挂载,所以我们还需要将挂载 swap 的操作添加到开机挂载目录的流程中。使用编辑器编辑/etc/fstab,加入下面这行内容即可,当然,开头的设备文件映射符要换成实际的设备映射符。

1
2
❯ vim /etc/fstab  # 添加下面这行
/dev/vdb1 swap swap defaults 0 0

/var 和/home 等数据分区

将 /dev/vdb5 和 /dev/vdb6 格式化为 ext4 格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
❯ mkfs.ext4 /dev/vdb5
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: 0d80f6eb-ac15-4bdf-8e03-d97508495618
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000

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

❯ mkfs.ext4 /dev/vdb6
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 16776448 4k blocks and 4194304 inodes
Filesystem UUID: 3fbc870d-3f3a-4182-86c2-690bcf1273b5
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424

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

转移数据和挂载

将 /dev/vdb6 挂载到 /mnt/tmp 下,使用 rsync 同步 /home 目录下内容到 vdb6 中。
rsync 据说是可以代替 cp 和 mv 指令的,具体使用情况可以看看 阮一峰的 rsync 教程

1
2
3
4
5
6
7
8
mkdir /mnt/tmp                   # 创建临时目录
❯ mount /dev/vdb6 /mnt/tmp # 挂载 vdb6
❯ rsync -ax /home/* /mnt/tmp # 同步文件
rm -rf /home/* # 删除原始目录下的文件
❯ mount /dev/vdb6 /home # 将 vdb6 挂载到/home 上
❯ umount /mnt/tmp # 卸载临时目录的挂载
ls /home # 使用 ls 查看文件情况
docker download go lost+found scripts

可以看到,文件已经转移过来了,但是多了一个 lost+found 目录,这是因为在格式化分区时自动生成的目录,这次是新增的磁盘分区,所以无需理会直接删掉即可。

之后还需要将分区挂载流程像 swap 一样加入到/etc/fstab 文件中,使得开机自动挂载。

先使用 blkid 获取到每个分区的 id。

1
2
3
4
5
❯ blkid
/dev/vda1: LABEL="/" UUID="abf381e7-98ce-491f-85d5-f16aa9b23811" TYPE="ext4" PARTUUID="13be70fb-01"
/dev/vdb1: UUID="220e512a-12a9-4a92-9668-24268004d8ab" TYPE="swap" PARTUUID="2681d385-01"
/dev/vdb5: UUID="0d80f6eb-ac15-4bdf-8e03-d97508495618" TYPE="ext4" PARTUUID="2681d385-05"
/dev/vdb6: UUID="3fbc870d-3f3a-4182-86c2-690bcf1273b5" TYPE="ext4" PARTUUID="2681d385-06"

像我这里因为是用 /dev/vdb6 挂载到 /home,所以 UUID 是3fbc870d-3f3a-4182-86c2-690bcf1273b5,获取到了 UUID 之后,在/etc/fstab 添加下面一行即可。

1
2
❯ vim /etc/fstab
UUID=3fbc870d-3f3a-4182-86c2-690bcf1273b5 /home ext4 defaults 0 2

接着如法炮制 /dev/vdb5 挂载到 /var 目录。

1
2
3
4
5
6
7
8
9
10
11
❯ mount /dev/vdb5 /mnt/tmp
❯ rsync -ax /var/* /mnt/tmp
rm -rf /var/*
❯ mount /dev/vdb5 /var
❯ blkid
/dev/vda1: LABEL="/" UUID="abf381e7-98ce-491f-85d5-f16aa9b23811" TYPE="ext4" PARTUUID="13be70fb-01"
/dev/vdb1: UUID="220e512a-12a9-4a92-9668-24268004d8ab" TYPE="swap" PARTUUID="2681d385-01"
/dev/vdb5: UUID="0d80f6eb-ac15-4bdf-8e03-d97508495618" TYPE="ext4" PARTUUID="2681d385-05"
/dev/vdb6: UUID="3fbc870d-3f3a-4182-86c2-690bcf1273b5" TYPE="ext4" PARTUUID="2681d385-06"
❯ vim /etc/fstab
UUID=0d80f6eb-ac15-4bdf-8e03-d97508495618 /var ext4 defaults 0 2

最后,使用 df 查看,一切目录挂载占用正常即可。

1
2
3
4
5
6
7
8
9
10
11
df -hT
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 914M 0 914M 0% /dev
tmpfs tmpfs 189M 1.2M 188M 1% /run
/dev/vda1 ext4 20G 7.1G 12G 38% /
tmpfs tmpfs 943M 0 943M 0% /dev/shm
tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs tmpfs 943M 0 943M 0% /sys/fs/cgroup
tmpfs tmpfs 189M 4.0K 189M 1% /run/user/0
/dev/vdb6 ext4 63G 5.9G 54G 10% /home
/dev/vdb5 ext4 20G 6.9G 12G 37% /var

/etc/fstab 文件填写要素

在编辑 fstab 的过程中对每个参数的意义产生了疑惑,所以查找了一些资料并且总结一下:

例如下面这条记录:

1
UUID=3fbc870d-3f3a-4182-86c2-690bcf1273b5  /home  ext4  defaults  0  2

我们从 fstab 的文件的头部注释中可以获取到一些信息,例如第一个参数是能够代表挂载点的硬件文件系统,第二个是挂载点,第三个是硬件分区类型,第四个是挂载选项,但是还是很难明确最后两个数字的意义。

1
2
3
4
5
6
7
8
9
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/vda1 during installation
...

对于六个参数的意义的明确:

  1. 设备

    意义:要挂载的设备
    输入类型:

    • 设备文件
    • LABEL=
    • UUID=
  2. 挂载点

    swap 没有挂载点,挂载点为 swap
    其余可以填写为目录名称,例如/home

  3. 文件系统类型

    ext2、ext3、ext4、xfs、nfs、smb、iso9660 等

  4. 挂载选项

    async、sync、_netdev
    defaults( rw, suid, dev, exec, auto, nouser, async, and relatime.)

  5. 转储频度

    0:从不备份
    1:每日备份
    2:每隔一天备份

  6. 自检次序

    0: 不自检
    1:首先自检,通常只能被/使用;
    2:等数字为 1 的自检完成后,再进行自检


参考资料:

Author: SmallXeon
Link: https://hexo.chensmallx.top/2021/08/26/record-a-disk-expansion-on-alicloud-ubuntu/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
一些推广链接
几个便宜量大的小✈场: FASTLINK, YToo, 论坛邀请注册: ,
便宜量大但是稳定性不足的VPS: Virmach, 价格略贵但好用的VPN: , ,