第十五章、磁碟配额(Quota)与进阶文件系统管理

最近升级日期:2009/09/10
如果您的 Linux 服务器有多个用户经常存取数据时,为了维护所有使用者在硬盘容量的公平使用,磁碟配额 (Quota) 就是一项非常有用的工具!另外,如果你的用户常常抱怨磁碟容量不够用,那么更进阶的文件系统就得要学习学习。 本章我们会介绍磁盘阵列 (RAID) 及逻辑卷轴文件系统 (LVM),这些工具都可以帮助你管理与维护使用者可用的磁碟容量喔!


磁碟配额 (Quota) 的应用与实作


Quota 这个玩意儿就字面上的意思来看,就是有多少『限额』的意思啦!如果是用在零用钱上面, 就是类似『有多少零用钱一个月』的意思之类的。如果是在计算机主机的磁碟使用量上呢?以 Linux 来说,就是有多少容量限制的意思罗。我们可以使用 quota 来让磁碟的容量使用较为公平, 底下我们会介绍什么是 quota ,然后以一个完整的范例来介绍 quota 的实作喔!


什么是 Quota


在 Linux 系统中,由於是多人多工的环境,所以会有多人共同使用一个磁盘空间的情况发生, 如果其中有少数几个使用者大量的占掉了磁盘空间的话,那势必压缩其他使用者的使用权力! 因此管理员应该适当的限制硬盘的容量给使用者,以妥善的分配系统资源!避免有人抗议呀!

举例来说,我们使用者的默认家目录都是在 /home 底下,如果 /home 是个独立的 partition , 假设这个分割槽有 10G 好了,而 /home 底下共有 30 个帐号,也就是说,每个使用者平均应该会有 333MB 的空间才对。 偏偏有个使用者在他的家目录底下塞了好多只影片,占掉了 8GB 的空间,想想看,是否造成其他正常使用者的不便呢? 如果想要让磁碟的容量公平的分配,这个时候就得要靠 quota 的帮忙罗!


  • Quota 的一般用途

quota 比较常使用的几个情况是:

  • 针对 WWW server ,例如:每个人的网页空间的容量限制!
  • 针对 mail server,例如:每个人的邮件空间限制。
  • 针对 file server,例如:每个人最大的可用网络磁盘空间 (教学环境中最常见!)

上头讲的是针对网络服务的设计,如果是针对 Linux 系统主机上面的配置那么使用的方向有底下这一些:

  • 限制某一群组所能使用的最大磁碟配额 (使用群组限制)
    你可以将你的主机上的使用者分门别类,有点像是目前很流行的付费与免付费会员制的情况, 你比较喜好的那一群的使用配额就可以给高一些!呵呵! ^_^...

  • 限制某一使用者的最大磁碟配额 (使用使用者限制)
    在限制了群组之后,你也可以再继续针对个人来进行限制,使得同一群组之下还可以有更公平的分配!

  • 以 Link 的方式,来使邮件可以作为限制的配额 (更改 /var/spool/mail 这个路径)
    如果是分为付费与免付费会员的『邮件主机系统』,是否需要重新再规划一个硬盘呢? 也不需要啦!直接使用 Link 的方式指向 /home (或者其他已经做好的 quota 磁碟) 就可以啦! 这通常是用在原本磁盘分区的规划不好,但是却又不想要更动原有主机架构的情况中啊!

大概有这些实际的用途啦!


  • Quota 的使用限制

虽然 quota 很好用,但是使用上还是有些限制要先了解的:

  • 仅能针对整个 filesystem:
    quota 实际在运行的时候,是针对『整个 filesystem』进行限制的, 例如:如果你的 /dev/sda5 是挂载在 /home 底下,那么在 /home 底下的所有目录都会受到限制!

  • 核心必须支持 quota :
    Linux 核心必须有支持 quota 这个功能才行:如果你是使用 CentOS 5.x 的默认核心, 嘿嘿!那恭喜你了,你的系统已经默认有支持 quota 这个功能罗!如果你是自行编译核心的, 那么请特别留意你是否已经『真的』开启了 quota 这个功能?否则底下的功夫将全部都视为『白工』。

  • Quota 的记录档:
    目前新版的 Linux distributions 使用的是 Kernel 2.6.xx 的核心版本,这个核心版本支持新的 quota 模块,使用的默认文件 (aquota.user, aquota.group )将不同於旧版本的 quota.user, quota.group ! (多了一个 a 呦!) 而由旧版本的 quota 可以藉由 convertquota 这个程序来转换呢!

  • 只对一般身份使用者有效:
    这就有趣了!并不是所有在 Linux 上面的帐号都可以配置 quota 呢,例如 root 就不能配置 quota , 因为整个系统所有的数据几乎都是他的啊! ^_^

所以罗,你不能针对『某个目录』来进行 Quota 的设计,但你可以针对『某个文件系统 (filesystem) 』来配置。 如果不明白目录与挂载点还有文件系统的关系,请回到第八章去瞧瞧再回来!


  • Quota 的规范配置项目:

quota 这玩意儿针对整个 filesystem 的限制项目主要分为底下几个部分:

  • 容量限制或文件数量限制 (block 或 inode):

    我们在第八章谈到文件系统中,说到文件系统主要规划为存放属性的 inode 与实际文件数据的 block 区块,Quota 既然是管理文件系统,所以当然也可以管理 inode 或 block 罗! 这两个管理的功能为:

    • 限制 inode 用量:可以管理使用者可以创建的『文件数量』;
    • 限制 block 用量:管理使用者磁碟容量的限制,较常见为这种方式。

  • 柔性劝导与硬性规定 (soft/hard):

    既然是规范,当然就有限制值。不管是 inode/block ,限制值都有两个,分别是 soft 与 hard。 通常 hard 限制值要比 soft 还要高。举例来说,若限制项目为 block ,可以限制 hard 为 500MBytes 而 soft 为 400MBytes。这两个限值的意义为:

    • hard:表示使用者的用量绝对不会超过这个限制值,以上面的配置为例, 使用者所能使用的磁碟容量绝对不会超过 500Mbytes ,若超过这个值则系统会锁住该用户的磁碟使用权;

    • soft:表示使用者在低於 soft 限值时 (此例中为 400Mbytes),可以正常使用磁碟,但若超过 soft 且低於 hard 的限值 (介於 400~500Mbytes 之间时),每次使用者登陆系统时,系统会主动发出磁碟即将爆满的警告信息, 且会给予一个宽限时间 (grace time)。不过,若使用者在宽限时间倒数期间就将容量再次降低於 soft 限值之下, 则宽限时间会停止。

  • 会倒数计时的宽限时间 (grace time):

    刚刚上面就谈到宽限时间了!这个宽限时间只有在使用者的磁碟用量介於 soft 到 hard 之间时,才会出现且会倒数的一个咚咚! 由於达到 hard 限值时,使用者的磁碟使用权可能会被锁住。为了担心使用者没有注意到这个磁碟配额的问题, 因此设计了 soft 。当你的磁碟用量即将到达 hard 且超过 soft 时,系统会给予警告,但也会给一段时间让使用者自行管理磁碟。 一般默认的宽限时间为七天,如果七天内你都不进行任何磁碟管理,那么 soft 限制值会即刻取代 hard 限值来作为 quota 的限制

    以上面配置的例子来说,假设你的容量高达 450MBytes 了,那七天的宽限时间就会开始倒数, 若七天内你都不进行任何删除文件的动作来替你的磁碟用量瘦身, 那么七天后你的磁碟最大用量将变成 400MBytes (那个 soft 的限制值),此时你的磁碟使用权就会被锁住而无法新增文件了。

整个 soft, hard, grace time 的相关性我们可以用底下的图示来说明:

soft, hard, grace time 的相关性
图 1.1.1、soft, hard, grace time 的相关性

图中的长条图为使用者的磁碟容量,soft/hard 分别是限制值。只要小於 400M 就一切 OK , 若高於 soft 就出现 grace time 并倒数且等待使用者自行处理,若到达 hard 的限制值, 那我们就搬张小板凳等著看好戏啦!嘿嘿!^_^!这样图示有清楚一点了吗?


一个 Quota 实作范例


坐而言不如起而行啊,所以这里我们使用一个范例来设计一下如何处理 Quota 的配置流程。

  • 目的与帐号:现在我想要让我的专题生五个为一组,这五个人的帐号分别是 myquota1, myquota2, myquota3, myquota4, myquota5,这五个用户的口令都是 password ,且这五个用户所属的初始群组都是 myquotagrp 。 其他的帐号属性则使用默认值。

  • 帐号的磁碟容量限制值:我想让这五个用户都能够取得 300MBytes 的磁碟使用量(hard),文件数量则不予限制。 此外,只要容量使用率超过 250MBytes ,就予以警告 (soft)。

  • 群组的限额:由於我的系统里面还有其他用户存在,因此我仅承认 myquotagrp 这个群组最多仅能使用 1GBytes 的容量。 这也就是说,如果 myquota1, myquota2, myquota3 都用了 280MBytes 的容量了,那么其他两人最多只能使用 (1000MB - 280x3 = 160MB) 的磁碟容量罗!这就是使用者与群组同时配置时会产生的后果。

  • 宽限时间的限制:最后,我希望每个使用者在超过 soft 限制值之后,都还能够有 14 天的宽限时间。

好了,那你怎么规范帐号以及相关的 Quota 配置呢?首先,在这个小节我们先来将帐号相关的属性与参数搞定再说吧!

# 制作帐号环境时,由於有五个帐号,因此鸟哥使用 script 来创建环境!
[root@www ~]# vi addaccount.sh
#!/bin/bash
# 使用 script 来创建实验 quota 所需的环境
groupadd myquotagrp
for username in myquota1 myquota2 myquota3 myquota4 myquota5
do
	useradd -g myquotagrp $username
	echo "password" | passwd --stdin $username
done

[root@www ~]# sh addaccount.sh

接下来,就让我们来实作 Quota 的练习吧!


实作 Quota 流程-1:文件系统支持


前面我们就谈到,要使用 Quota 必须要核心与文件系统支持才行!假设你已经使用了默认支持 Quota 的核心, 那么接下来就是要启动文件系统的支持啦!不过,由於 Quota 仅针对整个文件系统来进行规划,所以我们得先查一下, /home 是否是个独立的 filesystem 呢?

[root@www ~]# df -h /home
Filesystem     Size  Used Avail Use% Mounted on
/dev/hda3      4.8G  740M  3.8G  17% /home  <==鸟哥主机的 /home 确实是独立的!

[root@www ~]# mount | grep home
/dev/hda3 on /home type ext3 (rw)

从上面的数据来看,鸟哥这部主机的 /home 确实是独立的 filesystem,因此可以直接限制 /dev/hda3 。 如果你的系统的 /home 并非独立的文件系统,那么可能就得要针对根目录 (/) 来规范了!不过,不太建议在根目录配置 Quota。 此外,由於 VFAT 文件系统并不支持 Linux Quota 功能,所以我们得要使用 mount 查询一下 /home 的文件系统为何? 看起来是 Linux 传统的 ext2/ext3 ,这种文件系统肯定有支持 Quota 啦!没问题!

如果只是想要在这次启动中实验 Quota ,那么可以使用如下的方式来手动加入 quota 的支持:

[root@www ~]# mount -o remount,usrquota,grpquota /home
[root@www ~]# mount | grep home
/dev/hda3 on /home type ext3 (rw,usrquota,grpquota)
# 重点就在於 usrquota, grpquota !注意写法!

事实上,当你重新挂载时,系统会同步升级 /etc/mtab 这个文件, 所以你必须要确定 /etc/mtab 已经加入 usrquota, grpquota 的支持到你所想要配置的文件系统中。 另外也要特别强调,使用者与群组的 quota 文件系统支持参数分别是:usrquota, grpquota !千万不要写错了!这一点非常多初接触 Quota 的朋友常常搞错。

不过手动挂载的数据在下次重新挂载就会消失,因此最好写入配置档中啊!在鸟哥这部主机的案例中, 我可以直接修改 /etc/fstab 成为底下这个样子:

[root@www ~]# vi /etc/fstab
LABEL=/home   /home  ext3   defaults,usrquota,grpquota  1 2
# 其他项目鸟哥并没有列出来!重点在於第四栏位!於 default 后面加上两个参数!

[root@www ~]# umount /home
[root@www ~]# mount -a
[root@www ~]# mount | grep home
/dev/hda3 on /home type ext3 (rw,usrquota,grpquota)

还是要再次的强调,修改完 /etc/fstab 后,务必要测试一下!若有发生错误得要赶紧处理! 因为这个文件如果修改错误,是会造成无法启动完全的情况啊!切记切记!最好使用 vim 来修改啦! 因为会有语法的检验,就不会让你写错字了!启动文件系统的支持后,接下来让我们创建起 quota 的记录档吧!


实作 Quota 流程-2:创建 quota 记录档


其实 Quota 是透过分析整个文件系统中,每个使用者(群组)拥有的文件总数与总容量, 再将这些数据记录在该文件系统的最顶层目录,然后在该记录档中再使用每个帐号(或群组)的限制值去规范磁碟使用量的。 所以啦,建置这个 Quota 记录档就显的非常的重要。扫瞄有支持 Quota 参数 (usrquota, grpquota) 的文件系统, 就使用 quotacheck 这个命令!这个命令的语法如下:


  • quotacheck :扫瞄文件系统并创建 Quota 的记录档
[root@www ~]# quotacheck [-avugfM] [/mount_point]
选项与参数:
-a  :扫瞄所有在 /etc/mtab 内,含有 quota 支持的 filesystem,加上此参数后, 
      /mount_point 可不必写,因为扫瞄所有的 filesystem 了嘛!
-u  :针对使用者扫瞄文件与目录的使用情况,会创建 aquota.user
-g  :针对群组扫瞄文件与目录的使用情况,会创建 aquota.group
-v  :显示扫瞄过程的资讯;
-f  :强制扫瞄文件系统,并写入新的 quota 配置档 (危险)
-M  :强制以读写的方式扫瞄文件系统,只有在特殊情况下才会使用。

quotacheck 的选项你只要记得『 -avug 』一起下达即可!那个 -f 与 -M 是在文件系统可能已经启动 quota 了, 但是你还想要重新扫瞄文件系统时,系统会要求你加入那两个选项啦 (担心有其他人已经使用 quota 中)!平时没必要不要加上那两个项目。好了,那就让我们来处理我们的任务吧!

# 针对整个系统含有 usrquota, grpquota 参数的文件系统进行 quotacheck 扫瞄
[root@www ~]# quotacheck -avug
quotacheck: Scanning /dev/hda3 [/home] quotacheck: Cannot stat old user quota
file: No such file or directory <==有找到文件系统,但尚未制作记录档!
quotacheck: Cannot stat old group quota file: No such file or directory
quotacheck: Cannot stat old user quota file: No such file or directory
quotacheck: Cannot stat old group quota file: No such file or directory
done  <==上面三个错误只是说明记录档尚未创建而已,可以忽略不理!
quotacheck: Checked 130 directories and 107 files <==实际搜寻结果
quotacheck: Old file not found.
quotacheck: Old file not found.
# 若运行这个命令却出现如下的错误信息,表示你没有任何文件系统有启动 quota 支持!
# quotacheck: Can't find filesystem to check or filesystem not mounted with 
# quota option.

[root@www ~]# ll -d /home/a*
-rw------- 1 root root 8192 Mar  6 11:58 /home/aquota.group
-rw------- 1 root root 9216 Mar  6 11:58 /home/aquota.user
# 在鸟哥的案例中,/home 独立的文件系统,因此搜寻结果会将两个记录档放在 
# /home 底下。这两个文件就是 Quota 最重要的资讯了!

这个命令只要进行到这里就够了,不要反覆的进行!因为等一下我们会启动 quota 功能,若启动后你还要进行 quotacheck , 系统会担心破坏原有的记录档,所以会产生一些错误信息警告你。如果你确定没有任何人在使用 quota 时, 可以强制重新进行 quotacheck 的动作。强制运行的情况可以使用如下的选项功能:

# 如果因为特殊需求需要强制扫瞄已挂载的文件系统时
[root@www ~]# quotacheck -avug -mf
quotacheck: Scanning /dev/hda3 [/home] done
quotacheck: Checked 130 directories and 109 files
# 数据要简洁很多!因为有记录档存在嘛!所以警告信息不会出现!

这样记录档就创建起来了!你不用手动去编辑那两个文件~因为那两个文件是 quota 自己的数据档,并不是纯文字档啦! 且该文件会一直变动,这是因为当你对 /home 这个文件系统进行操作时,你操作的结果会影响磁碟吧! 所以当然会同步记载到那两个文件中啦!所以要创建 aquota.user, aquota.group,记得使用的是 quotacheck 命令! 不是手动编辑的喔!


实作 Quota 流程-3:Quota 启动、 关闭与限制值配置

制作好 Quota 配置档之后,接下来就是要启动 quota 了!启动的方式很简单!使用 quotaon ,至於关闭就用 quotaoff 即可


  • quotaon :启动 quota 的服务
[root@www ~]# quotaon [-avug]
[root@www ~]# quotaon [-vug] [/mount_point]
选项与参数:
-u  :针对使用者启动 quota (aquota.user)
-g  :针对群组启动 quota (aquota.group)
-v  :显示启动过程的相关信息;
-a  :根据 /etc/mtab 内的 filesystem 配置启动有关的 quota ,若不加 -a 的话,
      则后面就需要加上特定的那个 filesystem 喔!

# 由於我们要启动 user/group 的 quota ,所以使用底下的语法即可
[root@www ~]# quotaon -auvg
/dev/hda3 [/home]: group quotas turned on
/dev/hda3 [/home]: user quotas turned on

# 特殊用法,假如你的启动 /var 的 quota 支持,那么仅启动 user quota 时
[root@www ~]# quotaon -uv /var

这个『 quotaon -auvg 』的命令几乎只在第一次启动 quota 时才需要进行!因为下次等你重新启动系统时, 系统的 /etc/rc.d/rc.sysinit 这个初始化脚本就会自动的下达这个命令了!因此你只要在这次实例中进行一次即可, 未来都不需要自行启动 quota ,因为 CentOS 5.x 系统会自动帮你搞定他!


  • quotaoff :关闭 quota 的服务
[root@www ~]# quotaoff [-a]
[root@www ~]# quotaoff [-ug] [/mount_point]
选项与参数:
-a  :全部的 filesystem 的 quota 都关闭 (根据 /etc/mtab)
-u  :仅针对后面接的那个 /mount_point 关闭 user quota
-g  :仅针对后面接的那个 /mount_point 关闭 group quota

这个命令就是关闭了 quota 的支持!我们这里需要练习 quota 实作,所以这里请不要关闭他喔! 接下来让我们开始来配置使用者与群组的 quota 限额吧!


  • edquota :编辑帐号/群组的限值与宽限时间

edquota 是 edit quota 的缩写,所以就是用来编辑使用者或者是群组限额的命令罗。我们先来看看 edquota 的语法吧, 看完后再来实际操作一下。

[root@www ~]# edquota [-u username] [-g groupname]
[root@www ~]# edquota -t  <==修改宽限时间
[root@www ~]# edquota -p 范本帐号 -u 新帐号
选项与参数:
-u  :后面接帐号名称。可以进入 quota 的编辑画面 (vi) 去配置 username 的限制值;
-g  :后面接群组名称。可以进入 quota 的编辑画面 (vi) 去配置 groupname 的限制值;
-t  :可以修改宽限时间。
-p  :复制范本。那个 范本帐号 为已经存在并且已配置好 quota 的使用者,
      意义为『将 范本帐号 这个人的 quota 限制值复制给 新帐号 』!

好了,先让我们来看看当进入 myquota1 的限额配置时,会出现什么画面:

范例一:配置 dmtsai 这个使用者的 quota 限制值
[root@www ~]# edquota -u myquota1
Disk quotas for user myquota1 (uid 710):
  Filesystem    blocks  soft   hard  inodes  soft  hard
  /dev/hda3         80     0      0      10     0     0

上头第一行在说明针对哪个帐号 (myquota1) 进行 quota 的限额配置,第二行则是标头行,里面共分为七个栏位, 七个栏位分别的意义为:

  1. 文件系统 (filesystem):说明该限制值是针对哪个文件系统 (或 partition);
  2. 磁碟容量 (blocks):这个数值是 quota 自己算出来的,单位为 Kbytes,请不要更动他;
  3. soft:磁碟容量 (block) 的 soft 限制值,单位亦为 KB
  4. hard:block 的 hard 限制值,单位 KB;
  5. 文件数量 (inodes):这是 quota 自己算出来的,单位为个数,请不要更动他;
  6. soft:inode 的 soft 限制值;
  7. hard:inode 的 hard 限制值;

当 soft/hard 为 0 时,表示没有限制的意思。好,依据我们的范例说明,我们需要配置的是 blocks 的 soft/hard ,至於 inode 则不要去更动他!因此上述的画面我们将他改成如下的模样:

Tips:
在 edquota 的画面中,每一行只要保持七个栏位就可以了,并不需要排列整齐的!
鸟哥的图示
Disk quotas for user myquota1 (uid 710):
  Filesystem    blocks    soft    hard  inodes  soft  hard
  /dev/hda3         80  250000  300000      10     0     0
# 鸟哥使用 1000 去近似 1024 的倍数!比较好算啦!然后就可以储存后离开罗!

配置完成之后,我们还有其他 5 个用户要配置,由於配置值都一样,此时可以使用 quota 复制喔!

# 将 myquota1 的限制值复制给其他四个帐号
[root@www ~]# edquota -p myquota1 -u myquota2
[root@www ~]# edquota -p myquota1 -u myquota3
[root@www ~]# edquota -p myquota1 -u myquota4
[root@www ~]# edquota -p myquota1 -u myquota5

这样就方便多了!然后,赶紧更改一下群组的 quota 限额吧!

[root@www ~]# edquota -g myquotagrp
Disk quotas for group myquotagrp (gid 713):
  Filesystem    blocks    soft     hard  inodes  soft  hard
  /dev/hda3        400  900000  1000000      50     0     0
# 记得,单位为 KB 喔!

最后,将宽限时间给他改成 14 天吧!

# 宽限时间原本为 7 天,将他改成 14 天吧!
[root@www ~]# edquota -t
Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
  Filesystem         Block grace period     Inode grace period
  /dev/hda3                14days                  7days
# 原本是 7days ,我们将他给改为 14days 喔!

透过这个简单的小步骤,我们已经将使用者/群组/宽限时间都配置妥当!接下来就是观察到底配置有没有生效啦!


实作 Quota 流程-4:Quota 限制值的报表

quota 的报表主要有两种模式,一种是针对每个个人或群组的 quota 命令,一个是针对整个文件系统的 repquota 命令。 我们先从较简单的 quota 来介绍!你也可以顺道看看你的配置值对不对啊!


  • quota :单一用户的 quota 报表
[root@www ~]# quota [-uvs] [username]
[root@www ~]# quota [-gvs] [groupname]
选项与参数:
-u  :后面可以接 username ,表示显示出该使用者的 quota 限制值。若不接 username 
      ,表示显示出运行者的 quota 限制值。
-g  :后面可接 groupname ,表示显示出该群组的 quota 限制值。
-v  :显示每个用户在 filesystem 的 quota 值;
-s  :使用 1024 为倍数来指定单位,会显示如 M 之类的单位!

# 直接使用 quota 去显示出 myquota1 与 myquota2 的限额
[root@www ~]# quota -uvs myquota1 myquota2
Disk quotas for user myquota1 (uid 710):
   Filesystem  blocks  quota  limit   grace   files   quota   limit   grace
    /dev/hda3      80   245M   293M              10       0       0
Disk quotas for user myquota2 (uid 711):
   Filesystem  blocks  quota  limit   grace   files   quota   limit   grace
    /dev/hda3      80   245M   293M              10       0       0
# 这个命令显示出来的数据跟 edquota 几乎是一模一样的!只是多了个 grace 项目。
# 你会发现 grace 底下没有任何数据,这是因为我们的使用量 (80) 尚未超过 soft

# 显示出 myquotagrp 的群组限额
[root@www ~]# quota -gvs myquotagrp
Disk quotas for group myquotagrp (gid 713):
   Filesystem  blocks  quota  limit   grace   files   quota   limit   grace
    /dev/hda3     400   879M   977M              50       0       0

由於使用常见的 K, M, G 等单位比较好算,因此上头我们使用了『 -s 』的选项,就能够以 M 为单位显示了。 不过由於我们使用 edquota 配置限额时,使用的是近似值 (1000) 而不是实际的 1024 倍数, 所以看起来会有点不太一样喔!由於 quota 仅能针对某些用户显示报表,如果要针对整个 filesystem 列出报表时, 那个可爱的 repquota 就派上用场啦!


  • repquota :针对文件系统的限额做报表
[root@www ~]# repquota -a [-vugs]
选项与参数:
-a  :直接到 /etc/mtab 搜寻具有 quota 标志的 filesystem ,并报告 quota 的结果;
-v  :输出的数据将含有 filesystem 相关的细部资讯;
-u  :显示出使用者的 quota 限值 (这是默认值);
-g  :显示出个别群组的 quota 限值。
-s  :使用 M, G 为单位显示结果

# 查询本案例中所有使用者的 quota 限制情况:
[root@www ~]# repquota -auvs
*** Report for user quotas on device /dev/hda3    <==针对 /dev/hda3
Block grace time: 14days; Inode grace time: 7days <==block 宽限时间为 14 天
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --    651M       0       0              5     0     0
myquota1  --      80    245M    293M             10     0     0
myquota2  --      80    245M    293M             10     0     0
myquota3  --      80    245M    293M             10     0     0
myquota4  --      80    245M    293M             10     0     0
myquota5  --      80    245M    293M             10     0     0

Statistics:  <==这是所谓的系统相关资讯,用 -v 才会显示
Total blocks: 9
Data blocks: 2
Entries: 22
Used average: 11.000000

根据这些资讯,您就可以知道目前的限制情况罗! ^_^!怎样, Quota 很简单吧!你可以赶紧针对你的系统配置一下磁碟使用的守则,让你的用户不会抱怨磁碟怎么老是被耗光!


实作 Quota 流程-5:测试与管理


Quota 到底有没有效果?测试看看不就知道了?让我们使用 myquota1 去测试看看,如果创建一个大文件时, 整个系统会便怎样呢?

# 测试一:利用 myquota1 的身份,建置一个 270MB 的大文件,并观察 quota 结果!
[myquota1@www ~]$ dd if=/dev/zero of=bigfile bs=1M count=270
hda3: warning, user block quota exceeded.
270+0 records in
270+0 records out
283115520 bytes (283 MB) copied, 3.20282 seconds, 88.4 MB/s
# 注意看,我是使用 myquota1 的帐号去进行 dd 命令的喔!不要恶搞啊!
# 然后你可以发现出现一个 warning 的信息喔!接下来看看报表。

[root@www ~]# repquota -auv 
*** Report for user quotas on device /dev/hda3
Block grace time: 14days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
myquota1  +-  276840  250000  300000 13days      11     0     0
# 这个命令则是利用 root 去查阅的!
# 你可以发现 myquota1 的 grace 出现!并且开始倒数了!

# 测试二:再创建另外一个大文件,让总容量超过 300M !
[myquota1@www ~]$ dd if=/dev/zero of=bigfile2 bs=1M count=300
hda3: write failed, user block limit reached.
dd: writing `bigfile2': Disk quota exceeded <==看!错误信息不一样了!
23+0 records in  <==没办法写入了!所以只记录 23 笔
22+0 records out
23683072 bytes (24 MB) copied, 0.260081 seconds, 91.1 MB/s

[myquota1@www ~]$ du -sk
300000  .  <==果然是到极限了!

此时 myquota1 可以开始处理他的文件系统了!如果不处理的话,最后宽限时间会归零,然后出现如下的画面:

[root@www ~]# repquota -au
*** Report for user quotas on device /dev/hda3
Block grace time: 00:01; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
myquota1  +-  300000  250000  300000   none      11     0     0
# 倒数整个归零,所以 grace 的部分就会变成 none 啦!不继续倒数

其实倒数归零也不会有什么特殊的意外啦!别担心!只是如果你的磁碟使用量介於 soft/hard 之间时, 当倒数归零那么 soft 的值会变成严格限制,此时你就没有多余的容量可以使用了。如何解决? 就登陆系统去删除文件即可啦!没有想像中那么可怕啦!问题是,使用者通常傻傻分不清楚到底系统出了什么问题, 所以我们可能需要寄送一些警告信 (email) 给用户比较妥当。那么如何处理呢?透过 warnquota 来处置即可。


  • warnquota :对超过限额者发出警告信

warnquota字面上的意义就是 quota 的警告 (warn) 嘛!那么这东西有什么用呢?他可以依据 /etc/warnquota.conf 的配置,然后找出目前系统上面 quota 用量超过 soft (就是有 grace time 出现的那些家伙) 的帐号,透过 email 的功能将警告信件发送到使用者的电子邮件信箱。 warnquota 并不会自动运行,所以我们需要手动去运行他。单纯运行『 warnquota 』之后,他会发送两封信出去, 一封给 myquota1 一封给 root !

[root@www ~]# warnquota
# 完全不会出现任何信息!没有信息就是『好信息』! ^_^

[root@www ~]# mail
 N329 root@www.vbird.tsai   Fri Mar  6 16:10  27/1007  "NOTE: ....
& 329   <==因为新信件在第 329 封之故
From root@www.vbird.tsai  Fri Mar  6 16:10:18 2009
Date: Fri, 6 Mar 2009 16:10:17 +0800
From: root 
Reply-To: root@myhost.com
Subject: NOTE: You are exceeding your allocated disk space limits
To: myquota1@www.vbird.tsai
Cc: root@www.vbird.tsai   <==注意这三行,分别是标题、收件者与副本 (CC)。

Your disk usage has exceeded the agreed limits on this server <==问题说明
Please delete any unnecessary files on following filesystems:

/dev/hda3  <==底下这几行为发生磁碟『爆表』的资讯啦!
                        Block limits               File limits
Filesystem           used    soft    hard  grace    used  soft  hard  grace
/dev/hda3      +-  300000  250000  300000 13days      12     0     0

root@localhost  <==这个是警告信息发送者的『签名数据』啦!

& exit  <==离开 mail 程序!

运行 warnquota 可能也不会产生任何信息以及信件,因为只有当使用者的 quota 有超过 soft 时, warnquota 才会发送警告信啦!那么上表的内容中,包括标题、资讯内容说明、签名档等数据放在哪里呢? 刚刚不是讲过吗? /etc/warnquota 啦!因为上述的数据是英文,不好理解吗?没关系,你可以自己转成中文喔! 所以你可以这样处理的:

[root@www ~]# vi /etc/warnquota.conf
# 先找到底下这几行的配置值:
SUBJECT   = NOTE: You are exceeding your allocated disk space limits <==第10行
CC_TO     = "root@localhost"                                         <==第11行
MESSAGE   = Your disk usage has exceeded the agreed limits\          <==第21行
 on this server|Please delete any unnecessary files on following filesystems:|
SIGNATURE = root@localhost                                           <==第25行

# 可以将他改成如下的模样啊!
SUBJECT   = 注意:你在本系统上拥有的文件容量已经超过最大容许限额
CC_TO     = "root@localhost"  <==除非你要寄给其他人,否则这个项目可以不改
MESSAGE   = 你的磁碟容量已经超过本机的容许限额,|\
  请在如下的文件系统中,删除不必要的文件:|
SIGNATURE = 你的系统管理员 (root@localhost)
# 在 MESSAGE 内的 | 代表断行的意思,反斜线则代表连接下一行;

如果你重复运行 warnquota ,那么 myquota1 就会收到类似如下的信件内容:

Subject: 注意:你在本系统上拥有的文件容量已经超过最大容许限额
To: myquota1@www.vbird.tsai
Cc: root@www.vbird.tsai

你的磁碟容量已经超过本机的容许限额,
  请在如下的文件系统中,删除不必要的文件:

/dev/hda3

Filesystem           used    soft    hard  grace    used  soft  hard  grace
/dev/hda3      +-  300000  250000  300000   none      11     0     0

你的系统管理员 (root@localhost)

不过这个方法并不适用在 /var/spool/mail 也爆表的 quota 控管中,因为如果使用者在这个 filesystem 的容量已经爆表,那么新的信件当然就收不下来啦!此时就只能等待使用者自己发现并跑来这里删除数据, 或者是请求 root 帮忙处理罗!知道了这玩意儿这么好用,那么我们怎么让系统自动的运行 warnquota 呢? 你可以这样做:

[root@www ~]# vi /etc/cron.daily/warnquota
/usr/sbin/warnquota
# 你没有看错!只要这一行,且将运行档以绝对路径的方式写入即可!

[root@www ~]# chmod 755 /etc/cron.daily/warnquota

那么未来每天早上 4:02am 时,这个文件就会主动被运行,那么系统就能够主动的通知磁碟配额爆表的用户罗! 您瞧瞧!这玩意儿是否很好用啊!至於为何要写入上述的文件呢?留待下一章工作排程时我们再来加强介绍罗!


  • setquota :直接於命令中配置 quota 限额

如果你想要使用 script 的方法来创建大量的帐号,并且所有的帐号都在创建时就给予 quota ,那该如何是好? 其实有两个方法可以考虑:

  • 先创建一个原始 quota 帐号,再以『 edquota -p old -u new 』写入 script 中;
  • 直接以 setquota 创建用户的 quota 配置值。

不同於 edquota 是呼叫 vi 来进行配置,setquota 直接由命令输入所必须要的各项限制值。 他的语法有点像这样:

[root@www ~]# setquota [-u|-g] 名称 block(soft) block(hard) \
>  inode(soft) inode(hard) 文件系统

# 观察原始的 myquota5 限值,并给予 soft/hard 分别为 100000/200000
[root@www ~]# quota -uv myquota5
Disk quotas for user myquota5 (uid 714): 
   Filesystem blocks  quota  limit  grace files  quota  limit  grace
    /dev/hda3     80 250000 300000           10      0      0

[root@www ~]# setquota -u myquota5 100000 200000 0 0 /home

[root@www ~]# quota -uv myquota5
Disk quotas for user myquota5 (uid 714): 
   Filesystem blocks  quota  limit  grace files  quota  limit  grace
    /dev/hda3     80 100000 200000           10      0      0
# 看吧!真的有改变过来!这就是 quota 的简单脚本配置语法!


不更动既有系统的 quota 实例


想一想,如果你的主机原先没有想到要配置成为邮件主机,所以并没有规划将邮件信箱所在的 /var/spool/mail/ 目录独立成为一个 partition ,然后目前你的主机已经没有办法新增或分割出任何新的分割槽了。那我们知道 quota 是针对整个 filesystem 进行设计的,因此,你是否就无法针对 mail 的使用量给予 quota 的限制呢?

此外,如果你想要让使用者的邮件信箱与家目录的总体磁碟使用量为固定,那又该如何是好? 由於 /home 及 /var/spool/mail 根本不可能是同一个 filesystem (除非是都不分割,使用根目录,才有可能整合在一起), 所以,该如何进行这样的 quota 限制呢?

其实没有那么难啦!既然 quota 是针对整个 filesystem 来进行限制,假设你又已经有 /home 这个独立的分割槽了, 那么你只要:

  1. 将 /var/spool/mail 这个目录完整的移动到 /home 底下;
  2. 利用 ln -s /home/mail /var/spool/mail 来创建连结数据;
  3. 将 /home 进行 quota 限额配置

只要这样的一个小步骤,嘿嘿!您家主机的邮件就有一定的限额罗!当然罗!您也可以依据不同的使用者与群组来配置 quota 然后同样的以上面的方式来进行 link 的动作!嘿嘿嘿!就有不同的限额针对不同的使用者提出罗!很方便吧! ^_^

Tips:
朋友们需要注意的是,由於目前新的 distributions 大多有使用 SELinux 的机制, 因此你要进行如同上面的目录搬移时,在许多情况下可能会有使用上的限制喔!或许你得要先暂时关闭 SELinux 才能测试, 也或许你得要自行修改 SELinux 的守则才行喔!
鸟哥的图示

软件磁盘阵列 (Software RAID)


在过去鸟哥还年轻的时代,我们能使用的硬盘容量都不大,几十 GB 的容量就是大硬盘了!但是某些情况下,我们需要很大容量的储存空间, 例如鸟哥在跑的空气品质模式所输出的数据文件一个案例通常需要好几 GB ,连续跑个几个案例,磁碟容量就不够用了。 此时我该如何是好?其实可以透过一种储存机制,称为磁盘阵列 (RAID) 的就是了。这种机制的功能是什么?他有哪些等级?什么是硬件、软件磁盘阵列?Linux 支持什么样的软件磁盘阵列? 底下就让我们来谈谈!


什么是 RAID


磁盘阵列全名是『 Redundant Arrays of Inexpensive Disks, RAID 』,英翻中的意思是:容错式廉价磁盘阵列。 RAID 可以透过一个技术(软件或硬件),将多个较小的磁碟整合成为一个较大的磁碟装置; 而这个较大的磁碟功能可不止是储存而已,他还具有数据保护的功能呢。整个 RAID 由於选择的等级 (level) 不同,而使得整合后的磁碟具有不同的功能, 基本常见的 level 有这几种(注1):

  • RAID-0 (等量模式, stripe):效能最佳

这种模式如果使用相同型号与容量的磁碟来组成时,效果较佳。这种模式的 RAID 会将磁碟先切出等量的区块 (举例来说, 4KB), 然后当一个文件要写入 RAID 时,该文件会依据区块的大小切割好,之后再依序放到各个磁碟里面去。由於每个磁碟会交错的存放数据, 因此当你的数据要写入 RAID 时,数据会被等量的放置在各个磁碟上面。举例来说,你有两颗磁碟组成 RAID-0 , 当你有 100MB 的数据要写入时,每个磁碟会各被分配到 50MB 的储存量。RAID-0 的示意图如下所示:

 RAID-0 的磁碟写入示意图
图 2.1.1、 RAID-0 的磁碟写入示意图

上图的意思是,在组成 RAID-0 时,每颗磁碟 (Disk A 与 Disk B) 都会先被区隔成为小区块 (chunk)。 当有数据要写入 RAID 时,数据会先被切割成符合小区块的大小,然后再依序一个一个的放置到不同的磁碟去。 由於数据已经先被切割并且依序放置到不同的磁碟上面,因此每颗磁碟所负责的数据量都降低了!照这样的情况来看, 越多颗磁碟组成的 RAID-0 效能会越好,因为每颗负责的数据量就更低了! 这表示我的数据可以分散让多颗磁碟来储存,当然效能会变的更好啊!此外,磁碟总容量也变大了! 因为每颗磁碟的容量最终会加总成为 RAID-0 的总容量喔!

只是使用此等级你必须要自行负担数据损毁的风险,由上图我们知道文件是被切割成为适合每颗磁盘分区区块的大小, 然后再依序放置到各个磁碟中。想一想,如果某一颗磁碟损毁了,那么文件数据将缺一块,此时这个文件就损毁了。 由於每个文件都是这样存放的,因此 RAID-0 只要有任何一颗磁碟损毁,在 RAID 上面的所有数据都会遗失而无法读取

另外,如果使用不同容量的磁碟来组成 RAID-0 时,由於数据是一直等量的依序放置到不同磁碟中,当小容量磁碟的区块被用完了, 那么所有的数据都将被写入到最大的那颗磁碟去。举例来说,我用 200G 与 500G 组成 RAID-0 , 那么最初的 400GB 数据可同时写入两颗磁碟 (各消耗 200G 的容量),后来再加入的数据就只能写入 500G 的那颗磁碟中了。 此时的效能就变差了,因为只剩下一颗可以存放数据嘛!

  • RAID-1 (映射模式, mirror):完整备份

这种模式也是需要相同的磁碟容量的,最好是一模一样的磁碟啦!如果是不同容量的磁碟组成 RAID-1 时,那么总容量将以最小的那一颗磁碟为主!这种模式主要是『让同一份数据,完整的保存在两颗磁碟上头』。举例来说,如果我有一个 100MB 的文件,且我仅有两颗磁碟组成 RAID-1 时, 那么这两颗磁碟将会同步写入 100MB 到他们的储存空间去。 因此,整体 RAID 的容量几乎少了 50%。由於两颗硬盘内容一模一样,好像镜子映照出来一样, 所以我们也称他为 mirror 模式罗~

 RAID-1 的磁碟写入示意图
图 2.1.2、 RAID-1 的磁碟写入示意图

如上图所示,一份数据传送到 RAID-1 之后会被分为两股,并分别写入到各个磁碟里头去。 由於同一份数据会被分别写入到其他不同磁碟,因此如果要写入 100MB 时,数据传送到 I/O 汇流排后会被复制多份到各个磁碟, 结果就是数据量感觉变大了!因此在大量写入 RAID-1 的情况下,写入的效能可能会变的非常差 (因为我们只有一个南桥啊!)。 好在如果你使用的是硬件 RAID (磁盘阵列卡) 时,磁盘阵列卡会主动的复制一份而不使用系统的 I/O 汇流排,效能方面则还可以。 如果使用软件磁盘阵列,可能效能就不好了。

由於两颗磁碟内的数据一模一样,所以任何一颗硬盘损毁时,你的数据还是可以完整的保留下来的! 所以我们可以说, RAID-1 最大的优点大概就在於数据的备份吧!不过由於磁碟容量有一半用在备份, 因此总容量会是全部磁碟容量的一半而已。虽然 RAID-1 的写入效能不佳,不过读取的效能则还可以啦!这是因为数据有两份在不同的磁碟上面,如果多个 processes 在读取同一笔数据时, RAID 会自行取得最佳的读取平衡。

  • RAID 0+1,RAID 1+0

RAID-0 的效能佳但是数据不安全,RAID-1 的数据安全但是效能不佳,那么能不能将这两者整合起来配置 RAID 呢? 可以啊!那就是 RAID 0+1 或 RAID 1+0。所谓的 RAID 0+1 就是: (1)先让两颗磁碟组成 RAID 0,并且这样的配置共有两组; (2)将这两组 RAID 0 再组成一组 RAID 1。这就是 RAID 0+1 罗!反过来说,RAID 1+0 就是先组成 RAID-1 再组成 RAID-0 的意思。

 RAID-0+1 的磁碟写入示意图
图 2.1.3、 RAID-0+1 的磁碟写入示意图

如上图所示,Disk A + Disk B 组成第一组 RAID 0,Disk C + Disk D 组成第二组 RAID 0, 然后这两组再整合成为一组 RAID 1。如果我有 100MB 的数据要写入,则由於 RAID 1 的关系, 两组 RAID 0 都会写入 100MB,但由於 RAID 0 的关系,因此每颗磁碟仅会写入 50MB 而已。 如此一来不论哪一组 RAID 0 的磁碟损毁,只要另外一组 RAID 0 还存在,那么就能够透过 RAID 1 的机制来回复数据。

由於具有 RAID 0 的优点,所以效能得以提升,由於具有 RAID 1 的优点,所以数据得以备份。 但是也由於 RAID 1 的缺点,所以总容量会少一半用来做为备份喔!

  • RAID 5:效能与数据备份的均衡考量

RAID-5 至少需要三颗以上的磁碟才能够组成这种类型的磁盘阵列。这种磁盘阵列的数据写入有点类似 RAID-0 , 不过每个循环的写入过程中,在每颗磁碟还加入一个同位检查数据 (Parity) ,这个数据会记录其他磁碟的备份数据, 用於当有磁碟损毁时的救援。RAID-5 读写的情况有点像底下这样:

 RAID-5 的磁碟写入示意图
图 2.1.4、 RAID-5 的磁碟写入示意图

如上图所示,每个循环写入时,都会有部分的同位检查码 (parity) 被记录起来,并且记录的同位检查码每次都记录在不同的磁碟, 因此,任何一个磁碟损毁时都能够藉由其他磁碟的检查码来重建原本磁碟内的数据喔!不过需要注意的是, 由於有同位检查码,因此 RAID 5 的总容量会是整体磁碟数量减一颗。以上图为例, 原本的 3 颗磁碟只会剩下 (3-1)=2 颗磁碟的容量。而且当损毁的磁碟数量大於等於两颗时,这整组 RAID 5 的数据就损毁了。 因为 RAID 5 默认仅能支持一颗磁碟的损毁情况

在读写效能的比较上,读取的效能还不赖!与 RAID-0 有的比!不过写的效能就不见得能够添加很多! 这是因为要写入 RAID 5 的数据还得要经过计算同位检查码 (parity) 的关系。由於加上这个计算的动作, 所以写入的效能与系统的硬件关系较大!尤其当使用软件磁盘阵列时,同位检查码是透过 CPU 去计算而非专职的磁盘阵列卡, 因此效能方面还需要评估。

另外,由於 RAID 5 仅能支持一颗磁碟的损毁,因此近来还有发展出另外一种等级,就是 RAID 6 ,这个 RAID 6 则使用两颗磁碟的容量作为 parity 的储存,因此整体的磁碟容量就会少两颗,但是允许出错的磁碟数量就可以达到两颗了! 也就是在 RAID 6 的情况下,同时两颗磁碟损毁时,数据还是可以救回来!

  • Spare Disk:预备磁碟的功能:

当磁盘阵列的磁碟损毁时,就得要将坏掉的磁碟拔除,然后换一颗新的磁碟。换成新磁碟并且顺利启动磁盘阵列后, 磁盘阵列就会开始主动的重建 (rebuild) 原本坏掉的那颗磁碟数据到新的磁碟上!然后你磁盘阵列上面的数据就复原了! 这就是磁盘阵列的优点。不过,我们还是得要动手拔插硬盘,此时通常得要关机才能这么做。

为了让系统可以即时的在坏掉硬盘时主动的重建,因此就需要预备磁碟 (spare disk) 的辅助。 所谓的 spare disk 就是一颗或多颗没有包含在原本磁盘阵列等级中的磁碟,这颗磁碟平时并不会被磁盘阵列所使用, 当磁盘阵列有任何磁碟损毁时,则这颗 spare disk 会被主动的拉进磁盘阵列中,并将坏掉的那颗硬盘移出磁盘阵列! 然后立即重建数据系统。如此你的系统则可以永保安康啊!若你的磁盘阵列有支持热拔插那就更完美了! 直接将坏掉的那颗磁碟拔除换一颗新的,再将那颗新的配置成为 spare disk ,就完成了!

举例来说,鸟哥之前所待的研究室有一个磁盘阵列可允许 16 颗磁碟的数量,不过我们只安装了 10 颗磁碟作为 RAID 5。 每颗磁碟的容量为 250GB,我们用了一颗磁碟作为 spare disk ,并将其他的 9 颗配置为一个 RAID 5, 因此这个磁盘阵列的总容量为: (9-1)*250G=2000G。运行了一两年后真的有一颗磁碟坏掉了,我们后来看灯号才发现! 不过对系统没有影响呢!因为 spare disk 主动的加入支持,坏掉的那颗拔掉换颗新的,并重新配置成为 spare 后, 系统内的数据还是完整无缺的!嘿嘿!真不错!

  • 磁盘阵列的优点

说的口沫横飞,重点在哪里呢?其实你的系统如果需要磁盘阵列的话,其实重点在於:

  • 数据安全与可靠性:指的并非资讯安全,而是当硬件 (指磁碟) 损毁时,数据是否还能够安全的救援或使用之意;
  • 读写效能:例如 RAID 0 可以加强读写效能,让你的系统 I/O 部分得以改善;
  • 容量:可以让多颗磁碟组合起来,故单一文件系统可以有相当大的容量。

尤其数据的可靠性与完整性更是使用 RAID 的考量重点!毕竟硬件坏掉换掉就好了,软件数据损毁那可不是闹著玩的! 所以企业界为何需要大量的 RAID 来做为文件系统的硬件基准,现在您有点了解了吧?


software, hardware RAID


为何磁盘阵列又分为硬件与软件呢?所谓的硬件磁盘阵列 (hardware RAID) 是透过磁盘阵列卡来达成阵列的目的。 磁盘阵列卡上面有一块专门的芯片在处理 RAID 的任务,因此在效能方面会比较好。在很多任务 (例如 RAID 5 的同位检查码计算) 磁盘阵列并不会重复消耗原本系统的 I/O 汇流排,理论上效能会较佳。此外目前一般的中高阶磁盘阵列卡都支持热拔插, 亦即在不关机的情况下抽换损坏的磁碟,对於系统的复原与数据的可靠性方面非常的好用。

不过一块好的磁盘阵列卡动不动就上万元台币,便宜的在主板上面『附赠』的磁盘阵列功能可能又不支持某些高阶功能, 例如低阶主板若有磁盘阵列芯片,通常仅支持到 RAID0 与 RAID1 ,鸟哥喜欢的 RAID 5 并没有支持。 此外,操作系统也必须要拥有磁盘阵列卡的驱动程序,才能够正确的捉到磁盘阵列所产生的磁碟机!

由於磁盘阵列有很多优秀的功能,然而硬件磁盘阵列卡偏偏又贵的很~因此就有发展出利用软件来模拟磁盘阵列的功能, 这就是所谓的软件磁盘阵列 (software RAID)。软件磁盘阵列主要是透过软件来模拟阵列的任务, 因此会损耗较多的系统资源,比如说 CPU 的运算与 I/O 汇流排的资源等。不过目前我们的个人计算机实在已经非常快速了, 因此以前的速度限制现在已经不存在!所以我们可以来玩一玩软件磁盘阵列!

我们的 CentOS 提供的软件磁盘阵列为 mdadm 这套软件,这套软件会以 partition 或 disk 为磁碟的单位,也就是说,你不需要两颗以上的磁碟,只要有两个以上的分割槽 (partition) 就能够设计你的磁盘阵列了。此外, mdadm 支持刚刚我们前面提到的 RAID0/RAID1/RAID5/spare disk 等! 而且提供的管理机制还可以达到类似热拔插的功能,可以线上 (文件系统正常使用) 进行分割槽的抽换! 使用上也非常的方便呢!

另外你必须要知道的是,硬件磁盘阵列在 Linux 底下看起来就是一颗实际的大磁碟,因此硬件磁盘阵列的装置档名为 /dev/sd[a-p] ,因为使用到 SCSI 的模块之故。至於软件磁盘阵列则是系统模拟的,因此使用的装置档名是系统的装置档, 档名为 /dev/md0, /dev/md1...,两者的装置档名并不相同!不要搞混了喔!因为很多朋友常常觉得奇怪, 怎么他的 RAID 档名跟我们这里测试的软件 RAID 档名不同,所以这里特别强调说明喔!


软件磁盘阵列的配置


软件磁盘阵列的配置很简单呢!简单到让你很想笑喔!因为你只要使用一个命令即可!那就是 mdadm 这个命令。 这个命令在创建 RAID 的语法有点像这样:

[root@www ~]# mdadm --detail /dev/md0
[root@www ~]# mdadm --create --auto=yes /dev/md[0-9] --raid-devices=N \
> --level=[015] --spare-devices=N /dev/sdx /dev/hdx...
选项与参数:
--create :为创建 RAID 的选项;
--auto=yes :决定创建后面接的软件磁盘阵列装置,亦即 /dev/md0, /dev/md1...
--raid-devices=N :使用几个磁碟 (partition) 作为磁盘阵列的装置
--spare-devices=N :使用几个磁碟作为备用 (spare) 装置
--level=[015] :配置这组磁盘阵列的等级。支持很多,不过建议只要用 0, 1, 5 即可
--detail :后面所接的那个磁盘阵列装置的详细资讯

上面的语法中,最后面会接许多的装置档名,这些装置档名可以是整颗磁碟,例如 /dev/sdb , 也可以是分割槽,例如 /dev/sdb1 之类。不过,这些装置档名的总数必须要等於 --raid-devices 与 --spare-devices 的个数总和才行!鸟哥利用我的测试机来建置一个 RAID 5 的软件磁盘阵列给您瞧瞧! 首先,将系统里面过去练习过而目前用不到的分割槽通通删除掉:

[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        2302     2008093+  83  Linux
/dev/hda7            2303        2334      257008+  82  Linux swap / Solaris
/dev/hda8            2335        2353      152586   83  Linux
/dev/hda9            2354        2366      104391   83  Linux

[root@www ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2              9920624   3858800   5549756  42% /
/dev/hda1               101086     21408     74459  23% /boot
tmpfs                   371332         0    371332   0% /dev/shm
/dev/hda3              4956316   1056996   3643488  23% /home
# 从上面可以发现,我的 /dev/hda6~/dev/hda9 没有用到!将他删除看看!

[root@www ~]# fdisk /dev/hda
Command (m for help): d
Partition number (1-9): 9

Command (m for help): d
Partition number (1-8): 8

Command (m for help): d
Partition number (1-7): 7

Command (m for help): d
Partition number (1-6): 6

Command (m for help): p

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

Command (m for help): w

[root@www ~]# partprobe
# 这个动作很重要!还记得吧!将核心的 partition table 升级!

底下是鸟哥希望做成的 RAID 5 环境:

  • 利用 4 个 partition 组成 RAID 5;
  • 每个 partition 约为 1GB 大小,需确定每个 partition 一样大较佳;
  • 利用 1 个 partition 配置为 spare disk
  • 这个 spare disk 的大小与其他 RAID 所需 partition 一样大!
  • 将此 RAID 5 装置挂载到 /mnt/raid 目录下

最终我需要 5 个 1GB 的 partition 。由於鸟哥的系统仅有一颗磁碟,这颗磁碟剩余容量约 20GB 是够用的, 分割槽代号仅使用到 5 号,所以要制作成 RAID 5 应该是不成问题!接下来就是连续的建置流程罗!


  • 建置所需的磁碟装置

如前所述,我需要 5 个 1GB 的分割槽,请利用 fdisk 来建置吧!

[root@www ~]# fdisk /dev/hda
Command (m for help): n
First cylinder (2053-5005, default 2053): <==直接按下 [enter]
Using default value 2053
Last cylinder or +size or +sizeM or +sizeK (2053-5005, default 5005): +1000M
# 上述的动作请作五次!

Command (m for help): p

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        2175      987966   83  Linux
/dev/hda7            2176        2298      987966   83  Linux
/dev/hda8            2299        2421      987966   83  Linux
/dev/hda9            2422        2544      987966   83  Linux
/dev/hda10           2545        2667      987966   83  Linux
# 上面的 6~10 号,就是我们需要的 partition 罗!

Command (m for help): w

[root@www ~]# partprobe


  • 以 mdadm 建置 RAID

接下来就简单啦!透过 mdadm 来创建磁盘阵列先!

[root@www ~]# mdadm --create --auto=yes /dev/md0 --level=5 \
> --raid-devices=4 --spare-devices=1 /dev/hda{6,7,8,9,10}
# 详细的参数说明请回去前面看看罗!这里我透过 {} 将重复的项目简化!

[root@www ~]# mdadm --detail /dev/md0
/dev/md0:                                        <==RAID 装置档名
        Version : 00.90.03
  Creation Time : Tue Mar 10 17:47:51 2009       <==RAID 被创建的时间
     Raid Level : raid5                          <==RAID 等级为 RAID 5
     Array Size : 2963520 (2.83 GiB 3.03 GB)     <==此 RAID 的可用磁碟容量
  Used Dev Size : 987840 (964.85 MiB 1011.55 MB) <==每个装置的可用容量
   Raid Devices : 4                              <==用作 RAID 的装置数量
  Total Devices : 5                              <==全部的装置数量
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Tue Mar 10 17:52:23 2009
          State : clean
 Active Devices : 4                              <==启动的(active)装置数量
Working Devices : 5                              <==可动作的装置数量
 Failed Devices : 0                              <==出现错误的装置数量
  Spare Devices : 1                              <==预备磁碟的数量

         Layout : left-symmetric
     Chunk Size : 64K      <==就是图2.1.4内的小区块

           UUID : 7c60c049:57d60814:bd9a77f1:57e49c5b <==此装置(RAID)识别码
         Events : 0.2

    Number   Major   Minor   RaidDevice State
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       2       3        8        2      active sync   /dev/hda8
       3       3        9        3      active sync   /dev/hda9

       4       3       10        -      spare   /dev/hda10
# 最后五行就是这五个装置目前的情况,包括四个 active sync 一个 spare !
# 至於 RaidDevice  指的则是此 RAID 内的磁碟顺序

由於磁盘阵列的建置需要一些时间,所以你最好等待数分钟后再使用『 mdadm --detail /dev/md0 』去查阅你的磁盘阵列详细资讯! 否则有可能看到某些磁碟正在『spare rebuilding』之类的建置字样!透过上面的命令, 你就能够创建一个 RAID5 且含有一颗 spare disk 的磁盘阵列罗!非常简单吧! 除了命令之外,你也可以查阅如下的文件来看看系统软件磁盘阵列的情况:

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[4](S) hda8[2] hda7[1] hda6[0]    <==第一行
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU] <==第二行

unused devices: 

上述的数据比较重要的在特别指出的第一行与第二行部分(注2):

  • 第一行部分:指出 md0 为 raid5 ,且使用了 hda9, hda8, hda7, hda6 等四颗磁碟装置。每个装置后面的中括号 [] 内的数字为此磁碟在 RAID 中的顺序 (RaidDevice);至於 hda10 后面的 [S] 则代表 hda10 为 spare 之意。

  • 第二行:此磁盘阵列拥有 2963520 个block(每个 block 单位为 1K),所以总容量约为 3GB, 使用 RAID 5 等级,写入磁碟的小区块 (chunk) 大小为 64K,使用 algorithm 2 磁盘阵列演算法。 [m/n] 代表此阵列需要 m 个装置,且 n 个装置正常运行。因此本 md0 需要 4 个装置且这 4 个装置均正常运行。 后面的 [UUUU] 代表的是四个所需的装置 (就是 [m/n] 里面的 m) 的启动情况,U 代表正常运行,若为 _ 则代表不正常。

这两种方法都可以知道目前的磁盘阵列状态啦!


  • 格式化与挂载使用 RAID

接下来就是开始使用格式化工具啦!这部分就简单到爆!不多说了,直接进行吧!

[root@www ~]# mkfs -t ext3 /dev/md0
# 有趣吧!是 /dev/md0 做为装置被格式化呢!

[root@www ~]# mkdir /mnt/raid
[root@www ~]# mount /dev/md0 /mnt/raid
[root@www ~]# df
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/hda2        9920624   3858820   5549736  42% /
/dev/hda1         101086     21408     74459  23% /boot
tmpfs             371332         0    371332   0% /dev/shm
/dev/hda3        4956316   1056996   3643488  23% /home
/dev/md0         2916920     69952   2698792   3% /mnt/raid
# 看吧!多了一个 /dev/md0 的装置,而且真的可以让你使用呢!还不赖!


模拟 RAID 错误的救援模式


俗话说『天有不测风云、人有旦夕祸福』,谁也不知道你的磁盘阵列内的装置啥时会出差错,因此, 了解一下软件磁盘阵列的救援还是必须的!底下我们就来玩一玩救援的机制吧!首先来了解一下 mdadm 这方面的语法:

[root@www ~]# mdadm --manage /dev/md[0-9] [--add 装置] [--remove 装置] \
> [--fail 装置] 
选项与参数:
--add :会将后面的装置加入到这个 md 中!
--remove :会将后面的装置由这个 md 中移除
--fail :会将后面的装置配置成为出错的状态


  • 配置磁碟为错误 (fault)

首先,我们来处理一下,该如何让一个磁碟变成错误,然后让 spare disk 自动的开始重建系统呢?

# 0. 先复制一些东西到 /mnt/raid 去,假设这个 RAID 已经在使用了
[root@www ~]# cp -a /etc /var/log /mnt/raid
[root@www ~]# df /mnt/raid ; du -sm /mnt/raid/*
Filesystem   1K-blocks      Used Available Use% Mounted on
/dev/md0       2916920    188464   2580280   7% /mnt/raid
118     /mnt/raid/etc <==看吧!确实有数据在里面喔!
8       /mnt/raid/log
1       /mnt/raid/lost+found

# 1. 假设 /dev/hda8 这个装置出错了!实际模拟的方式:
[root@www ~]# mdadm --manage /dev/md0 --fail /dev/hda8
mdadm: set /dev/hda8 faulty in /dev/md0

[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
          State : clean, degraded, recovering
 Active Devices : 3
Working Devices : 4
 Failed Devices : 1  <==出错的磁碟有一个!
  Spare Devices : 1
....(中间省略)....
    Number   Major   Minor   RaidDevice State
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       4       3       10        2      spare rebuilding   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       5       3        8        -      faulty spare   /dev/hda8
# 看到没!这的动作要快做才会看到! /dev/hda10 启动了而 /dev/hda8 死掉了

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[4] hda8[5](F) hda7[1] hda6[0]
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/3] [UU_U]
      [>.......]  recovery =  0.8% (9088/987840) finish=14.3min speed=1136K/sec

上面的画面你得要快速的连续输入那些 mdadm 的命令才看的到!因为你的 RAID 5 正在重建系统! 若你等待一段时间再输入后面的观察命令,则会看到如下的画面了:

# 2. 已经藉由 spare disk 重建完毕的 RAID 5 情况
[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
    Number   Major   Minor   RaidDevice State
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       2       3       10        2      active sync   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       4       3        8        -      faulty spare   /dev/hda8

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[2] hda8[4](F) hda7[1] hda6[0]
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU]

看吧!又恢复正常了!真好!我们的 /mnt/raid 文件系统是完整的!并不需要卸载!很棒吧!


  • 将出错的磁碟移除并加入新磁碟

首先,我们再创建一个新的分割槽,这个分割槽要与其他分割槽一样大才好!然后再利用 mdadm 移除错误的并加入新的!

# 3. 创建新的分割槽
[root@www ~]# fdisk /dev/hda
Command (m for help): n
First cylinder (2668-5005, default 2668): <==这里按 [enter]
Using default value 2668
Last cylinder or +size or +sizeM or +sizeK (2668-5005, default 5005): +1000M

Command (m for help): w

[root@www ~]# partprobe
# 此时系统会多一个 /dev/hda11 的分割槽喔!

# 4. 加入新的拔除有问题的磁碟
[root@www ~]# mdadm --manage /dev/md0 --add /dev/hda11 --remove /dev/hda8
mdadm: added /dev/hda11
mdadm: hot removed /dev/hda8

[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       2       3       10        2      active sync   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       4       3       11        -      spare   /dev/hda11

嘿嘿!你的磁盘阵列内的数据不但一直存在,而且你可以一直顺利的运行 /mnt/raid 内的数据,即使 /dev/hda8 损毁了!然后透过管理的功能就能够加入新磁碟且拔除坏掉的磁碟!注意,这一切都是在上线 (on-line) 的情况下进行! 所以,您说这样的咚咚好不好用啊! ^_^


启动自动启动 RAID 并自动挂载


新的 distribution 大多会自己搜寻 /dev/md[0-9] 然后在启动的时候给予配置好所需要的功能。不过鸟哥还是建议你, 修改一下配置档吧! ^_^。software RAID 也是有配置档的,这个配置档在 /etc/mdadm.conf !这个配置档内容很简单, 你只要知道 /dev/md0 的 UUID 就能够配置这个文件啦!这里鸟哥仅介绍他最简单的语法:

[root@www ~]# mdadm --detail /dev/md0 | grep -i uuid
        UUID : 7c60c049:57d60814:bd9a77f1:57e49c5b
# 后面那一串数据,就是这个装置向系统注册的 UUID 识别码!

# 开始配置 mdadm.conf
[root@www ~]# vi /etc/mdadm.conf
ARRAY /dev/md0 UUID=7c60c049:57d60814:bd9a77f1:57e49c5b
#     RAID装置      识别码内容

# 开始配置启动自动挂载并测试
[root@www ~]# vi /etc/fstab
/dev/md0    /mnt/raid    ext3    defaults     1 2

[root@www ~]# umount /dev/md0; mount -a
[root@www ~]# df /mnt/raid
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/md0               2916920    188464   2580280   7% /mnt/raid
# 你得确定可以顺利挂载,并且没有发生任何错误!

如果到这里都没有出现任何问题!接下来就请 reboot 你的系统并等待看看能否顺利的启动吧! ^_^


关闭软件 RAID(重要!)


除非你未来就是要使用这颗 software RAID (/dev/md0),否则你势必要跟鸟哥一样,将这个 /dev/md0 关闭! 因为他毕竟是我们在这个测试机上面的练习装置啊!为什么要关掉他呢?因为这个 /dev/md0 其实还是使用到我们系统的磁盘分区槽, 在鸟哥的例子里面就是 /dev/hda{6,7,8,9,10,11},如果你只是将 /dev/md0 卸载,然后忘记将 RAID 关闭, 结果就是....未来你在重新分割 /dev/hdaX 时可能会出现一些莫名的错误状况啦!所以才需要关闭 software RAID 的步骤! 那如何关闭呢?也是简单到爆炸!(请注意,确认你的 /dev/md0 确实不要用且要关闭了才进行底下的玩意儿)

# 1. 先卸载且删除配置档内与这个 /dev/md0 有关的配置:
[root@www ~]# umount /dev/md0
[root@www ~]# vi /etc/fstab
/dev/md0    /mnt/raid     ext3    defaults      1 2
# 将这一行删除掉!或者是注解掉也可以!

# 2. 直接关闭 /dev/md0 的方法!
[root@www ~]# mdadm --stop /dev/md0
mdadm: stopped /dev/md0  <==不罗唆!这样就关闭了!

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
unused devices:   <==看吧!确实不存在任何阵列装置!

[root@www ~]# vi /etc/mdadm.conf
ARRAY /dev/md0 UUID=7c60c049:57d60814:bd9a77f1:57e49c5b
# 一样啦!删除他或是注解他!
Tips:
在这个练习中,鸟哥使用同一颗磁碟进行软件 RAID 的实验。不过朋友们要注意的是,如果真的要实作软件磁盘阵列, 最好是由多颗不同的磁碟来组成较佳!因为这样才能够使用到不同磁碟的读写,效能才会好! 而数据分配在不同的磁碟,当某颗磁碟损毁时数据才能够藉由其他磁碟挽救回来!这点得特别留意呢!
鸟哥的图示

逻辑卷轴管理员 (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 的相关性图示
图 3.1.1、PE 与 VG 的相关性图示

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

  • 实作流程

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

LVM 各组件的实现流程图示
图 3.1.2、 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)。

讲是很难,作是很简单!这样就将 PV 创建了两个罗!简单到不行吧! ^_^!继续来玩 VG 去!


  • 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 的大小啊!

我们多了一个装置喔!接下来为这个 vbirdvg 进行分割吧!透过 LV 功能来处理!


  • 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/vbirdlv
lrwxrwxrwx 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 ~]# df
Filesystem           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
[root@www ~]# cp -a /etc /var/log /mnt/lvm

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


放大 LV 容量


我们不是说 LVM 最大的特色就是弹性调整磁碟容量吗?好!那我们就来处理一下,如果要放大 LV 的容量时, 该如何进行完整的步骤呢?其实一点都不难喔!你只要这样做即可:

  1. 用 fdisk 配置新的具有 8e system ID 的 partition
  2. 利用 pvcreate 建置 PV
  3. 利用 vgextend 将 PV 加入我们的 vbirdvg
  4. 利用 lvresize 将新加入的 PV 内的 PE 加入 vbirdlv 中
  5. 透过 resize2fs 将文件系统的容量确实添加!

其中最后一个步骤最重要!我们在第八章当中知道, 整个文件系统在最初格式化的时候就创建了 inode/block/superblock 等资讯,要改变这些资讯是很难的! 不过因为文件系统格式化的时候建置的是多个 block group ,因此我们可以透过在文件系统当中添加 block group 的方式来增减文件系统的量!而增减 block group 就是利用 resize2fs 啦!所以最后一步是针对文件系统来处理的, 前面几步则是针对 LVM 的实际容量大小!

# 1. 处理出一个 3GB 的新的 partition ,在鸟哥的系统中应该是 /dev/hda10
[root@www ~]# fdisk /dev/hda <==其他的动作请自行处理
[root@www ~]# partprobe
[root@www ~]# fdisk -l
   Device Boot      Start         End      Blocks   Id  System
....(中间省略)....
/dev/hda10           2785        3150     2939863+  8e  Linux LVM
# 这个就是我们要的新的 partition 罗!

# 2. 创建新的 PV:
[root@www ~]# pvcreate /dev/hda10
  Physical volume "/dev/hda10" successfully created
[root@www ~]# pvscan
  PV /dev/hda6    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda7    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda8    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda9    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda10                lvm2 [2.80 GB]
  Total: 5 [8.37 GB] / in use: 4 [5.56 GB] / in no VG: 1 [2.80 GB]
# 可以看到 /dev/hda10 是新加入并且尚未被使用的喔!

# 3. 加大 VG ,利用 vgextend 功能!
[root@www ~]# vgextend vbirdvg /dev/hda10
  Volume group "vbirdvg" successfully extended
[root@www ~]# vgdisplay
  --- Volume group ---
  VG Name               vbirdvg
  System ID
  Format                lvm2
  Metadata Areas        5
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                5
  Act PV                5
  VG Size               8.36 GB
  PE Size               16.00 MB
  Total PE              535
  Alloc PE / Size       356 / 5.56 GB
  Free  PE / Size       179 / 2.80 GB
  VG UUID               4VU5Jr-gwOq-jkga-sUPx-vWPu-PmYm-dZH9EO
# 不但整体 VG 变大了!而且剩余的 PE 共有 179 个,容量则为 2.80G

# 4. 放大 LV 吧!利用 lvresize 的功能来添加!
[root@www ~]# lvresize -l +179 /dev/vbirdvg/vbirdlv
  Extending logical volume vbirdlv to 8.36 GB
  Logical volume vbirdlv successfully resized
# 这样就添加了 LV 了喔!lvresize 的语法很简单,基本上同样透过 -l 或 -L 来添加!
# 若要添加则使用 + ,若要减少则使用 - !详细的选项请参考 man lvresize 罗!

[root@www ~]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdlv
  VG Name                vbirdvg
  LV UUID                8vFOPG-Jrw0-Runh-ug24-t2j7-i3nA-rPEyq0
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                8.36 GB
  Current LE             535
  Segments               5
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

[root@www ~]# df /mnt/lvm
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv
                       5741020    261212   5188176   5% /mnt/lvm

看到了吧?最终的结果中 LV 真的有放大到 8.36GB 喔!但是文件系统却没有相对添加! 而且,我们的 LVM 可以线上直接处理,并不需要特别给他 umount 哩!真是人性化! 但是还是得要处理一下文件系统的容量啦!开始观察一下文件系统,然后使用 resize2fs 来处理一下吧!

# 5.1 先看一下原本的文件系统内的 superblock 记录情况吧!
[root@www ~]# dumpe2fs /dev/vbirdvg/vbirdlv
dumpe2fs 1.39 (29-May-2006)
....(中间省略)....
Block count:              1458176    <==这个filesystem的 block 总数
....(中间省略)....
Blocks per group:         32768      <==多少个 block 配置成为一个 block group
Group 0: (Blocks 0-32767)            <==括号内为 block 的号码
....(中间省略)....
Group 44: (Blocks 1441792-1458175)   <==这是本系统中最后一个 group
....(后面省略)....

# 5.2 resize2fs 的语法
[root@www ~]# resize2fs [-f] [device] [size]
选项与参数:
-f      :强制进行 resize 的动作!
[device]:装置的文件名称;
[size]  :可以加也可以不加。如果加上 size 的话,那么就必须要给予一个单位,
          譬如 M, G 等等。如果没有 size 的话,那么默认使用『整个 partition』
          的容量来处理!

# 5.3 完整的将 LV 的容量扩充到整个 filesystem 吧!
[root@www ~]# resize2fs /dev/vbirdvg/vbirdlv
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vbirdvg/vbirdlv is mounted on /mnt/lvm; on-line resizing 
Performing an on-line resize of /dev/vbirdvg/vbirdlv to 2191360 (4k) blocks.
The filesystem on /dev/vbirdvg/vbirdlv is now 2191360 blocks long.
# 可怕吧!这一版的 lvm 竟然还可以线上进行 resize 的功能哩!真好!

[root@www ~]# df /mnt/lvm
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv
                       8628956    262632   7931368   4% /mnt/lvm
[root@www ~]# ll /mnt/lvm
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  17 root root  4096 Mar 11 14:17 log
drwx------   2 root root 16384 Mar 11 16:59 lost+found
# 刚刚复制进去的数据可还是存在的喔!并没有消失不见!

嘿嘿!真的放大了吧!而且如果你已经有填数据在 LVM 磁区当中的话!这个数据是不会死掉的喔!还是继续存在原本的磁区当中啦! 整个动作竟然这么简单就完成了!原本的数据还是一直存在而不会消失~您说, LVM 好不好用啊!

此外,如果你再以 dumpe2fs 来检查 /dev/vbirdvg/vbirdlv 时,就会发现后续的 Group 添加了! 如果还是搞不清楚什么是 block group 时,请回到第八章看一下该章内图1.3.1的介绍吧!


缩小 LV 容量


上一小节我们谈到的是放大容量,现在来谈到的是缩小容量喔!假设我们想将 /dev/hda6 抽离出来! 那该如何处理啊?就让上一小节的流程倒转过来即可啊!我们就直接来玩吧!

# 1. 先找出 /dev/hda6 的容量大小,并尝试计算文件系统需缩小到多少
[root@www ~]# pvdisplay
  --- Physical volume ---
  PV Name               /dev/hda6
  VG Name               vbirdvg
  PV Size               1.40 GB / not usable 11.46 MB
  Allocatable           yes (but full)
  PE Size (KByte)       16384
  Total PE              89
  Free PE               0
  Allocated PE          89
  PV UUID               Z13Jk5-RCls-UJ8B-HzDa-Gesn-atku-rf2biN
# 从这里可以看出 /dev/hda6 有多大,而且含有 89 个 PE 的量喔!
# 那如果要使用 resize2fs 时,则总量减去 1.40GB 就对了!

[root@www ~]# pvscan
  PV /dev/hda6    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda7    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda8    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda9    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda10   VG vbirdvg   lvm2 [2.80 GB / 0    free]
  Total: 5 [8.36 GB] / in use: 5 [8.36 GB] / in no VG: 0 [0   ]
# 从上面可以发现如果扣除 /dev/hda6 则剩余容量有:1.39*3+2.8=6.97

# 2. 就直接降低文件系统的容量吧!
[root@www ~]# resize2fs /dev/vbirdvg/vbirdlv 6900M
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vbirdvg/vbirdlv is mounted on /mnt/lvm; on-line resizing
On-line shrinking from 2191360 to 1766400 not supported.
# 容量好像不能够写小数点位数,因此 6.9G 是错误的,鸟哥就使用 6900M 了。
# 此外,放大可以线上直接进行,缩小文件系统似乎无法支持!所以要这样做:

[root@www ~]# umount /mnt/lvm
[root@www ~]# resize2fs /dev/vbirdvg/vbirdlv 6900M
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/vbirdvg/vbirdlv' first.
# 他要我们先进行磁碟检查!不罗唆!那就直接进行吧!

[root@www ~]# e2fsck -f /dev/vbirdvg/vbirdlv
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vbirdvg/vbirdlv: 2438/1087008 files (0.1% non-contiguous), 

[root@www ~]# resize2fs /dev/vbirdvg/vbirdlv 6900M
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/vbirdvg/vbirdlv to 1766400 (4k) blocks.
The filesystem on /dev/vbirdvg/vbirdlv is now 1766400 blocks long.
# 再来 resize2fs 一次就能够成功了!如上所示啊!

[root@www ~]# mount /dev/vbirdvg/vbirdlv /mnt/lvm
[root@www ~]# df /mnt/lvm
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv
                       6955584    262632   6410328   4% /mnt/lvm

然后再来就是将 LV 的容量降低!要注意的是,我们想要抽离的是 /dev/hda6,这个 PV 有 89 个 PE (上面的 pvdisplay 查询到的结果)。所以要这样进行:

# 3. 降低 LV 的容量,同时我们知道 /dev/hda6 有 89 个 PE
[root@www ~]# lvresize -l -89 /dev/vbirdvg/vbirdlv
  WARNING: Reducing active and open logical volume to 6.97 GB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vbirdlv? [y/n]: y
  Reducing logical volume vbirdlv to 6.97 GB
  Logical volume vbirdlv successfully resized
# 会有警告信息!但是我们的实际数据量还是比 6.97G 小,所以就 y 下去吧!

[root@www ~]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdlv
  VG Name                vbirdvg
  LV UUID                8vFOPG-Jrw0-Runh-ug24-t2j7-i3nA-rPEyq0
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                6.97 GB
  Current LE             446
  Segments               5
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

很简单吧!这样就将 LV 缩小了!接下来就要将 /dev/hda6 移出 vbirdvg 这个 VG 之外罗! 我们得要先确定 /dev/hda6 里面的 PE 完全不被使用后,才能够将 /dev/hda6 抽离! 所以得要这样进行:

# 4.1 先确认 /dev/hda6 是否将 PE 都移除了!
[root@www ~]# pvdisplay
  --- Physical volume ---
  PV Name               /dev/hda6
  VG Name               vbirdvg
  PV Size               1.40 GB / not usable 11.46 MB
  Allocatable           yes (but full)
  PE Size (KByte)       16384
  Total PE              89
  Free PE               0
  Allocated PE          89
  PV UUID               Z13Jk5-RCls-UJ8B-HzDa-Gesn-atku-rf2biN
....(中间省略)....

  --- Physical volume ---
  PV Name               /dev/hda10
  VG Name               vbirdvg
  PV Size               2.80 GB / not usable 6.96 MB
  Allocatable           yes
  PE Size (KByte)       16384
  Total PE              179
  Free PE               89
  Allocated PE          90
  PV UUID               7MfcG7-y9or-0Jmb-H7RO-5Pa5-D3qB-G426Vq
# 搞了老半天,没有被使用的 PE 竟然在 /dev/hda10 !此时得要搬移 PE 罗!

[root@www ~]# pvmove /dev/hda6 /dev/hda10
# pvmove 来源PV 目标PV ,可以将 /dev/hda6 内的 PE 通通移动到 /dev/hda10
# 尚未被使用的 PE 去 (Free PE)。

# 4.2 将 /dev/hda6 移出 vbirdvg 中!
[root@www ~]# vgreduce vbirdvg /dev/hda6
  Removed "/dev/hda6" from volume group "vbirdvg"

[root@www ~]# pvscan
  PV /dev/hda7    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda8    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda9    VG vbirdvg   lvm2 [1.39 GB / 0    free]
  PV /dev/hda10   VG vbirdvg   lvm2 [2.80 GB / 0    free]
  PV /dev/hda6                 lvm2 [1.40 GB]
  Total: 5 [8.37 GB] / in use: 4 [6.97 GB] / in no VG: 1 [1.40 GB]

[root@www ~]# pvremove /dev/hda6
  Labels on physical volume "/dev/hda6" successfully wiped

很有趣吧!这样你的文件系统以及实际的 LV 与 VG 通通变小了,而且那个 /dev/hda6 还真的可以拿出来! 可以进行其他的用途啦!非常简单吧!


LVM 的系统快照


现在你知道 LVM 的好处咯,未来如果你有想要添加某个 LVM 的容量时,就可以透过这个放大、缩小的功能来处理。 那么 LVM 除了这些功能之外,还有什么能力呢?其实他还有一个重要的能力,那就是系统快照 (snapshot)。 什么是系统快照啊?快照就是将当时的系统资讯记录下来,就好像照相记录一般! 未来若有任何数据更动了,则原始数据会被搬移到快照区,没有被更动的区域则由快照区与文件系统共享。 用讲的好像很难懂,我们用图解说明一下好了:

LVM 系统快照区域的备份示意图
图 3.5.1、LVM 系统快照区域的备份示意图(虚线为文件系统,长虚线为快照区)

左图为最初建置系统快照区的状况,LVM 会预留一个区域 (左图的左侧三个 PE 区块) 作为数据存放处。 此时快照区内并没有任何数据,而快照区与系统区共享所有的 PE 数据, 因此你会看到快照区的内容与文件系统是一模一样的。 等到系统运行一阵子后,假设 A 区域的数据被更动了 (上面右图所示),则更动前系统会将该区域的数据移动到快照区, 所以在右图的快照区被占用了一块 PE 成为 A,而其他 B 到 I 的区块则还是与文件系统共享!

照这样的情况来看,LVM 的系统快照是非常棒的『备份工具』,因为他只有备份有被更动到的数据, 文件系统内没有被变更的数据依旧保持在原本的区块内,但是 LVM 快照功能会知道那些数据放置在哪里, 因此『快照』当时的文件系统就得以『备份』下来,且快照所占用的容量又非常小!所以您说,这不是很棒的工具又是什么?

那么快照区要如何创建与使用呢?首先,由於快照区与原本的 LV 共享很多 PE 区块,因此快照区与被快照的 LV 必须要在同一个 VG 上头。但是我们刚刚将 /dev/hda6 移除 vbirdvg 了,目前 vbirdvg 剩下的容量为 0 !因此,在这个小节里面我们得要再加入 /dev/hda6 到我们的 VG 后, 才能继续创建快照区罗!底下的动作赶紧再来玩玩看!


  • 快照区的创建

底下的动作主要在添加需要的 VG 容量,然后再透过 lvcreate -s 的功能创建快照区

# 1. 先观察 VG 还剩下多少剩余容量
[root@www ~]# vgdisplay
  --- Volume group ---
  VG Name               vbirdvg
....(其他省略)....
  VG Size               6.97 GB
  PE Size               16.00 MB
  Total PE              446
  Alloc PE / Size       446 / 6.97 GB
  Free  PE / Size       0 / 0  <==没有多余的 PE 可用!

# 2. 将刚刚移除的 /dev/hda6 加入这个 VG 吧!
[root@www ~]# pvcreate /dev/hda6
  Physical volume "/dev/hda6" successfully created
[root@www ~]# vgextend vbirdvg /dev/hda6
  Volume group "vbirdvg" successfully extended
[root@www ~]# vgdisplay
  --- Volume group ---
  VG Name               vbirdvg
....(其他省略)....
  VG Size               8.36 GB
  PE Size               16.00 MB
  Total PE              535
  Alloc PE / Size       446 / 6.97 GB
  Free  PE / Size       89 / 1.39 GB  <==多出了 89 个 PE 可用罗!

# 3. 利用 lvcreate 创建系统快照区,我们取名为 vbirdss,且给予 60 个 PE
[root@www ~]# lvcreate -l 60 -s -n vbirdss /dev/vbirdvg/vbirdlv
  Logical volume "vbirdss" created
# 上述的命令中最重要的是那个 -s 的选项!代表是 snapshot 快照功能之意!
# -n 后面接快照区的装置名称, /dev/.... 则是要被快照的 LV 完整档名。
# -l 后面则是接使用多少个 PE 来作为这个快照区使用。

[root@www ~]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdss
  VG Name                vbirdvg
  LV UUID                K2tJ5E-e9mI-89Gw-hKFd-4tRU-tRKF-oeB03a
  LV Write Access        read/write
  LV snapshot status     active destination for /dev/vbirdvg/vbirdlv
  LV Status              available
  # open                 0
  LV Size                6.97 GB    <==被快照的原 LV 磁碟容量
  Current LE             446
  COW-table size         960.00 MB  <==快照区的实际容量
  COW-table LE           60         <==快照区占用的 PE 数量
  Allocated to snapshot  0.00%
  Snapshot chunk size    4.00 KB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1

您看看!这个 /dev/vbirdvg/vbirdss 快照区就被创建起来了!而且他的 VG 量竟然与原本的 /dev/vbirdvg/vbirdlv 相同!也就是说,如果你真的挂载这个装置时,看到的数据会跟原本的 vbirdlv 相同喔!我们就来测试看看:

[root@www ~]# mkdir /mnt/snapshot
[root@www ~]# mount /dev/vbirdvg/vbirdss /mnt/snapshot
[root@www ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2              9920624   3859032   5549524  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
                       6955584    262632   6410328   4% /mnt/lvm
/dev/mapper/vbirdvg-vbirdss
                       6955584    262632   6410328   4% /mnt/snapshot
# 有没有看到!这两个咚咚竟然是一模一样喔!我们根本没有动过
# /dev/vbirdvg/vbirdss 对吧!不过这里面会主动记录原 vbirdlv 的内容!

[root@www ~]# umount /mnt/snapshot
# 最后将他卸载!我们准备来玩玩有趣的东西!


  • 利用快照区复原系统

首先,我们来玩一下,如何利用快照区复原系统吧!不过你要注意的是,你要复原的数据量不能够高於快照区所能负载的实际容量。由於原始数据会被搬移到快照区, 如果你的快照区不够大,若原始数据被更动的实际数据量比快照区大,那么快照区当然容纳不了,这时候快照功能会失效喔! 所以上面的案例中鸟哥才给予 60 个 PE (共 900MB) 作为快照区存放数据用。

我们的 /mnt/lvm 已经有 /mnt/lvm/etc, /mnt/lvm/log 等目录了,接下来我们将这个文件系统的内容作个变更, 然后再以快照区数据还原看看:

# 1. 先将原本的 /dev/vbirdvg/vbirdlv 内容作些变更,增增减减一些目录吧!
[root@www ~]# df /mnt/lvm
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv
                       6955584    262632   6410328   4% /mnt/lvm

[root@www ~]# ll /mnt/lvm
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  17 root root  4096 Mar 11 14:17 log
drwx------   2 root root 16384 Mar 11 16:59 lost+found

[root@www ~]# rm -r /mnt/lvm/log
[root@www ~]# cp -a /boot /lib /sbin /mnt/lvm
[root@www ~]# ll /mnt/lvm
drwxr-xr-x   4 root root  4096 Dec 15 16:28 boot
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  14 root root  4096 Sep  5  2008 lib
drwx------   2 root root 16384 Mar 11 16:59 lost+found
drwxr-xr-x   2 root root 12288 Sep  5  2008 sbin
# 看起来数据已经不一样了!

[root@www ~]# lvdisplay /dev/vbirdvg/vbirdss
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdss
  VG Name                vbirdvg
....(中间省略)....
  Allocated to snapshot  12.22%
....(底下省略)....
# 从这里也看得出来,快照区已经被使用了 12.22% !因为原始的文件系统有异动过!

# 2. 利用快照区将原本的 filesystem 备份
[root@www ~]# mount /dev/vbirdvg/vbirdss /mnt/snapshot
[root@www ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv
                       6955584    370472   6302488   6% /mnt/lvm
/dev/mapper/vbirdvg-vbirdss
                       6955584    262632   6410328   4% /mnt/snapshot
# 看吧!两者确实不一样了!开始将快照区内容复制出来吧!

[root@www ~]# mkdir -p /backups <==确认真的有这个目录!
[root@www ~]# cd /mnt/snapshot
[root@www snapshot]# tar -jcv -f /backups/lvm.tar.bz2 *
# 此时你就会有一个备份数据,亦即是 /backups/lvm.tar.bz2 了!

为什么要备份呢?为什么不可以直接格式化 /dev/vbirdvg/vbirdlv 然后将 /dev/vbirdvg/vbirdss 直接复制给 vbirdlv 呢? 要知道 vbirdss 其实是 vbirdlv 的快照,因此如果你格式化整个 vbirdlv 时,原本的文件系统所有数据都会被搬移到 vbirdss。 那如果 vbirdss 的容量不够大 (通常也真的不够大),那么部分数据将无法复制到 vbirdss 内,数据当然无法全部还原啊! 所以才要在上面表格中制作出一个备份文件的!了解乎?

而快照还有另外一个功能,就是你可以比对 /mnt/lvm 与 /mnt/snapshot 的内容,就能够发现到最近你到底改了啥咚咚! 这样也是很不赖啊!您说是吧! ^_^!接下来让我们准备还原 vbirdlv 的内容吧!

# 3. 将 vbirdss 卸载并移除 (因为里面的内容已经备份起来了)
[root@www ~]# umount /mnt/snapshot
[root@www ~]# lvremove /dev/vbirdvg/vbirdss
Do you really want to remove active logical volume "vbirdss"? [y/n]: y
  Logical volume "vbirdss" successfully removed

[root@www ~]# umount /mnt/lvm
[root@www ~]# mkfs -t ext3 /dev/vbirdvg/vbirdlv
[root@www ~]# mount /dev/vbirdvg/vbirdlv /mnt/lvm
[root@www ~]# tar -jxv -f /backups/lvm.tar.bz2 -C /mnt/lvm
[root@www ~]# ll /mnt/lvm
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  17 root root  4096 Mar 11 14:17 log
drwx------   2 root root 16384 Mar 11 16:59 lost+found
# 是否与最初的内容相同啊!这就是透过快照来还原的一个简单的方法罗!


  • 利用快照区进行各项练习与测试的任务,再以原系统还原快照

换个角度来想想,我们将原本的 vbirdlv 当作备份数据,然后将 vbirdss 当作实际在运行中的数据, 任何测试的动作都在 vbirdss 这个快照区当中测试,那么当测试完毕要将测试的数据删除时,只要将快照区删去即可! 而要复制一个 vbirdlv 的系统,再作另外一个快照区即可!这样是否非常方便啊? 这对於教学环境中每年都要帮学生制作一个练习环境主机的测试,非常有帮助呢!

Tips:
以前鸟哥老是觉得使用 LVM 的快照来进行备份不太合理,因为还要制作一个备份档!后来仔细研究并参考徐秉义老师的教材(注3)后,才发现 LVM 的快照实在是一个棒到不行的工具!尤其是在虚拟机器当中建置多份给同学使用的测试环境, 你只要有一个基础的环境保持住,其他的环境使用快照来提供即可。即时同学将系统搞烂了,你只要将快照区删除, 再重建一个快照区!这样环境就恢复了!天呐!实在是太棒了! ^_^
鸟哥的图示
# 1. 创建一个大一些的快照区,让我们将 /dev/hda6 的 PE 全部给快照区!
[root@www ~]# lvcreate -s -l 89 -n vbirdss /dev/vbirdvg/vbirdlv
  Logical volume "vbirdss" created

[root@www ~]# lvdisplay /dev/vbirdvg/vbirdss
  --- Logical volume ---
  LV Name                /dev/vbirdvg/vbirdss
  VG Name                vbirdvg
  LV UUID                as0ocQ-KjRS-Bu7y-fYoD-1CHC-0V3Y-JYsjj1
  LV Write Access        read/write
  LV snapshot status     active destination for /dev/vbirdvg/vbirdlv
  LV Status              available
  # open                 0
  LV Size                6.97 GB
  Current LE             446
  COW-table size         1.39 GB
  COW-table LE           89
  Allocated to snapshot  0.00%
  Snapshot chunk size    4.00 KB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1
# 如何!这个快照区不小吧!

# 2. 隐藏 vbirdlv 挂载 vbirdss
[root@www ~]# umount /mnt/lvm
[root@www ~]# mount /dev/vbirdvg/vbirdss /mnt/snapshot
[root@www ~]# df /mnt/snapshot
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vbirdvg-vbirdss
                       7192504    265804   6561340   4% /mnt/snapshot

# 3. 开始恶搞!
[root@www ~]# rm -r /mnt/snapshot/etc /mnt/snapshot/log
[root@www ~]# cp -a /boot /lib /sbin /mnt/snapshot/
[root@www ~]# ll /mnt/snapshot
drwxr-xr-x  4 root root  4096 Dec 15 16:28 boot
drwxr-xr-x 14 root root  4096 Sep  5  2008 lib
drwx------  2 root root 16384 Mar 11 16:59 lost+found
drwxr-xr-x  2 root root 12288 Sep  5  2008 sbin  <==与原本数据有差异了

[root@www ~]# mount /dev/vbirdvg/vbirdlv /mnt/lvm
[root@www ~]# ll /mnt/lvm
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  17 root root  4096 Mar 11 14:17 log
drwx------   2 root root 16384 Mar 11 16:59 lost+found
# 不论你在快照区恶搞啥咚咚,原本的 vbirdlv 里面的数据安好如初啊!
# 假设你将 vbirdss 搞烂了!里面的数据不再需要!那该如何是好?

# 4. 还原原本快照区的数据,回到与原文件系统相同的资讯
[root@www ~]# umount /mnt/snapshot
[root@www ~]# lvremove /dev/vbirdvg/vbirdss
Do you really want to remove active logical volume "vbirdss"? [y/n]: y
  Logical volume "vbirdss" successfully removed

[root@www ~]# lvcreate -s -l 89 -n vbirdss /dev/vbirdvg/vbirdlv
[root@www ~]# mount /dev/vbirdvg/vbirdss /mnt/snapshot
[root@www ~]# ll /mnt/snapshot
drwxr-xr-x 105 root root 12288 Mar 11 16:59 etc
drwxr-xr-x  17 root root  4096 Mar 11 14:17 log
drwx------   2 root root 16384 Mar 11 16:59 lost+found
# 数据这样就复原了!

老实说,上面的测试有点无厘头~因为快照区损毁了就删除再建一个就好啦!何必还要测试呢? 不过,为了让您了解到快照区也能够这样使用,上面的测试还是需要存在的啦!未来如果你有接触到虚拟机器, 再回到这里来温习一下肯定会有收获的!


LVM 相关命令汇整与 LVM 的关闭


好了,我们将上述用过的一些命令给他汇整一下,提供给您参考参考:

任务PV 阶段VG 阶段LV 阶段
搜寻(scan)pvscanvgscanlvscan
创建(create)pvcreatevgcreatelvcreate
列出(display)pvdisplayvgdisplaylvdisplay
添加(extend) vgextendlvextend (lvresize)
减少(reduce) vgreducelvreduce (lvresize)
删除(remove)pvremovevgremovelvremove
改变容量(resize)  lvresize
改变属性(attribute)pvchangevgchangelvchange

至於文件系统阶段 (filesystem 的格式化处理) 部分,还需要以 resize2fs 来修订文件系统实际的大小才行啊! ^_^ 。至於虽然 LVM 可以弹性的管理你的磁碟容量,但是要注意,如果你想要使用 LVM 管理您的硬盘时,那么在安装的时候就得要做好 LVM 的规划了, 否则未来还是需要先以传统的磁碟添加方式来添加后,移动数据后,才能够进行 LVM 的使用啊!

会玩 LVM 还不行!你必须要会移除系统内的 LVM 喔!因为你的实体 partition 已经被使用到 LVM 去, 如果你还没有将 LVM 关闭就直接将那些 partition 删除或转为其他用途的话,系统是会发生很大的问题的! 所以罗,你必须要知道如何将 LVM 的装置关闭并移除才行!会不会很难呢?其实不会啦! 依据以下的流程来处理即可:

  1. 先卸载系统上面的 LVM 文件系统 (包括快照与所有 LV);
  2. 使用 lvremove 移除 LV ;
  3. 使用 vgchange -a n VGname 让 VGname 这个 VG 不具有 Active 的标志;
  4. 使用 vgremove 移除 VG:
  5. 使用 pvremove 移除 PV;
  6. 最后,使用 fdisk 修改 ID 回来啊!

好吧!那就实际的将我们之前创建的所有 LVM 数据给删除吧!

[root@www ~]# umount /mnt/lvm
[root@www ~]# umount /mnt/snapshot
[root@www ~]# lvremove /dev/vbirdvg/vbirdss  <==先处理快照
Do you really want to remove active logical volume "vbirdss"? [y/n]: y
  Logical volume "vbirdss" successfully removed
[root@www ~]# lvremove /dev/vbirdvg/vbirdlv  <==再处理原系统
Do you really want to remove active logical volume "vbirdlv"? [y/n]: y
  Logical volume "vbirdlv" successfully removed

[root@www ~]# vgchange -a n vbirdvg
  0 logical volume(s) in volume group "vbirdvg" now active

[root@www ~]# vgremove vbirdvg
  Volume group "vbirdvg" successfully removed

[root@www ~]# pvremove /dev/hda{6,7,8,9,10}
  Labels on physical volume "/dev/hda6" successfully wiped
  Labels on physical volume "/dev/hda7" successfully wiped
  Labels on physical volume "/dev/hda8" successfully wiped
  Labels on physical volume "/dev/hda9" successfully wiped
  Labels on physical volume "/dev/hda10" successfully wiped

最后再用 fdisk 将磁碟的 ID 给他改回来 83 就好啦!整个过程就这样的啦! ^_^


重点回顾


  • Quota 可公平的分配系统上面的磁碟容量给使用者;分配的资源可以是磁碟容量(block)或可创建文件数量(inode);
  • Quota 的限制可以有 soft/hard/grace time 等重要项目;
  • Quota 仅能针对整个 filesystem 进行限制,不是针对目录喔!
  • Quota 的使用必须要核心与文件系统均支持。文件系统的参数必须含有 usrquota, grpquota
  • Quota 实作的命令有 quotacheck, quotaon, edquota, repquota 等命令;
  • 磁盘阵列 (RAID) 有硬件与软件之分,Linux 操作系统可支持软件磁盘阵列,透过 mdadm 套件来达成;
  • 磁盘阵列建置的考量依据为『容量』、『效能』、『数据可靠性』等;
  • 磁盘阵列所建置的等级常见有的 raid0, raid1, raid0+1, raid5 及 raid6
  • 硬件磁盘阵列的装置档名与 SCSI 相同,至於 software RAID 则为 /dev/md[0-9]
  • 软件磁盘阵列的状态可藉由 /proc/mdstat 文件来了解;
  • LVM 强调的是『弹性的变化文件系统的容量』;
  • 与 LVM 有关的组件有: PV/VG/PE/LV 等组件,可以被格式化者为 LV
  • LVM 拥有快照功能,快照可以记录 LV 的数据内容,并与原有的 LV 共享未更动的数据,备份与还原就变的很简单;
  • Ext3 透过 resize2fs 命令,可以弹性的调整文件系统的大小

本章习题


( 要看答案请将鼠标移动到『答:』底下的空白处,按下左键圈选空白处即可察看 )
  • 情境模拟题一:由於 LVM 可以弹性调整 filesystem 的大小,但是缺点是可能没有加速与硬件备份(与快照不同)的功能。 而磁盘阵列则具有效能与备份的功能,但是无法提供类似 LVM 的优点。在此情境中,我们想利用『在 RAID 上面建置 LVM』的功能,以达到两者兼顾的能力。

    • 目标:测试在 RAID 磁碟上面架构 LVM 系统;
    • 需求:需要具有磁碟管理的能力,包括 RAID 与 LVM;
    • 前提:将本章与之前章节练习所制作的分割槽全部删除,剩下默认的分割槽即可。

    那要如何处理呢?如下的流程一个步骤一个步骤的实施看看吧:

    1. 复原系统时,你必须要:

      • 利用 umount 先卸载之前挂载的文件系统;
      • 修改 /etc/fstab 里面的数据,让启动不会自动挂载;
      • 利用 fdisk 将该分割槽删除。

      最终你的系统应该会只剩下如下的模样:
      [root@www ~]# fdisk -l
         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        9382    59898352+   5  Extended
      /dev/hda5            1926        2052     1020096   82  Linux swap / Solaris
      

    2. 创建 RAID ,假设我们利用五个 1GB 的分割槽创建 RAID-5 ,且具有一个 spare disk , 那么你应该要如何进行?首先,请自行使用 fdisk 建置好如下的分割槽状态:
      [root@www ~]# fdisk -l
      ....(前面省略)....
      /dev/hda6            2053        2175      987966   83  Linux
      /dev/hda7            2176        2298      987966   83  Linux
      /dev/hda8            2299        2421      987966   83  Linux
      /dev/hda9            2422        2544      987966   83  Linux
      /dev/hda10           2545        2667      987966   83  Linux
      
      接下来开始创建 RAID 吧!创建的方法可以如下简单处理即可:
      [root@www ~]# mdadm --create --auto=yes /dev/md0 --level=5  \
      > --raid-devices=4 --spare-devices=1 /dev/hda{6,7,8,9,10}
      
      若无出现任何错误信息,此时你已经具有 /dev/md0 这个磁盘阵列装置了!接下来让我们处理 LVM 吧!

    3. 开始处理 LVM ,现在我们假设所有的参数都使用默认值,包括 PE ,然后 VG 名为 raidvg ,LV 名为 raidlv ,底下为基本的流程:
      [root@www ~]# pvcreate /dev/md0                  <==创建 PV
      [root@www ~]# vgcreate raidvg /dev/md0           <==创建 VG
      [root@www ~]# lvcreate -L 2.82G -n raidlv raidvg <==创建 LM
      [root@www ~]# lvdisplay
        --- Logical volume ---
        LV Name                /dev/raidvg/raidlv
        VG Name                raidvg
        LV UUID                zQsKqW-8Bt2-kpJF-8rCI-Cql1-XQYT-jw1mfH
        LV Write Access        read/write
        LV Status              available
        # open                 0
        LV Size                2.82 GB
        Current LE             722
        Segments               1
        Allocation             inherit
        Read ahead sectors     auto
        - currently set to     256
        Block device           253:0
      
      这样就搞定了 LVM 了!而且这个 LVM 是架构在 /dev/md0 上面的喔!然后就是文件系统的创建与挂载了!

    4. 尝试创建成为 Ext3 文件系统,且挂载到 /mnt/raidlvm 目录下:
      [root@www ~]# mkfs -t ext3 /dev/raidvg/raidlv
      [root@www ~]# mkdir /mnt/raidlvm
      [root@www ~]# mount /dev/raidvg/raidlv /mnt/raidlvm
      

    5. 上述就是 LVM 架构在 RAID 上面的技巧,之后的动作都能够使用本章的其他管理方式来管理, 包括 RAID 热拔插机制、LVM 放大缩小机制等等。测试完毕之后请务必要关闭本题所创建的各项资讯。
      [root@www ~]# umount /mnt/raidlvm         <==卸载文件系统
      [root@www ~]# lvremove /dev/raidvg/raidlv <==移除 LV
      [root@www ~]# vgchange -a n raidvg        <==让 VG 不活动
      [root@www ~]# vgremove raidvg             <==移除 VG
      [root@www ~]# pvremove /dev/md0           <==移除 PV
      [root@www ~]# mdadm --stop /dev/md0       <==关闭 /dev/md0 RAID
      [root@www ~]# fdisk /dev/hda              <==还原原本的分割槽
      

简答题部分:
  • 在前一章的第一个大量新增帐号范例中, 如果我想要让每个用户均具有 soft/hard 各为 40MB/50MB 的容量时,应该如何修改这个 script ?
    你得先要依据本章的作法,先将 /home 制作好 quota 的环境然后, 你可以在 do...done 内的最后一行,新增一行内容为:
    setquota -u $username 40000 50000 0 0 /home
    这样就可以在制作用户时,指定升级口令且给予 quota 的限制!
  • 如果我想要让 RAID 具有保护数据的功能,防止因为硬件损毁而导致数据的遗失,那我应该要选择的 RAID 等级可能有哪些? (请以本章谈到的等级来思考即可)
    具有备份数据的有: RAID-1, RAID-5, RAID-6
  • 在默认的 LVM 配置中,请问 LVM 能否具有『备份』的功能?
    是有的,就是那个快照 (snopshot) 的功能,此功能即可进行数据的备份!
  • LVM 内的 LV 据说仅能达到 256 GB 的容量,请问如何克服此一容量问题?
    LV 的容量与 PE 这个数据有关,由於默认 PE 为 4MB ,所以才会有此限制。 若要修改这个限制值,则需要在建置 VG 时就给予 -s 的选项来进行 PE 数值的配置。 若给到 PE = 16MB 时,则 LV 的最大总量就能够达到 1TB 的容量了。
  • 如果你的计算机主机有提供 RAID 0 的功能,你将你的三颗硬盘全部在 BIOS 阶段使用 RAID 芯片整合成为一颗大磁碟, 则此磁碟在 Linux 系统当中的档名为何?
    由於硬件磁盘阵列是在 BIOS 阶段完成的,因此 Linux 系统会捉到一个完整的大的 RAID 磁碟, 此磁碟的档名就会是『 /dev/sda 』!

参考数据与延伸阅读



2002/07/14:第一次完成
2003/02/10:重新编排与加入 FAQ
2003/09/02:加入 quotacheck 发生错误时的解决方法。
2005/09/06:将旧的文章移动到 此处
2005/09/06:进行版面风格的转换,并且进行数据的查询,加入 repquota 的简单说明而已!
2009/03/04:将原本旧的基於 FC4 的文件移动到 此处
2009/03/06:加入 warnquota 这玩意儿!挺有趣的哩!
2009/03/12:加入了 software RAID 与 LVM 的加强说明,尤其是 LVM 的快照 (snapshot) 的说明!
2009/09/10:修改一些字样之外,添加情境模拟,以及后续的简答题部分题目。