Chinaunix首页 | 论坛 | 博客
  • 博客访问: 428708
  • 博文数量: 112
  • 博客积分: 4451
  • 博客等级: 上校
  • 技术积分: 1063
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-23 10:19
个人简介

更多精品http://shop65927331.taobao.com

文章分类

全部博文(112)

文章存档

2011年(19)

2010年(54)

2009年(39)

分类: LINUX

2010-03-22 16:34:25

本文是 Unix/Linux 系统管理自动化系列中的一篇,主要讲述如何实现自动化监控磁盘空间状态并及时通知系统管理员采取相应措施。

在 Unix/Linux 系统的日常管理工作中,系统管理员可能会遇到因磁盘空间耗尽而导致丢失数据,或者系统崩溃等。这些严重的事故极大的影响了工作效率。因此,关注系统的磁盘使用情况,建立一个警告系统对磁盘空间的潜在问题发出警告,确保文件系统没有被填满或滥用是系统管理的一个重要的方面。

在本文中,作者介绍了一些查看磁盘使用情况的工具命令并结合这些工具实现了一个自动化监控磁盘空间的示范脚本。通过介绍,读者将了解如何监视磁盘空间、如何发现究竟是哪些文件系统占用了大部分的空间并以此为依据做出相应的调整。

在获知磁盘使用状态之前,你可能需要知道你当前的系统使用的是什么类型的磁盘,它的属性参数是什么。目前大多数的 Linux/Unix 服务器硬盘使用 SCSI 或 IDE 硬盘。在 Linux 和 AIX 中查看硬盘的属性使用不同的命令,下面的例子给出了在不同系统上如何获得硬盘属性,其中包括制造商,机器型号,序列号等。

清单 1. 在 RHEL5.3 系统上查看 SCSI 硬盘的属性

 # dmesg |grep scsi 
 vio_register_driver: driver ibmvscsi registering 
 ibmvscsi 30000002: SRP_VERSION: 16.a 
 scsi0 : IBM POWER Virtual SCSI Adapter 1.5.9 
 ibmvscsi 30000002: partner initialization complete 
 ibmvscsi 30000002: sent SRP login 
 ibmvscsi 30000002: SRP_LOGIN succeeded 
 ibmvscsi 30000002: host srp version: 16.a, host partition vios (1), OS 3, max io 1048576 
 sd 0:0:1:0: Attached scsi disk sda 
 sd 0:0:1:0: Attached scsi generic sg0 type 0 

清单 2. 在 AIX6.1 系统上显示硬盘配置信息

 # lsdev -CHc disk 
 name   status    location     description 
 hdisk0 Available 01-08-00-1,0 SCSI Disk Drive 

上面的命令给出了系统可用的硬盘信息,从上面的输出可以看出,系统有一个可用的 SCSI 硬盘,如果要获得硬盘的配置信息,可以使用 lscfg 来查看。
 # lscfg -vl hdisk0 
  hdisk0           U788D.001.99DZG0B-P1-T10-L1-L0  SCSI Disk Drive (36400 MB) 

        Manufacturer................IBM-ESXS 
        Machine Type and Model......ST936701SS 
        FRU Number..................39R7368 
        ROS Level and ID............42353142 
        Serial Number...............3LC0BGY8 
        EC Level....................H17923E 
        Part Number.................26K5266 
        Device Specific.(Z0)........000005129F00100A 
        Device Specific.(Z1)........0106B51B 
        Device Specific.(Z2)........1000 
        Device Specific.(Z3)........06114 
        Device Specific.(Z4)........0001 
        Device Specific.(Z5)........22 
        Device Specific.(Z6)........H17923E 
        Brand.......................XS 


查看磁盘与分区以及分区与挂载点的对应关系

硬盘需要分区,格式化并挂载后方能使用,Linux 下硬盘上的每个分区表示为一个设备文件。AIX 系统对磁盘的管理和 Linux 系统不同,AIX 默认使用 LVM 对磁盘进行管理。传统的磁盘管理方法使用类似 fdisk 的工具对物理磁盘进行分区的划分和删除,每个分区的大小是固定的,在此基础上挂载文件系统。AIX 系统上将多个物理分区汇聚为一个卷组,然后再从中分割出一块一块的逻辑卷,在逻辑卷上可以创建文件系统。在较新的 Linux 版本中,也开始提供对 LVM 的支持,和 AIX 中的概念和使用方法非常相似。

通过在 Linux 系统上面使用 fdisk 命令可以获得硬盘分区信息。而在 AIX 系统上,用户可以使用 lspv 来获得一个硬盘上的逻辑卷与文件系统对应信息。

在 Linux 和 AIX 系统上,都提供了一个 df 命令。df 的功能是检查文件系统的磁盘空间占用情况以及可用性,通常还包挂载点。管理员能利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。 df 的参数在 AIX 和 Linux 系统上略有不同。管理员可以通过查看用户手册来确定它的用法。

清单 3 .df 命令在 AIX6.1 系统上的缺省输出

 # df 
 Filesystem    512-blocks      Free %Used    Iused %Iused Mounted on 
 /dev/hd4          360448     84208   77%     9790    48% / 
 /dev/hd2         3309568    298576   91%    30742    47% /usr 
 /dev/hd9var       163840    124448   25%      514     4% /var 
 /dev/hd3          131072    122696    7%       70     1% /tmp 
 /dev/hd1           32768     32064    3%        5     1% /home 
 /dev/hd11admin     262144    261416    1%        5     1% /admin 
 /proc                  -         -    -         -     -  
 /proc/dev/hd10opt      294912    127536   57%     1661    11% /opt 

在上面 df 的输出列表中,第一列是表示文件系统对应的设备文件的路径名;第二列给出分区包含的数据块的数目;第三列表示可用的数据块数目,在缺省的每个分区都留了少量空间供系统管理员使用,即使遇见普通用户空间已满的情况,管理员仍能登录和留有解决问题所需的工作空间;清单中第四列 use% 列表示普通用户空间使用的百分比;最后一列表示文件系统的安装点。

需要注意的是上面显示的大小是以 512 字节块为单位,而不是千字节。缺省情况下,几乎所有传统的 UNIX 操作系统都以 512 字节块为单位报告大小。要获得以 1K 块为单位的信息,可以使用 -k 命令行选项,要获得以 MB 为单位的信息,需要使用 -m 命令,要获得以 GB 为单位的信息,需要使用 -g 命令行选项。

df 工具在 Linux 上默认显示是以 1K 字节为单位的。在 Linux 系统上,-h 选项是比较常用的选项,它能使得显示的内容简单易读。

清单 4. 带 -h 选项的 df 命令在 SLES 上的输出

 # df -h 
 Filesystem            Size  Used Avail Use% Mounted on 
 /dev/sda6              38G   16G   23G  41% / 
 udev                  1.5G   96K  1.5G   1% /dev 

显示目录或文件占用磁盘空间大小

du 命令并不是显示磁盘的空闲空间,而是显示磁盘使用情况的信息,它将统计目录或文件所占磁盘空间的大小。du 命令用于确定文件和目录的磁盘使用情况。

该命令可逐级进入指定目录的每一个子目录并显示该目录占用文件系统数据块的情况。若没有给出目录或文件的名字,则对当前目录进行统计。

下面的 du 输出清单中的第一列是以块为单位计的磁盘空间容量,第二列列出目录中使用这些空间的目录和文件名称。 带 -a 选项的 du 命令将从当前目录开始沿着目录结构向下直到列出所有目录和文件的容量为止。

 #du -a 
 0       ./lost+found 
 0       ./.oslevel.datafiles/.oslevel.hold 
 8       ./.oslevel.datafiles/.oslevel.mlinfo.cache 
 8       ./diagSEgenSnap/general/emgr.snap 
 2304    ./diagSEgenSnap/general/trcfmt 
 8       ./diagSEgenSnap/general/inittab 
 8       ./diagSEgenSnap/general/survdump.settings 
 4976    ./diagSEgenSnap/general 
 1448    ./diagSEgenSnap/snapH.pax.Z 
 6424    ./diagSEgenSnap 
 8       ./.ctinst.log 
 0       ./rc.net.serial.out 
 400     ./lvmt.log 
…
 7344 





回页首


在下面的内容中,我们给出了一个对磁盘分区剩余空间大小进行自动化监控的示例,用户可根据自身需求,对示例脚本进行修改以达到特定的管理目的。

我们的自动化磁盘分区空间监控系统分为三个部分,由三个文件 /root/disktab,checkdisk 脚本和 /root/diskresp 实现。/root/disktab 文件定义了需要监控的磁盘分区,报警阈值和达到阈值后的动作。checkdisk 则实现了整个对于磁盘空间的监控过程,而 /root/diskresp 文件为用户自定义的磁盘空间达到阈值后的响应脚本。

监控脚本将被添加到 crontab 中,这样就可以使监控循环进行。我们的脚本在 RedHatEL-Server 5.3(perl 版本 5.8.8)、SLES 11(perl 版本 5.10.0) 和 AIX 5.3(perl 版本 5.8.2) 上测试通过。

定义的 /root/disktab 文件拥有下面的格式

分区所 mount 的目录 报警阈值 达到阈值后的动作

清单 6. 分区监控 /root/disktab 文件示例

 /       80%     /root/diskresp 
 /data   100G 	    /root/diskresp 

在这个文件中,第一行表示当"/"分区空间占用超过 80% 时,则运行脚本 /root/diskresp 进行响应;第二行表示当"/data"分区的空间占用超过 100G 时运行脚本 /root/diskresp 进行响应。我们的文件允许报警阈值以 KB,MB,GB 为单位,也可以以百分比表示。

脚本 checkdisk 主要完成的任务是分析 /root/disktab 文件并和当前查看磁盘空间的输出进行比较,对于空间异常的分区采取相应的措施。脚本 checkdisk 的第一部分先进行了初始化,获得了要使用的分区监控定义文件,默认的分区监控定义文件为 /root/disktab,也可以通过参数指定该文件的位置。

清单 7. checkdisk 脚本初始化部分

 #!/usr/bin/perl 

 use strict; 

 my $DISKTABFILE = "/root/disktab"; 
 if ($ARGV[0] ne "") { 
    $DISKTABFILE = $ARGV[0]; 
 } 

 # 因为 Linux 和 AIX 的 df 命令格式略有不同,所以首先判断一下
 my $OS = `uname`; 
 chomp $OS; 
 my $DF; 
 if ($OS eq "Linux") { 
    $DF = "df -h"; 
 } elsif ($OS eq "AIX") { 
    # AIX 中的 df 命令,在这里使用了 -m 选项,则其输出都将以 MB 为单位(但是 MB 字样不会出现在结果输出中)
    $DF = "df -I -m"; 
 } else { 
    print "This OS is not supported.\n"; 
    exit 1; 
 } 

接下来,checkdisk 脚本逐行分析了 /root/disktab 文件,使用 perl 的正则表达式,很容易可以从 /root/disktab 中将分区所 mount 的目录,报警阈值以及达到阈值后的动作等信息提取出来,然后将获得的信息存放在一个 hash table 中。

清单 8. checkdisk 脚本分析 /root/disktab 文件部分

 # 分析 /root/disktab 文件
 my %table = getTable($DISKTABFILE); 

 sub getTable 
 { 
    # 通过参数取得 table 文件的位置
    my ($tabfile) = @_; 
    my %rs; 

    # 打开文件
    unless(open(TABF, $tabfile)) { 
        print "Can't open file '$tabfile'.\n"; 
        exit 1; 
    } 
    # 分析 disktab 文件每行的内容,将其存放在一个 hash table 中
    foreach my $line () { 
        # 使用正则表达式,分析出 table 文件中每一行的挂载点、阈值大小和采取的行动
        if(!($line =~ /^#/) && $line =~ /(\S+)\s+(\S+)\s+(.*)\s*$/) { 
            my $mp = $1; 
            my $size = $2; 
            my $action = $3; 
            $rs{$mp} = [$size, $action]; 
        } 
    } 
    close TABF; 
    return %rs; 
 } 

清单 9 中的脚本实现了实时监控并检测分区状况,通过前面获得的用户定义的阈值和 df 命令的输出进行比较,如果 df 显示的某个分区的空间占用超过了用户定义的阈值,则执行用户定义的操作。

清单 9. checkdisk 脚本根据分区状况执行响应

 # 将分析出的 hash table 以引用的形式传递给 checkDisk 函数,checkDisk 函数完成检查分区空间,并执行相应动作的任务。
 checkDisk(\%table); 
 sub checkDisk 
 { 
    my ($tab) = @_; 
    my @df_rs = `$DF`; # 执行 df 命令
    chomp @df_rs; 
    my ($mp, $used_size, $used_perc); 
    my ($minsize, $minperc); 
    my $comp_with_perc; # 此变量用于表明是使用百分比进行比较还是使用绝对空间大小值
    my %rs; 
    my $env_str; 
    # 分析 df 命令的每一行输出
    foreach my $line (@df_rs) { 
        $comp_with_perc = 0; 
        # 使用正则表达式,分析出 df 输出的每一行的挂载点、空间使用大小和空间使用百分比
        if ($line =~ /^\S+\s+\S+\s+(\S+)\s+\S+\s+(\d+)%\s+(\S+)\s*$/) { 
            $mp = $3; $used_size = $1; $used_perc = $2; 
        } else { 
            next; 
        } 
        # 如果某个分区的 Mount Point 在 table 中有一项和它对应,则继续进行,否则分析下一行
        if (!defined($$tab{$mp})) { 
            next; 
        } 

        # 将得到的信息,存储起来,作为环境变量传递给将要运行的响应脚本
        $env_str = "DISK_MOUNTP=$mp"; 
        $env_str .= " DISK_MIN=$$tab{$mp}[0]"; 
        $env_str .= $used_size =~ /^\d+\.?\d*$/ ? " DISK_USED=${used_size}M" : "
            DISK_USED=$used_size"; 
        $env_str .= " DISK_USED_PERC=$used_perc%"; 
        # 分析 hash table 中的阈值,如果阈值使用的是大小值,则现将其统一单位为 MB 
        if ($$tab{$mp}[0] =~ /^(\d+\.?\d*)G$/) { 
            $minsize = $1 * 1024; 
        }elsif ($$tab{$mp}[0] =~ /^(\d+\.?\d*)M$/) { 
            $minsize = $1; 
        }elsif ($$tab{$mp}[0] =~ /^(\d+\.?\d*)K$/) { 
            $minsize = $1 / 1024; 
        }elsif ($$tab{$mp}[0] =~ /^(\d+\.?\d*)%$/) { 
            $minperc = $1; 
            # 如果 hash table 中阈值存放的是一个百分比,则表明要进行占用百分比的比较
            $comp_with_perc = 1; 
        }else { 
            print "Format error: $$tab{$mp}[0]\n"; 
            next; 
        } 

        # 如果使用空间占用 size 进行比较,则也将 df 命令中得到的空间大小统一单位到 MB 
        if (!$comp_with_perc) { 
            if ($used_size =~ /^(\d+\.?\d*)G$/) { 
                $used_size = $1 * 1024; 
            }elsif ($used_size =~ /^(\d+\.?\d*)M$/ || $used_size =~ /^(\d+\.?\d*)$/) { 
                $used_size = $1; 
            }elsif ($used_size =~ /^(\d+\.?\d*)K$/) { 
                $used_size = $1 / 1024; 
            } 
        } 

        # 比较实际空间占用和 table 中记录的阈值
        if ((!$comp_with_perc && $minsize < $used_size) || 
            ($comp_with_perc && $minperc < $used_perc)) { 
            print "WARNING DISK SIZE for $mp\n"; 
            # 调用 table 中记录的响应脚本,$env_str 中存放的 DISK_MOUNTP,DISK_MIN,DISK_USED,
            # DISK_USED_PERC,作为环境变量传递给脚本
            my $cmd = "$env_str $$tab{$mp}[1] 2>&1"; 
            print "Running command: $cmd\n"; 
            my $output = `$cmd`; chomp $output; 
            print "Output:\n$output\nExit code = $?\n"; 
        } 
    } 
 } 

响应脚本(在本例中为 /root/diskresp)中可以从环境变量得到占用空间异常的分区的 Mount Point(DISK_MOUNTP),设置的阈值(DISK_MIN),空间占用大小(DISK_USED)以及空间占用比例(DISK_USED_PERC)。

响应脚本可以采取各种动作来解决空间占用问题,例如删除一些临时文件,或者是仅仅发一封信来通知管理员。一下给出一个响应脚本的例子,它所做的就是给 root 用户发一封信。

清单 10. 响应脚本示例

 #!/bin/bash 
 echo "The $DISK_MOUNTP is now used $DISK_USED ($DISK_USED_PERC), over $DISK_MIN." | 
 mail -s "WARNING DISK SIZE for $DISK_MOUNTP" root 

现在通过手工运行 /root/checkdisk 脚本,其已经可以正常工作。为了实现自动化的监控,我们需要系统的 cron 服务的帮助。

使用命令“crontab -e”编辑 crontab,添加一条类似于以下的项:

*/2 * * * * /root/checkdisk 2>&1 >> /root/checkdisk.log

这表示每两分钟运行一次 checkdisk 脚本,将其输出存储在 /root/checkdisk.log 文件中。可以根据自己的需求修改脚本运行的时间。cron 运行命令时,其命令输出不会显示在屏幕上,而是将输出通过邮件发给管理员,所以为了方便查看命令的输出,最好将输出重定向到文件中。

以上步骤完成后,就可以实现对磁盘分区的自动监控了。

对 checkdisk 脚本稍加修改就可以通过 ssh 或 rsh 实现对远程机器某个分区的监控,也可以使用 du 实现对某个文件夹大小的监控。(比如管理员可能在没有使用 quota 的情况下要监控每个用户的 home 目录的大小,以免某个用户占用过大的空间。)





回页首


本文介绍了 Unix/Linux 上的磁盘管理命令并通过一个自动化监控脚本详细介绍了如何实现磁盘空间的自动化监控管理。磁盘空间的自动化监控能帮助系统管理员及时发现磁盘空间的异常问题,通过采取相应的措施使得问题得以消除和缓解

原文链接:http://www.ibm.com/developerworks/cn/aix/library/0907_unixdisk_litt/

阅读(1338) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~