Unix/Linux 系統自動化管理: 磁碟管理篇

yhj20041128001發表於2011-05-30

在 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 

UNIX/Linux 系統磁碟空間監控自動化指令碼示例

在下面的內容中,我們給出了一個對磁碟分割槽剩餘空間大小進行自動化監控的示例,使用者可根據自身需求,對示例指令碼進行修改以達到特定的管理目的。

我們的自動化磁碟分割槽空間監控系統分為三個部分,由三個檔案 /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 上的磁碟管理命令並通過一個自動化監控指令碼詳細介紹瞭如何實現磁碟空間的自動化監控管理。磁碟空間的自動化監控能幫助系統管理員及時發現磁碟空間的異常問題,通過採取相應的措施使得問題得以消除和緩解。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23757700/viewspace-696594/,如需轉載,請註明出處,否則將追究法律責任。

相關文章