我经常用虚拟机装各种版本的Linux系统来跑程序,一般硬盘分得比较小。比如CentOS 6就只分了16G,跑的是服务端的程序,不用安装界面,整个系统也就占3G不到,一般也够用。直到某一天,我需要把一个20G的sql脚本导入到数据库里。这才发觉自己从来没做过Linux的硬盘扩容,一番鼓捣之后,做个笔记本留档。
现在主流的Linux,基本都使用LVM分区。哪啥是LVM?这得先来了解一下基础概念。Logical Volume Manager
中文名叫逻辑卷管理器,简称LVM,它是Linux下对逻辑卷进行管理的一套程序,LVM分区,就是LVM管理下的一个逻辑卷。LVM通常涉及下面几个术语:
- PP(physical Partition)
物理分区,通常指硬盘中的主分区,逻辑分区。严格来讲整个硬盘或者其他能存东西的物理介质包括网络存储也能作为一个物理分区,但一定是有实物的 - PV(Physical Volume)
物理卷,就是在PP(物理分区)的基础上,使用pvcreate
指令写入一些数据,转换为可供LVM识别后的物理介质。 - VG(Volumes Group)
卷组,由一个或多个PV组成的一个分组,形成一大块存储空间 - LV(Logical Volume)
逻辑卷,也就是LVM分区,在VG上划分一块空间称为逻辑卷,一个VG上只要还有空间就可以建立多个LV。在逻辑卷之上可以建立文件系统(ext3、ext4等),然后即可把数据存到分区里 - PE(Physical Extent)
具有唯一编号的PE是可以被LVM寻址的最小单元,其大小是在创建VG时确定的,默认为4MB(可通过vgcreate -s
指定)。一个VG包含N个PE,从VG上划分一块空间作为LV时就是把其中一部分数量的PE标记为该LV。
它们之间的关系,可以简单地概括为:一块硬盘,被分成了几个分区(PP),然后把PP转换为PV,多个PV可以组成一个VG。组成VG后,就得到了一块很大的空间,它的大小是以PE的来衡量的。现在从VG上划分一块空间形成一个LV,然后就可以在LV上创建文件系统,进行读写数据。
(图片来源于网络)
这么做的目的,就是把物理存储介质和具体使用的空间解耦,例如/home
这个文件夹,可能一部分在硬盘A,另一部分在硬盘B。这就是为什么被称为逻辑卷
,因为这个卷是通过逻辑虚拟出来的,物理上不存在这个卷。解耦之后整个系统的空间就可以方便的扩容、更换物理介质,这对长期运行,不停服更换硬件的服务器很重要。
我的CentOS 6是在VritualBox中以一个硬盘以默认方式安装的,它的分区如下:
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
14G 2.1G 11G 16% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 477M 34M 418M 8% /boot
可以看到,默认情况下只有一个根分区,从参数/dev/mapper/VolGroup-lv_root
可以看出来它是一个LVM分区。所有数据都存在这个唯一的分区里,所以这次就是要对这个分区进行扩容。
使用lsblk
则可以更清析地看到硬盘的分区结构
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 58.2M 0 rom
sda 8:0 0 16G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 15.5G 0 part
├─VolGroup-lv_root (dm-0) 253:0 0 13.9G 0 lvm /
└─VolGroup-lv_swap (dm-1) 253:1 0 1.6G 0 lvm [SWAP]
可以看到系统中有一个光驱sr0
;一个硬盘sda
。硬盘被分为两个区(sda1、sda2),而sda2被划分为两个LVM分区(VolGroup-lv_root、VolGroup-lv_swap)。假如需要看到硬盘的一些更详细的信息,可以使用parted
:
[root@localhost ~]# parted /dev/sda
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print all
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 17.2GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 525MB 524MB primary ext4 boot
2 525MB 17.2GB 16.7GB primary lvm
可以看到当前这个硬盘大小为17.2GB,有两个主分区,一个为ext4,另一个被标记为lvm。对于这个lvm管理的分区,它有PV、VG、LV等参数,可通过pvdisplay、vgdisplay、lvdisyplay打印出来:
[root@localhost ~]# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name VolGroup
PV Size 15.51 GiB / not usable 3.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 3970
Free PE 0
Allocated PE 3970
PV UUID XydIzE-RJIT-Hcfc-5vCw-NnKE-goPE-VFwhn3
[root@localhost ~]# vgdisplay
--- Volume group ---
VG Name VolGroup
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 1
Act PV 1
VG Size 15.51 GiB
PE Size 4.00 MiB
Total PE 3970
Alloc PE / Size 3970 / 15.51 GiB
Free PE / Size 0 / 0
VG UUID 43d3d6-xFIm-s2vF-Z1jY-pKBc-sniG-wT0VTL
[root@localhost ~]# lvdisplay
--- Logical volume ---
LV Path /dev/VolGroup/lv_root
LV Name lv_root
VG Name VolGroup
LV UUID 2OJpKu-4KI9-DpUX-ZiVl-wanM-gdlY-yMbCau
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2022-03-14 17:48:16 +0800
LV Status available
# open 1
LV Size 13.91 GiB
Current LE 3561
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
--- Logical volume ---
LV Path /dev/VolGroup/lv_swap
LV Name lv_swap
VG Name VolGroup
LV UUID jWqLXl-yzPu-xzJ9-ao4a-9JB5-KYXu-X2niXP
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2022-03-14 17:48:18 +0800
LV Status available
# open 1
LV Size 1.60 GiB
Current LE 409
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:1
通过上面的信息,可以看到整个系统中有一个PV(物理卷,也就是sda2这个分区);有一个VG名字叫VolGroup,一共有3970个PE,每个PE大小为4MB,所以整个VG大小为15.51GB,空闲的PE(Free PE)为0,说明空间都被用光了;有两个LV,都是从VolGroup这个VG上划分出来的,一个13.91GB,一个1.6GB。
了解当前系统的信息后,开始对硬盘进行扩容。由于是虚拟机,就不用去买新硬盘了,可以直接在虚拟机上调整硬盘大小。VirtualBox的操作方式为:
关闭虚拟机,在菜单“管理/虚拟介质管理”中找到对应虚拟机的硬盘,设置新的大小即可。
我这里直接把它调整到128GB,现在重新启动虚拟机,df -h
可以看到各个分区大小没变,而parted
使用print free可以看到硬盘大小变了,后面多出120G空间。这是因为系统是根据分区表来确定分区大小的,新加的空间没法直接使用。
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
14G 2.1G 11G 16% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 477M 34M 418M 8% /boot
[root@localhost ~]# parted /dev/sda
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 137GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
32.3kB 1049kB 1016kB Free Space
1 1049kB 525MB 524MB primary ext4 boot
2 525MB 17.2GB 16.7GB primary lvm
17.2GB 137GB 120GB Free Space
(parted)
如果是新增一个硬盘,可以直接整个硬盘作为一个PP转换为PV(当然把整个硬盘格式化成一个分区来操作也是可以的)
pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created
但现在是在原有硬盘上扩展空间,因此只能分区。分区使用fdisk
或者parted
都可以,这里用更广泛一些的fdisk
[root@localhost ~]# fdisk /dev/sda
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (2089-16709, default 2089):
Using default value 2089
Last cylinder, +cylinders or +size{K,M,G} (2089-16709, default 16709):
Using default value 16709
Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 8e
Changed system type of partition 3 to 8e (Linux LVM)
Command (m for help): p
Disk /dev/sda: 137.4 GB, 137438953472 bytes
255 heads, 63 sectors/track, 16709 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000a342
Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 2089 16264192 8e Linux LVM
/dev/sda3 2089 16709 117437826+ 8e Linux LVM
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.
Command (m for help): n
使用n指令创建分区,选p创建主分区(由上面的信息可知,默认情况下系统分了sda1 sda2两个主分区,那我干脆也分一个主分区3)Partition number (1-4): 3
设置主分区id为3,即sda3
First cylinder (2089-16709, default 2089):
输入分区开始的第一个扇区,默认为空闲空间的第一个扇区2089,所以我这里直接回车Last cylinder, +cylinders or +size{K,M,G} (2089-16709, default 16709):
输入分区结束的最后一个扇区,默认为空闲空间的最后一个扇区16709,所以我这里直接回车Command (m for help): t
使用t指令修改分区的类型Partition number (1-4): 3
选择要修改的分区idHex code (type L to list codes): 8e
选择分区的类型(8e就表示lvm),输入l可列出所有支持的类型Command (m for help): p
现在打印一下当前分区表,确认是不是自己想要的Command (m for help): w
确认分区表正确后,用w写入硬盘。我这里出现了一个警告,按提示是要重启一下
现在把新建的分区sda3
转换为PV。由于我忽略了上面的警告,结果找不到sda3
,这可能和VirtualBox的硬盘模拟有关,其他机子不一定会出现:
[root@localhost ~]# pvcreate sda3
Device sda3 not found (or ignored by filtering).
重启后再执行即可
[root@localhost ~]# pvcreate /dev/sda3
Physical volume "/dev/sda3" successfully created
由之前vgdisplay
查看的数据可知道,当前系统有一个名字为VolGroup的VG,现在要把刚转换好的PV添加到这个VG里
[root@localhost ~]# vgextend VolGroup /dev/sda3
Volume group "VolGroup" successfully extended
再次用vgdisplay
,可以看到VG已经被扩大,现在有很多空闲的PE了
[root@localhost ~]# vgdisplay
--- Volume group ---
VG Name VolGroup
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 2
Act PV 2
VG Size 127.50 GiB
PE Size 4.00 MiB
Total PE 32641
Alloc PE / Size 3970 / 15.51 GiB
Free PE / Size 28671 / 112.00 GiB
VG UUID 43d3d6-xFIm-s2vF-Z1jY-pKBc-sniG-wT0VTL
由之前lvdisplay
查看的数据可知道,当前有两个LV,一个lv_swap
路径为/dev/VolGroup/lv_swap
,一个lv_root
路径为/dev/VolGroup/lv_root
。记住路径,下面的扩容操作是使用路径来操作。现在需要对lv_root
进行扩容
[root@localhost ~]# lvextend -l +100%FREE /dev/VolGroup/lv_root
Size of logical volume VolGroup/lv_root changed from 13.91 GiB (3561 extents) to 125.91 GiB (32232 extents).
Logical volume lv_root successfully resized.
上面是使用百分比来扩容,通过lvextend --help
可以知道,还有很多种方式指定扩容的单位,比如
# 使用M、G等常用单位扩容,支持的单位为[bBsSkKmMgGtTpPeE]
lvextend -L +10G /dev/VolGroup/lv_root
# 使用PE数量扩容,通用一个PE为4M。空闲PE的数量和单个PE的大小可通过`vgdisplay`查看
lvextend -l +2560 /dev/VolGroup/lv_root
lvm分区的大小扩展了,但是通过df -h
来查看,可以看到空间还是不变的。因为在lvm分区之上,linux还有一层文件系统(ext3、ext4等等),需要对文件系统扩展才行。ext3 和 ext4文件系统使用resize2fs
,其他系统查下资料才知道
[root@localhost ~]# resize2fs /dev/VolGroup/lv_root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/VolGroup/lv_root is mounted on /; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 8
Performing an on-line resize of /dev/VolGroup/lv_root to 33005568 (4k) blocks.
The filesystem on /dev/VolGroup/lv_root is now 33005568 blocks long.
现在使用df -h
可以看到空间已经扩展了。
相比之下,Window的区分则显得更加简单、直观。Windows的分区直接就是采用“物理卷”,即分区怎么分,在物理上就是怎么划分的,使用DiskGenius
或者傲梅分区助手
等流行的工具可以直观地调整分区的大小
不过这种简单也是有限制的,那就是需要进入PE系统来操作,没办法不停机操作(也许有,但我不会),当然这对于个人电脑来说并不是一个重要的指标。