本文参考了《Linux鸟哥私房菜第十五章、磁碟配额(Quota)与进阶文件系统管理

逻辑卷轴管理员 (Logical Volume Manager)

 什么是 LVM: PV, PE, VG, LV 的意义
 LVM 实作流程: PV 阶段VG 阶段LV 阶段文件系统阶段

逻辑卷轴管理员 (Logical Volume Manager)

想像一个情况,你在当初规划主机的时候将 /home 只给他 50G ,等到使用者众多之后导致这个 filesystem 不够大, 此时你能怎么作?多数的朋友都是这样:再加一颗新硬盘,然后重新分割、格式化,将 /home 的数据完整的复制过来, 然后将原本的 partition 卸载重新挂载新的 partition 。啊!好忙碌啊!若是第二次分割却给的容量太多!导致很多磁碟容量被浪费了! 你想要将这个 partition 缩小时,又该如何作?将上述的流程再搞一遍!唉~烦死了,尤其复制很花时间ㄟ~有没有更简单的方法呢? 有的!那就是我们这个小节要介绍的 LVM 这玩意儿!

LVM 的重点在於『可以弹性的调整 filesystem 的容量!』而并非在於效能与数据保全上面。 需要文件的读写效能或者是数据的可靠性,请参考前面的 RAID 小节。 LVM 可以整合多个实体 partition 在一起, 让这些 partitions 看起来就像是一个磁碟一样!而且,还可以在未来新增或移除其他的实体 partition 到这个 LVM 管理的磁碟当中。 如此一来,整个磁碟空间的使用上,实在是相当的具有弹性啊! 既然 LVM 这么好用,那就让我们来瞧瞧这玩意吧!


什么是 LVM: PV, PE, VG, LV 的意义

LVM 的全名是 Logical Volume Manager,中文可以翻译作逻辑卷轴管理员。之所以称为『卷轴』可能是因为可以将 filesystem 像卷轴一样伸长或缩短之故吧!LVM 的作法是将几个实体的 partitions (或 disk) 透过软件组合成为一块看起来是独立的大磁碟 (VG) ,然后将这块大磁碟再经过分割成为可使用分割槽 (LV), 最终就能够挂载使用了。但是为什么这样的系统可以进行 filesystem 的扩充或缩小呢?其实与一个称为 PE 的项目有关! 底下我们就得要针对这几个项目来好好聊聊!

  • Physical Volume, PV, 实体卷轴

我们实际的 partition 需要调整系统识别码 (system ID) 成为 8e (LVM 的识别码),然后再经过 pvcreate 的命令将他转成 LVM 最底层的实体卷轴 (PV) ,之后才能够将这些 PV 加以利用! 调整 system ID 的方是就是透过 fdisk 啦!

  • Volume Group, VG, 卷轴群组

所谓的 LVM 大磁碟就是将许多 PV 整合成这个 VG 的东西就是啦!所以 VG 就是 LVM 组合起来的大磁碟!这么想就好了。 那么这个大磁碟最大可以到多少容量呢?这与底下要说明的 PE 有关喔~因为每个 VG 最多仅能包含 65534 个 PE 而已。 如果使用 LVM 默认的参数,则一个 VG 最大可达 256GB 的容量啊!(参考底下的 PE 说明)

  • Physical Extend, PE, 实体延伸区块

LVM 默认使用 4MB 的 PE 区块,而 LVM 的 VG 最多仅能含有 65534 个 PE ,因此默认的 LVM VG 会有 4M*65534/(1024M/G)=256G。 这个 PE 很有趣喔!他是整个 LVM 最小的储存区块,也就是说,其实我们的文件数据都是藉由写入 PE 来处理的。 简单的说,这个 PE 就有点像文件系统里面的 block 大小啦。 这样说应该就比较好理解了吧?所以调整 PE 会影响到 VG 的最大容量喔!

  • Logical Volume, LV, 逻辑卷轴

最终的 VG 还会被切成 LV,这个 LV 就是最后可以被格式化使用的类似分割槽的咚咚了!那么 LV 是否可以随意指定大小呢? 当然不可以!既然 PE 是整个 LVM 的最小储存单位,那么 LV 的大小就与在此 LV 内的 PE 总数有关。 为了方便使用者利用 LVM 来管理其系统,因此 LV 的装置档名通常指定为『 /dev/vgname/lvname 』的样式!

此外,我们刚刚有谈到 LVM 可弹性的变更 filesystem 的容量,那是如何办到的?其实他就是透过『交换 PE 』来进行数据转换, 将原本 LV 内的 PE 移转到其他装置中以降低 LV 容量,或将其他装置的 PE 加到此 LV 中以加大容量! VG、LV 与 PE 的关系有点像下图:

PE 与 VG 的相关性图示
PE 与 VG 的相关性图示

如上图所示,VG 内的 PE 会分给虚线部分的 LV,如果未来这个 VG 要扩充的话,加上其他的 PV 即可。 而最重要的 LV 如果要扩充的话,也是透过加入 VG 内没有使用到的 PE 来扩充的!

  • 实作流程

透过 PV, VG, LV 的规划之后,再利用 mkfs 就可以将你的 LV 格式化成为可以利用的文件系统了!而且这个文件系统的容量在未来还能够进行扩充或减少, 而且里面的数据还不会被影响!实在是很『福气啦!』那实作方面要如何进行呢?很简单呢! 整个流程由基础到最终的结果可以这样看:

LVM 各组件的实现流程图示
 LVM 各组件的实现流程图示

如此一来,我们就可以利用 LV 这个玩意儿来进行系统的挂载了。不过,你应该要觉得奇怪的是, 那么我的数据写入这个 LV 时,到底他是怎么写入硬盘当中的? 呵呵!好问题~其实,依据写入机制的不同,而有两种方式:

  • 线性模式 (linear):假如我将 /dev/hda1, /dev/hdb1 这两个 partition 加入到 VG 当中,并且整个 VG 只有一个 LV 时,那么所谓的线性模式就是:当 /dev/hda1 的容量用完之后,/dev/hdb1 的硬盘才会被使用到, 这也是我们所建议的模式。

  • 交错模式 (triped):那什么是交错模式?很简单啊,就是我将一笔数据拆成两部分,分别写入 /dev/hda1 与 /dev/hdb1 的意思,感觉上有点像 RAID 0 啦!如此一来,一份数据用两颗硬盘来写入,理论上,读写的效能会比较好。

基本上,LVM 最主要的用处是在实现一个可以弹性调整容量的文件系统上, 而不是在创建一个效能为主的磁碟上,所以,我们应该利用的是 LVM 可以弹性管理整个 partition 大小的用途上,而不是著眼在效能上的。因此, LVM 默认的读写模式是线性模式啦! 如果你使用 triped 模式,要注意,当任何一个 partition 『归天』时,所有的数据都会『损毁』的! 所以啦,不是很适合使用这种模式啦!如果要强调效能与备份,那么就直接使用 RAID 即可, 不需要用到 LVM 啊!


LVM 实作流程

LVM 必需要核心有支持且需要安装 lvm2 这个软件,好佳在的是, CentOS 与其他较新的 distributions 已经默认将 lvm 的支持与软件都安装妥当了!所以你不需要担心这方面的问题!用就对了!

鸟哥使用的测试机又要出动了喔!刚刚我们才练习过 RAID,必须要将一堆目前没有用到的分割槽先杀掉, 然后再重建新的分割槽。并且由於鸟哥仅有一个 40GB 的磁碟,所以底下的练习都仅针对同一颗磁碟来作的。 我的要求有点像这样:

  • 先分割出 4 个 partition ,每个 partition 的容量均为 1.5GB 左右,且 system ID 需要为 8e;

  • 全部的 partition 整合成为一个 VG,VG 名称配置为 vbirdvg;且 PE 的大小为 16MB;

  • 全部的 VG 容量都丢给 LV ,LV 的名称配置为 vbirdlv;

  • 最终这个 LV 格式化为 ext3 的文件系统,且挂载在 /mnt/lvm 中

鸟哥就不仔细的介绍实体分割了,请您自行参考第八章的 fdisk 来达成底下的范例:(注意:修改系统识别码请使用 t 这个 fdisk 内的命令来处理即可)

[root@www ~]# fdisk /dev/hda  <==其他流程请自行参考第八章处理
[root@www ~]# partprobe       <==别忘记这个动作了!粉重要!
[root@www ~]# fdisk -l
Disk /dev/hda: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        1288    10241437+  83  Linux
/dev/hda3            1289        1925     5116702+  83  Linux
/dev/hda4            1926        5005    24740100    5  Extended
/dev/hda5            1926        2052     1020096   82  Linux swap / Solaris/dev/hda6            2053        2235     1469916   8e  Linux LVM
/dev/hda7            2236        2418     1469916   8e  Linux LVM
/dev/hda8            2419        2601     1469916   8e  Linux LVM
/dev/hda9            2602        2784     1469916   8e  Linux LVM

上面的 /dev/hda{6,7,8,9} 这四个分割槽就是我们的实体分割槽!也就是底下会实际用到的资讯! 注意看,那个 8e 的出现会导致 system 变成『 Linux LVM 』哩!其实没有配置成为 8e 也没关系, 不过某些 LVM 的侦测命令可能会侦测不到该 partition 就是了!接下来,就一个一个的处理各流程吧!


  • PV 阶段

要创建 PV 其实很简单,只要直接使用 pvcreate 即可!我们来谈一谈与 PV 有关的命令吧!

  • pvcreate :将实体 partition 创建成为 PV ;

  • pvscan :搜寻目前系统里面任何具有 PV 的磁碟;

  • pvdisplay :显示出目前系统上面的 PV 状态;

  • pvremove :将 PV 属性移除,让该 partition 不具有 PV 属性。

# 1. 检查有无 PV 在系统上,然后将 /dev/hda6~/dev/hda9 创建成为 PV 格式[root@www ~]# pvscan
  No matching physical volumes found <==找不到任何的 PV 存在喔!
  [root@www ~]# pvcreate /dev/hda{6,7,8,9}
  Physical volume "/dev/hda6" successfully created
  Physical volume "/dev/hda7" successfully created
  Physical volume "/dev/hda8" successfully created
  Physical volume "/dev/hda9" successfully created# 这个命令可以一口气创建这四个 partition 成为 PV 啦!注意大括号的用途[root@www ~]# pvscan
  PV /dev/hda6         lvm2 [1.40 GB]
  PV /dev/hda7         lvm2 [1.40 GB]
  PV /dev/hda8         lvm2 [1.40 GB]
  PV /dev/hda9         lvm2 [1.40 GB]
  Total: 4 [5.61 GB] / in use: 0 [0   ] / in no VG: 4 [5.61 GB]# 这就分别显示每个 PV 的资讯与系统所有 PV 的资讯。尤其最后一行,显示的是:
# 整体 PV 的量 / 已经被使用到 VG 的 PV 量 / 剩余的 PV 量# 2. 更详细的列示出系统上面每个 PV 的个别资讯:[root@www ~]# pvdisplay
  "/dev/hda6" is a new physical volume of "1.40 GB"
  --- NEW Physical volume ---
  PV Name               /dev/hda6  <==实际的 partition 装置名称
  VG Name                          <==因为尚未分配出去,所以空白!
  PV Size               1.40 GB    <==就是容量说明
  Allocatable           NO         <==是否已被分配,结果是 NO
  PE Size (KByte)       0          <==在此 PV 内的 PE 大小
  Total PE              0          <==共分割出几个 PE
  Free PE               0          <==没被 LV 用掉的 PE
  Allocated PE          0          <==尚可分配出去的 PE 数量
  PV UUID               Z13Jk5-RCls-UJ8B-HzDa-Gesn-atku-rf2biN....(底下省略)....# 由於 PE 是在创建 VG 时才给予的参数,因此在这里看到的 PV 里头的 PE 都会是 0
# 而且也没有多余的 PE 可供分配 (allocatable)。


  • VG 阶段

创建 VG 及 VG 相关的命令也不少,我们来看看:

  • vgcreate :就是主要创建 VG 的命令啦!他的参数比较多,等一下介绍。

  • vgscan :搜寻系统上面是否有 VG 存在?

  • vgdisplay :显示目前系统上面的 VG 状态;

  • vgextend :在 VG 内添加额外的 PV ;

  • vgreduce :在 VG 内移除 PV;

  • vgchange :配置 VG 是否启动 (active);

  • vgremove :删除一个 VG 啊!

与 PV 不同的是, VG 的名称是自订的!我们知道 PV 的名称其实就是 partition 的装置档名, 但是这个 VG 名称则可以随便你自己取啊!在底下的例子当中,我将 VG 名称取名为 vbirdvg 。创建这个 VG 的流程是这样的:

[root@www ~]# vgcreate [-s N[mgt]] VG名称 PV名称选项与参数:
-s :后面接 PE 的大小 (size) ,单位可以是 m, g, t (大小写均可)# 1. 将 /dev/hda6-8 创建成为一个 VG,且指定 PE 为 16MB 喔!
[root@www ~]# vgcreate -s 16M vbirdvg /dev/hda{6,7,8}
  Volume group "vbirdvg" successfully created

[root@www ~]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "vbirdvg" using metadata type lvm2# 确实存在这个 vbirdvg 的 VG 啦![root@www ~]# pvscan  PV /dev/hda6   VG vbirdvg   lvm2 [1.39 GB / 1.39 GB free]
  PV /dev/hda7   VG vbirdvg   lvm2 [1.39 GB / 1.39 GB free]
  PV /dev/hda8   VG vbirdvg   lvm2 [1.39 GB / 1.39 GB free]
  PV /dev/hda9                lvm2 [1.40 GB]
  Total: 4 [5.57 GB] / in use: 3 [4.17 GB] / in no VG: 1 [1.40 GB]# 嘿嘿!发现没!有三个 PV 被用去,剩下一个 /dev/hda9 的 PV 没被用掉!
  [root@www ~]# vgdisplay
  --- Volume group ---
  VG Name               vbirdvg
  System ID
  Format                lvm2
  Metadata Areas        3
  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                3
  Act PV                3
  VG Size               4.17 GB   <==整体的 VG 容量有这么大
  PE Size               16.00 MB  <==内部每个 PE 的大小  Total PE              267       <==总共的 PE 数量共有这么多!
  Alloc PE / Size       0 / 0
  Free  PE / Size       267 / 4.17 GB
  VG UUID               4VU5Jr-gwOq-jkga-sUPx-vWPu-PmYm-dZH9EO# 最后那三行指的就是 PE 能够使用的情况!由於尚未切出 LV,因此所有的 PE 
# 均可自由使用。

这样就创建一个 VG 了!假设我们要添加这个 VG 的容量,因为我们还有 /dev/hda9 嘛!此时你可以这样做:

# 2. 将剩余的 PV (/dev/hda9) 丢给 vbirdvg 吧!
[root@www ~]# vgextend vbirdvg /dev/hda9
  Volume group "vbirdvg" successfully extended

[root@www ~]# vgdisplay....(前面省略)....
  VG Size               5.56 GB
  PE Size               16.00 MB  Total PE              356
  Alloc PE / Size       0 / 0
  Free  PE / Size       356 / 5.56 GB
  VG UUID               4VU5Jr-gwOq-jkga-sUPx-vWPu-PmYm-dZH9EO# 基本上,不难吧!这样就可以抽换整个 VG 的大小啊!
  • LV 阶段

创造出 VG 这个大磁碟之后,再来就是要创建分割区啦!这个分割区就是所谓的 LV 罗!假设我要将刚刚那个 vbirdvg 磁碟,分割成为 vbirdlv ,整个 VG 的容量都被分配到 vbirdlv 里面去!先来看看能使用的命令后,就直接工作了先!

  • lvcreate :创建 LV 啦!

  • lvscan :查询系统上面的 LV ;

  • lvdisplay :显示系统上面的 LV 状态啊!

  • lvextend :在 LV 里面添加容量!

  • lvreduce :在 LV 里面减少容量;

  • lvremove :删除一个 LV !

  • lvresize :对 LV 进行容量大小的调整!

[root@www ~]# lvcreate [-L N[mgt]] [-n LV名称] VG名称[root@www ~]# lvcreate [-l N] [-n LV名称] VG名称选项与参数:
-L  :后面接容量,容量的单位可以是 M,G,T 等,要注意的是,最小单位为 PE,
      因此这个数量必须要是 PE 的倍数,若不相符,系统会自行计算最相近的容量。
-l  :后面可以接 PE 的『个数』,而不是数量。若要这么做,得要自行计算 PE 数。
-n  :后面接的就是 LV 的名称啦!
更多的说明应该可以自行查阅吧! man lvcreate # 1. 将整个 vbirdvg 通通分配给 vbirdlv 啊,要注意, PE 共有 356 个。
[root@www ~]# lvcreate -l 356 -n vbirdlv vbirdvg
  Logical volume "vbirdlv" created# 由於本案例中每个 PE 为 16M ,因此上述的命令也可以使用如下的方式来创建:
# lvcreate -L 5.56G -n vbirdlv vbirdvg
[root@www ~]# ll /dev/vbirdvg/vbirdlvlrwxrwxrwx 1 root root 27 Mar 11 16:49 /dev/vbirdvg/vbirdlv ->
/dev/mapper/vbirdvg-vbirdlv# 看见了没有啊!这就是我们最重要的一个玩意儿了!
[root@www ~]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdlv  <==这个才是 LV 的全名!
  VG Name                vbirdvg
  LV UUID                8vFOPG-Jrw0-Runh-ug24-t2j7-i3nA-rPEyq0
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                5.56 GB               <==这个 LV 的容量这么大!
  Current LE             356
  Segments               4
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

如此一来,整个 partition 也准备好啦!接下来,就是针对这个 LV 来处理啦!要特别注意的是, VG 的名称为 vbirdvg , 但是 LV 的名称必须使用全名!亦即是 /dev/vbirdvg/vbirdlv 才对喔! 后续的处理都是这样的!这点初次接触 LVM 的朋友很容易搞错!


  • 文件系统阶段

# 1. 格式化、挂载与观察我们的 LV 吧!
[root@www ~]# mkfs -t ext3 /dev/vbirdvg/vbirdlv <==注意 LV 全名!
[root@www ~]# mkdir /mnt/lvm
[root@www ~]# mount /dev/vbirdvg/vbirdlv /mnt/lvm
[root@www ~]# dfFilesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2              9920624   3858984   5549572  42% /
/dev/hda3              4956316   1056996   3643488  23% /home
/dev/hda1               101086     21408     74459  23% /boot
tmpfs                   371332         0    371332   0% /dev/shm/dev/mapper/vbirdvg-vbirdlv
                       5741020    142592   5306796   3% /mnt/lvm

其实 LV 的名称建置成为 /dev/vbirdvg/vbirdlv 是为了让使用者直觉式的找到我们所需要的数据, 实际上 LVM 使用的装置是放置到 /dev/mapper/ 目录下的!所以你才会看到上表当中的特殊字体部分。 透过这样的功能,我们现在已经建置好一个 LV 了!你可以自由的应用 /mnt/lvm 内的所有资源!