# LVM

我们可能会遇到这样的情况，系统中有两块硬盘，一个100G，一个200G，但是我们需要在某个目录下，空间大小需要250G。如果按照之前的方法，先把硬盘分区，再把分区挂载到该目录下，很明显满足不了需求。此时，LVM（Logic Volume Management）技术就能够派上用场了。

首先，我们介绍三个重要的概念

* PV：物理卷（Physical Volume），一个物理卷可以由一个主分区或者逻辑分区、或者是一个没有分区的硬盘创建而来，但是不能使用扩展分区创建物理卷。
* VG：卷组（Volume Group），一个卷组由多个物理卷组成，这些物理卷可以是不同硬盘上的分区。卷组支持动态增加或删除物理卷，从而实现动态扩缩容。
* LV：逻辑卷（Logic Volume），可以从一个卷组中创建多个逻辑卷，逻辑卷可以格式化与挂载

介绍了上面三个概念，我们发现，一个100G和200G的硬盘，我们可以通过LVM技术创建一个250G逻辑卷，然后挂载到对应目录下，满足需求。

接下来，我们将通过实践来看看是如何使用LVM的。首先我们看一下前置条件：系统中有两个硬盘`/dev/sda`与`/dev/sdb`。`/dev/sda`有两个主分区`/dev/sda1`（50G）与`/dev/sda2`（787G），`/dev/sdb`有两个主分区`/dev/sdb1`（50G）与`/dev/sdb2`（173G）。我们的目标是，用`/dev/sda2`与`/dev/sdb2`创建一个卷组（787G+173G=960G），然后从卷组中创建一个大小为900G的逻辑卷，格式化该逻辑卷然后将其挂载到目录`/data2`下。

硬盘与分区情况如下：

```
[root@localhost ~]# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    1   837G  0 disk 
├─sda1   8:1    1    50G  0 part /
└─sda2   8:2    1   787G  0 part 
sdb      8:16   1 223.4G  0 disk 
├─sdb1   8:17   1    50G  0 part 
└─sdb2   8:18   1 173.4G  0 part 
[root@localhost ~]# fdisk -l

Disk /dev/sda: 898.7 GB, 898708275200 bytes, 1755289600 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
Disk label type: dos
Disk identifier: 0x0009613d

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048   104859647    52428800   83  Linux
/dev/sda2       104859648  1755289599   825214976   83  Linux

Disk /dev/sdb: 239.9 GB, 239902654464 bytes, 468559872 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
Disk label type: dos
Disk identifier: 0x93de47a2

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048   104859647    52428800   83  Linux
/dev/sdb2       104859648   468559871   181850112   83  Linux
```

接下来，我们用分区`/dev/sda2`与`/dev/sdb2`创建对应的两个物理卷，然后pvdisplay一下发现多了两个pv

```
[root@localhost ~]# pvcreate /dev/sda2
  Physical volume "/dev/sda2" successfully created.
[root@localhost ~]# pvcreate /dev/sdb2
  Physical volume "/dev/sdb2" successfully created.
[root@localhost ~]# pvdisplay
  "/dev/sdb2" is a new physical volume of "<173.43 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb2
  VG Name               
  PV Size               <173.43 GiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               mLapVo-tZSK-mpVY-ye4T-rf7w-kBUO-PTqsDd

  "/dev/sda2" is a new physical volume of "<786.99 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sda2
  VG Name               
  PV Size               <786.99 GiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               kle4Ia-DdOY-zG40-8CqP-gqhw-kwLP-hOABne
```

然后利用这两个物理卷创建一个卷组，可以看出，这个卷组的大小为960.41G

```
[root@localhost ~]# vgcreate myvg /dev/sda2 /dev/sdb2
  Volume group "myvg" successfully created
[root@localhost ~]# vgdisplay
  --- Volume group ---
  VG Name               myvg
  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               <960.41 GiB
  PE Size               4.00 MiB
  Total PE              245864
  Alloc PE / Size       0 / 0   
  Free  PE / Size       245864 / <960.41 GiB
  VG UUID               86QgV0-uxvo-nA8F-x2ae-HR2Q-GnXd-fut39o
```

接下来，我们在卷组中创建一个大小为900G的逻辑卷

```
[root@localhost ~]# lvcreate -n mylv --size 900G myvg
  Logical volume "mylv" created.
[root@localhost ~]# lvdisplay
  --- Logical volume ---
  LV Path                /dev/myvg/mylv
  LV Name                mylv
  VG Name                myvg
  LV UUID                00dplX-uqHr-IpzA-tA6T-hf3d-TFnA-c5cnuk
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2018-11-30 17:08:52 +0800
  LV Status              available
  # open                 0
  LV Size                900.00 GiB
  Current LE             230400
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0
```

然后格式化逻辑卷，并挂载到`/data2`目录下

```
[root@localhost ~]# mkfs.xfs -f -i attr=2 -l lazy-count=1,sectsize=4096 -b size=4096 -d sectsize=4096 -n ftype=1 -L data /dev/myvg/mylv
meta-data=/dev/myvg/mylv         isize=512    agcount=4, agsize=58982400 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=235929600, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=115200, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@localhost ~]# mkdir /data2
[root@localhost ~]# mount -o rw,noatime,nodiratime,noikeep,nobarrier,allocsize=100M,attr2,largeio,inode64,swalloc /dev/myvg/mylv /data2
```

接下来，我们来看一下分区与挂载的情况，发现`/data2`目录的大小为900G，设备的目录需要注意下，为`/dev/mapper/myvg-mylv`

```
[root@localhost ~]# df -hT
Filesystem            Type      Size  Used Avail Use% Mounted on
/dev/sda1             xfs        50G  7.8G   43G  16% /
devtmpfs              devtmpfs   63G     0   63G   0% /dev
tmpfs                 tmpfs      63G     0   63G   0% /dev/shm
tmpfs                 tmpfs      63G   18M   63G   1% /run
tmpfs                 tmpfs      63G     0   63G   0% /sys/fs/cgroup
tmpfs                 tmpfs      13G   40K   13G   1% /run/user/0
/dev/mapper/myvg-mylv xfs       900G   33M  900G   1% /data2
```

我们看一下`lsblk`与`fdisk`命令的输出，发现`lsblk`中的`sda2`与`sdb2`下多了`myvg-mylv`，且类型为lvm，这说明`myvg-mylv`是一个逻辑卷，它所属的卷组所`sda2`与`sdb2`两个物理组成。另外，`fdisk`命令中并没有显示这个逻辑卷，看来`fdisk`只会显示分区的内容。

```
[root@localhost ~]# lsblk
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda             8:0    1   837G  0 disk 
├─sda1          8:1    1    50G  0 part /
└─sda2          8:2    1   787G  0 part 
  └─myvg-mylv 253:0    0   900G  0 lvm  /data2
sdb             8:16   1 223.4G  0 disk 
├─sdb1          8:17   1    50G  0 part 
└─sdb2          8:18   1 173.4G  0 part 
  └─myvg-mylv 253:0    0   900G  0 lvm  /data2
[root@localhost ~]# fdisk -l

Disk /dev/sda: 898.7 GB, 898708275200 bytes, 1755289600 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
Disk label type: dos
Disk identifier: 0x0009613d

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048   104859647    52428800   83  Linux
/dev/sda2       104859648  1755289599   825214976   83  Linux

Disk /dev/sdb: 239.9 GB, 239902654464 bytes, 468559872 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
Disk label type: dos
Disk identifier: 0x93de47a2

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048   104859647    52428800   83  Linux
/dev/sdb2       104859648   468559871   181850112   83  Linux

Disk /dev/mapper/myvg-mylv: 966.4 GB, 966367641600 bytes, 1887436800 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
```

## 删除操作

接下来，我们来删除这些逻辑卷、卷组和物理卷。首先先卸载逻辑卷

```
umount /dev/mapper/myvg-mylv
```

然后删除逻辑卷`/dev/myvg/mylv`，再lvdisplay一下发现lv没有了

```
[root@localhost ~]# lvremove /dev/myvg/mylv
Do you really want to remove active logical volume myvg/mylv? [y/n]: y
  Logical volume "mylv" successfully removed
[root@localhost ~]# lvdisplay
[root@localhost ~]#
```

接着删除卷组`myvg`，再vgdisplay一下发现vg没有了

```
[root@localhost ~]# vgremove myvg
  Volume group "myvg" successfully removed
[root@localhost ~]# vgdisplay 
[root@localhost ~]#
```

接着可以删除物理卷`/dev/sda2`和`/dev/sdb2`，再pvdisplay一下发现不存在pv了

```
[root@localhost ~]# pvremove /dev/sda2
  Labels on physical volume "/dev/sda2" successfully wiped.
[root@localhost ~]# pvremove /dev/sdb2
  Labels on physical volume "/dev/sdb2" successfully wiped.
[root@localhost ~]# pvdisplay 
[root@localhost ~]#
```

## Reference

\[1] <https://www.tecmint.com/add-new-disks-using-lvm-to-linux/>

\[2] <http://blog.51cto.com/11093860/2164405>
