前幾天接到朋友聯系,說他的服務器壞了,啟動不起來了。這是一個RHEL 4的服務器,而且是那種盜版RHEL 4,也就是說沒有售后服務的,聯系我問問能不能幫幫忙。我也很久沒有弄過Linux系統上的東西了。只好嘗試一下,慶幸的是,修好了,并幫朋友維護了一段時間,在此記錄一些修復和維護中碰到的問題。修復 superblock 本身并不復雜,我覺得值得記錄的是修復過程中的思考過程,和修復所需要注意的問題。

一、啟動故障


系統無法啟動,啟動時內核panic:

Uncompressing Linux Ok, booting the kernel.
audit(
1297269214.612:0): initialized
ide2: I/O resource 0x3F6-0x3F6 not free.
ide2: ports already in use
, skipping probe
Red Hat nash version 
4.1.18 starting
File descriptor 
3 left open
  Reading all physical volumes.  This may take a while
  /dev/hda: open failed: No medium found
  Found volume group 
"VolGroup_ID_17253" using metadata type lvm2
File descriptor 
3 left open
  
8 logical volume(s) in volume group "VolGroup_ID_17253" now active
File descriptor 
3 left open
VFS: Can't find ext3 filesystem on dev dm-
0.
mount: error 
22 mounting ext3
mount: error 
2 mounting none
switchroot: mount failed: 
22
umount /initrd/dev failed: 
2
Kernel panic - not syncing: Attempted to kill init!
 _


看到這個報錯,我Google了一下,很快就發現,這很有可能是硬盤的superblock [1] 壞了,因此感覺需要修復superblock。

詢問了一下,癱瘓之前都發生了些什么。朋友提到了一個情況,在癱瘓前,他發現有一個目錄存儲了太多的文件了(確實非常的多,大約是幾百萬到上千萬個文件,程序設計上有問題),這是他寫的一個php做緩存的腳本生成的后綴為.php的文件,絕大多數都已經是垃圾文件了。他覺得太占磁盤空間了,想清理一下,于是用下面的命令刪除這些生成的文件:

find . -name "*.php" -exec rm -f {} \;

可是執行命令后,等了幾分鐘,發現系統沒有反應。于是就Ctrl-C了,后來發現系統還是很慢,于是就執行reboot了。接下來,系統就啟動不起來了。

可以推斷,其實并不是系統沒有反應,而是刪除如此大量的文件,需要相當的時間,當Ctrl-C后,磁盤寫入行為并沒有因此而立即停止,在如此密集磁盤寫入時執行reboot,確實比較容易引起磁盤上的故障。再加上這塊硬盤雖然是ext3,但是日志使用的是默認的ordered [2],出問題的幾率就更大了,所以懷疑是 superblock 的可能性就更大了。

二、修復環境


當時朋友有些慌張了,因為他認為這是他操作失誤導致服務器癱瘓,有些不知道該怎么辦了,那天我有事情比較忙,打算晚些時候再回來幫他。隨后的操作中可以看到他做了很多危險的操作,我會一一提出來,大家有類似情況的時候,一定要注意。

首先是他把硬盤直接拆下來來了,打算拿回公司備份。備份的想法是好的,如果有合適的服務器,拆下來接過去備份也是對的。但是問題就在于,這是一塊SCSI接口的硬盤,是一堆Linux分區,使用的還是LVM [3],而他公司沒有一個SCSI接口的機器,他可能還需要去市場上買個SCSI卡,而且,他也沒有一臺Linux的機器,全是Windows,他甚至打算使用explore2fs之類的不成熟的軟件來掛載這塊硬盤。

這問題就大了。買的SCSI卡的穩定性如何?別是雜牌的,卡再造成硬盤的二次數據損失。用Windows備份可能損壞的硬盤的數據是非常危險的,explorer2fs這類Windows掛載ext2/3分區的軟件從來就沒成熟過,至今為止還有大量的特性不支持,只是試驗產品。使用他們掛載分區,很可能會造成數據損失。另外,之前說過,問題很可能是superblock出問題了,這種情況下,不修復 superblock ,誰也別想掛載成功,而Windows上顯然沒有這類軟件。

碰到這類問題,比較好的辦法是使用另一臺具有SCSI接口的Linux,進行修復、掛載、備份。當然,對于朋友而言,這不現實。那就折中,還在原服務器上修復,但是使用 Linux LiveCD 進行修復,將數據備份到外置 USB 硬盤上。

這里需要注意的是,即使硬盤有幾個分區,只壞了一個,備份到其它貌似還好的分區似乎也不是什么大問題。但是,在修復、備份的時候,一定要盡可能的避免被修復磁盤的寫操作,無論是哪個分區。因為在問題確認修復前,你并不能肯定只有那個報錯的分區有故障,其它一切正常。

那天朋友在機房的時候,他什么都沒有帶,只能眼睜睜的一次次的重啟,看錯誤日志,試著能不能進系統。這是很不好的,如果懷疑硬盤出了故障,那么這么一次次重啟很容易加重問題,因此一定要避免。

沒有任何修復環境是沒有辦法工作的。我讓朋友回去準備幾張光盤,都是可引導的修復盤。朋友對 Linux 有一些經驗但不是很熟悉,折中起見,我讓朋友準備了 Fedora 14、Ubuntu 10.10、UBCD等光盤備用,并且打算使用 Fedora 14 的 Live CD 進行修復。并且第二天帶一個大容量的,最好是空的USB硬盤來,備份數據。并且,在家用 Fedora 14 啟動一下,看看怎么進入命令行模式,第二天啟動的時候,不要進入圖形界面。在命令行模式下修復。

第二天約好時間后,看了他的gtalk留言,感覺是一身冷汗啊。

首先是告訴我,在服務器上 Fedora 啟動后直接進桌面了,沒有選項,點了點不知道怎么修復,甚至打開了故障硬盤的幾個分區,沒找到需要備份的文件。于是乎,又啟動了Ubuntu選擇了修復壞系統,結果發現要安裝文件,然后報錯說沒有硬盤,于是退出了。

敢情這哥們直接把我說的話當耳旁風,在故障服務器上直接啟動圖形界面,更甚的是,他還嘗試讓 Ubuntu 覆蓋安裝 RHEL 4。幸好分區的 superblock 是壞的,不然全毀了。

這里面有三個錯誤。首先是不應該啟動圖形界面,其次是錯誤的理解了 Ubuntu 中修復系統選項的含義,然后是在菜單上點擊服務器分區從而激發了綁定操作,很可能直接造成寫入操作。

這些都應該是前一天晚上回家琢磨的,他顯然偷懶了,直接拿故障環境練手。如果不是這哥們命大,而且系統出的問題沒有那么嚴重,那么這些連續的錯誤,很可能造成不可挽回的結果。

雖然對于 Windows 用戶來說,看著純命令行覺得無從下手,但是,得到了美麗的界面往往意味著你得付出些什么。在以前的某些 LiveCD 中,加載圖形界面的時候,由于各種驅動和程序的加載,錯誤的進行了硬盤的寫操作,從而導致有些人抱怨過啟動 LiveCD 導致硬盤數據二次損壞,最終使得修復無望。雖然,最近這些版本的 LiveCD 可能沒有這類問題,但是為了避免萬一,應當盡量減少對硬盤寫入操作的可能性。既然所有修復行為都會在命令行模式下進行,那就沒必要啟動圖形界面冒風險。

我讓他帶著 Ubuntu 的盤就是以防萬一,萬一 Fedora 啟動出現奇怪的問題,我們可以用 Ubuntu 啟動然后修復系統。而不是進入 Ubuntu的修復系統選項。那個選項是給 Ubuntu 系統準備的,是以光盤上的系統文件及配置覆蓋硬盤上的系統文件及配置,從而達到修復系統的目的。這顯然和我們要修復的 RHEL 驢唇不對馬嘴。修復系統所需要的只是一個 Linux 環境而已。

至于最后在菜單上點擊硬盤分區,甚至還打開里面的文件看看,這就是純屬找死了。系統已經報錯了,即使能夠掛載成功,文件系統也很可能是有問題的,必須在訪問前先fsck,否則很可能會引發更大的問題。畢竟默認 Fedora 掛載可不是只讀,而是可讀寫,混亂后,誰也無法預測會把硬盤寫成啥樣。

三、確認問題


該準備的光盤準備了,不該操作的操作也做了,這讓我很無語,雖然懷疑僅僅是邏輯錯誤導致superblock壞掉,應該不會有大問題,但還是讓我對這次修復的可能性感到懷疑。至少這朋友完全不按照我說的辦,經常的做些自己覺得沒什么的危險操作,哎,前景黯淡啊。

既然他已經改點的都點了,該造成的損壞基本上也造成了。那就在 Fedora LiveCD 的圖形界面下修復吧,至少他還可以更方便的把命令返回結果通過 firefox 給我發過來。比用 android 手機通訊好多了。

首先我需要知道,都有哪些文件系統被他掛載了,另外,系統上有哪些分區。

[root@localhost liveuser]# mount |grep LogVol
/dev/mapper/VolGroup_ID_17253-LogVol4 on /media/0edef924-567f-45fc-
9609-51722cad6e9e type ext3 (rw,nosuid,nodev,uhelper=udisks)
/dev/mapper/VolGroup_ID_17253-LogVol7 on /media/ee0c40c6-d9d1-4a81-
9806-9991621db1dd type ext3 (rw,nosuid,nodev,uhelper=udisks)
/dev/mapper/VolGroup_ID_17253-LogVolHome on /media/f524534e-3d24-4a22-b475-9e4b7dac0d35 type ext3 (rw
,nosuid,nodev,uhelper=udisks)
/dev/mapper/VolGroup_ID_17253-LogVol6 on /media/12953c57-baba-
4358-baeb-cdd17d6513a2 type ext3 (rw,nosuid,nodev,uhelper=udisks)


好嘛,據我所知,服務器上好像有5個綁定目錄的分區,LogVol{3,4,6,7,Home},LogVol3 好像就是那個壞的分區,想綁也綁不上,除了它,他全綁上了。

我需要確定 LVM 總共有哪些分區,lvscan 命令可以告訴我們LVM下面的分區情況。

[root@localhost liveuser]# lvscan
ACTIVE '/dev/VolGroup_ID_17253/LogVol3' 
[10.00 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol4' 
[1.06 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol7' 
[53.56 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol6' 
[5.38 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol1' 
[2.00 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol0' 
[2.00 GiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVol2' 
[64.00 MiB] inherit
ACTIVE '/dev/VolGroup_ID_17253/LogVolHome' 
[29.44 GiB] inherit


嗯,LogVol{0,1}是交換分區,LogVol2肯定不是我們的目標,那么缺失的是LogVol3,這個分區出問題了。如此,我們手動綁定一下 LogVol3 看一下報錯信息。

[root@localhost liveuser]# mkdir /media/myroot
[root@localhost liveuser]# mount -t ext3 /dev/mapper/VolGroup_ID_17253-LogVol3 /media/myroot
mount: wrong fs type
, bad option, bad superblock on /dev/mapper/VolGroup_ID_17253-LogVol3,
missing codepage or helper program
, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so

這里我們可以直接看到報錯說 'bad superblock' 信息。
然后我們再看一下內核報錯。

[root@localhost liveuser]# dmesg | tail -n 20
[ 343.583694] EXT3-fs (dm-3): mounted filesystem with ordered data mode
[ 343.585926] SELinux: initialized (dev dm-3, type ext3), uses xattr
[ 346.179128] EXT3-fs: barriers not enabled
[ 346.183702] kjournald starting. Commit interval 5 seconds
[ 346.189688] EXT3-fs (dm-4): using internal journal
[ 346.189694] EXT3-fs (dm-4): mounted filesystem with ordered data mode
[ 346.193216] SELinux: initialized (dev dm-4, type ext3), uses xattr
[ 348.911539] EXT3-fs: barriers not enabled
[ 348.918113] kjournald starting. Commit interval 5 seconds
[ 348.918151] EXT3-fs (dm-9): warning: mounting fs with errors, running e2fsck is recommended
[ 348.922722] EXT3-fs (dm-9): using internal journal
[ 348.922728] EXT3-fs (dm-9): mounted filesystem with ordered data mode
[ 348.922738] SELinux: initialized (dev dm-9, type ext3), uses xattr
[ 350.225535] EXT3-fs: barriers not enabled
[ 350.230730] kjournald starting. Commit interval 5 seconds
[ 350.236075] EXT3-fs (dm-5): using internal journal
[ 350.236081] EXT3-fs (dm-5): mounted filesystem with ordered data mode
[ 350.241386] SELinux: initialized (dev dm-5, type ext3), uses xattr
[ 1957.796112] EXT3-fs (dm-2): error: can't find ext3 filesystem on dev dm-2.
[ 2688.247855] EXT3-fs (dm-2): error: can't find ext3 filesystem on dev dm-2.

這里我們看到,內核報錯說無法在 dm-2 上找到 ext3 文件系統。這很有可能就是 superblock 損壞造成的問題。

另外,我們看到,正如我所擔心的那樣,不僅僅是 dm-2 (LogVol3) 有故障, dm-9 分區也有故障。很可能其它分區也有問題,都需要在使用前,進行磁盤檢查 fsck。冒失的訪問,很可能會造成數據損壞或丟失。

如此,我們基本上可以確定是 superblock 的損壞,至于是否還有其它故障,以及是否有數據損失,需要在 fsck 之后才能知道了。

四、鏡像備份損壞的硬盤


執行 fsck 會對磁盤進行寫操作,我們需要在此之前對磁盤進行鏡像備份。這樣萬一 fsck 的修復造成了更大的損失,我們還可以恢復原始狀態。

我讓朋友插上 USB 硬盤,桌面上會自動出現這個硬盤的圖標,如果沒有菜單上也會有,點擊菜單項打開這個 USB 硬盤,會觸發 Fedora 自動綁定該硬盤。這么操作省的朋友敲命令了 (心里想,反正之前不該點的也都點了,破罐破摔吧~~)。

通過 mount 命令找到新綁定的磁盤路徑:

/dev/sdb1 on /media/BACKUP type fuseblk (rw,nosuid,nodev,allow_other,blksize=4096,default_permissions)

然后,開始鏡像 LogVol3:

[root@localhost ~]# dd if=/dev/VolGroup_ID_17253/LogVol3 | gzip > /media/BACKUP/server_root_image.gz
20971520+0 records in
20971520+0 records out
10737418240 bytes (11 GB) copied, 666.429 s, 16.1 MB/s

確認一下文件確實存在:

[root@localhost ~]# ls -l /media/BACKUP/*.gz
-rwxrwxrwx. 
1 liveuser liveuser 5943229016 Feb 10 17:29 /media/BACKUP/server_root_image.gz

五、修復


先進行第一次修復嘗試。

[root@localhost liveuser]# fsck.ext3 -B 1024 /dev/mapper/VolGroup_ID_17253-LogVol3
e2fsck 
1.41.12 (17-May-2010)
fsck.ext3: Superblock invalid
, trying backup blocks
fsck.ext3: Bad magic number in super-block while trying to open /dev/mapper/VolGroup_ID_17253-LogVol3

The superblock could not be read or does not describe a correct ext2
filesystem. If the device is valid and it really contains an ext2
filesystem (and not swap or ufs or something else)
, then the superblock
is corrupt
, and you might try running e2fsck with an alternate superblock:
e2fsck -b 
8193 <device>

這里面說無法修復,原因是 superblock 損壞了,所以 fsck 無法定位相關分區數據。建議使用備份的 superblok。

我們知道,superblock 對于分區而言非常重要,因此 ext2/3 文件系統將 superblock 備份到了磁盤的各個位置,如此多的備份,降低了所有 superblock 備份都損壞的概率。

可是問題是,這些備份在哪里呢?superblock 的備份是和 block size 相關的。詢問后得知,這個服務器上的分區的參數都是默認設置,只是調整了一下大小和個數。既然如此,那么所有的分區都應該是同樣的 block size,那么它們備份 superblock 的相對位置也都一樣。

鑒于此,我們打算通過 LogVol7 分區給出一個superblock 備份相對位置的列表:

[root@localhost liveuser]# dumpe2fs /dev/VolGroup_ID_17253/LogVol7 | grep -i superblock
dumpe2fs 
1.41.12 (17-May-2010)
Primary superblock at 
0, Group descriptors at 1-4
Backup superblock at 
32768, Group descriptors at 32769-32772
Backup superblock at 
98304, Group descriptors at 98305-98308
Backup superblock at 
163840, Group descriptors at 163841-163844
Backup superblock at 
229376, Group descriptors at 229377-229380
Backup superblock at 
294912, Group descriptors at 294913-294916
Backup superblock at 
819200, Group descriptors at 819201-819204
Backup superblock at 
884736, Group descriptors at 884737-884740
Backup superblock at 
1605632, Group descriptors at 1605633-1605636
Backup superblock at 
2654208, Group descriptors at 2654209-2654212
Backup superblock at 
4096000, Group descriptors at 4096001-4096004
Backup superblock at 
7962624, Group descriptors at 7962625-7962628
Backup superblock at 
11239424, Group descriptors at 11239425-11239428

嘗試使用 32768 的備份:

[root@localhost liveuser]# fsck.ext3 -B 1024 -b 32768 /dev/mapper/VolGroup_ID_17253-LogVol3
e2fsck 
1.41.12 (17-May-2010)
fsck.ext3: Bad magic number in super-block while trying to open /dev/mapper/VolGroup_ID_17253-LogVol3

The superblock could not be read or does not describe a correct ext2
filesystem. If the device is valid and it really contains an ext2
filesystem (and not swap or ufs or something else)
, then the superblock
is corrupt
, and you might try running e2fsck with an alternate superblock:
e2fsck -b 
8193 <device>


這個備份還是不行,再換一個:

[root@localhost liveuser]# fsck.ext3 -b 98304 /dev/VolGroup_ID_17253/LogVol3
e2fsck 
1.41.12 (17-May-2010)
Superblock needs_recovery flag is clear
, but journal has data.
Recovery flag not set in backup superblock
, so running journal anyway.
/dev/VolGroup_ID_17253/LogVol3: recovering journal
Adding dirhash hint to filesystem.

Pass 
1: Checking inodes, blocks, and sizes
Inode 
81, i_blocks is 8, should be 0. Fix<y>?

不錯,98304 這個備份是好的。已經修復了一些內容了,只要繼續就很有可能修復系統。不過,當我讓朋友點擊 y 確認的時候,悲劇又發生了。他在復制粘貼返回信息的時候,習慣了 Windows 的 Ctrl-C 和 Ctrl-V,呃,我們要知道,Ctrl-C 在 命令行下有另外的含義,就是終止程序運行。結果,他按 Ctrl-C 了……

[1]+ Stopped fsck.ext3 -b 98304 /dev/VolGroup_ID_17253/LogVol3

磁盤修復一半的時候強行終止退出?我現在非常不確定系統當前的狀態和磁盤的狀態,我只好讓朋友重新啟動,重來。重啟前跟他說,千萬不要再做任何異常的操作了,否則可能系統會無法恢復的。

很不幸,我的話又變成了耳旁風。重啟后,他興高采烈的告訴我說,可以看見 LogVol3 啦,不過有些文件夾還是打不開啊。我暈倒~~

我非常懷疑他是不是關心硬盤的數據。這個硬盤僅僅是恢復了 superblock,但是必然還有很多其它的問題,冒然以可寫形式綁定,磁盤很可能會丟數據的。我給了他嚴重警告,再這么做我就不幫忙了,我替你擔心半天,你反而不聽我勸,混不在乎。

重新開始修復硬盤:

[root@localhost liveuser]# fsck.ext3 -y -b 98304 /dev/VolGroup_ID_17253/LogVol3



Free blocks count wrong for group #
78 (32254, counted=5049).
Fix? yes

Free blocks count wrong for group #
79 (32254, counted=4724).
Fix? yes

Free blocks count wrong (
2566343, counted=1869026).
Fix? yes

Free inodes count wrong for group #
0 (16373, counted=16288).
Fix? yes



/dev/VolGroup_ID_17253/LogVol3: ***** FILE SYSTEM WAS MODIFIED *****
/dev/VolGroup_ID_17253/LogVol3: 
229199/1310720 files (1.6% non-contiguous), 752414/2621440 blocks

經過了一段時間的等待,LogVol3 修復終于完成了。由于得知當時LogVolHome進行了大量的讀寫,因此,雖然可以掛載,但是非常懷疑其中也有故障,因此也許進行磁盤檢查和修復:

[root@localhost /]# fsck.ext3 /dev/VolGroup_ID_17253/LogVolHome
e2fsck 
1.41.12 (17-May-2010)
/dev/VolGroup_ID_17253/LogVolHome contains a file system with errors
, check forced.
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/VolGroup_ID_17253/LogVolHome: 
2301889/3859072 files (9.9% non-contiguous), 2554717/7716864 blocks

果然,確實有錯誤,并且修復了。

然后,嘗試掛載 LogVol3,看這次是否沒有問題了:

[root@localhost /]# mkdir /media/myroot
[root@localhost /]# mount -t ext3 /dev/VolGroup_ID_17253/LogVol3 /media/myroot

一切正常,沒有任何報錯。磁盤修復基本可以宣告完成,接下來就是備份和重新啟動了。

六、備份重要數據


重新啟動系統,如果一切正常,系統會正常加載所有的服務器,并且開始提供服務,那時數據就會發生改變了,在還不知道服務器是否正常的情況下貿然啟動服務器,而沒有備份,這是危險的。因此,我們先備份重要數據。

[root@localhost /]# cd /media/myroot
[root@localhost myroot]# tar -czvf /media/BACKUP/www.tgz www
[root@localhost myroot]# tar -czvf /media/BACKUP/server_lampp.tgz opt/lampp
[root@localhost myroot]# tar -czvf /media/BACKUP/server_mysql.tgz opt/lampp/var/mysql


最后確認一下數據是否已經備份好了。

[root@localhost myroot]# ls l /media/BACKUP
total 
6287380
-rwxrwxrwx. 
1 liveuser liveuser 92690926 Feb 10 19:35 server_lampp.tgz
-rwxrwxrwx. 
1 liveuser liveuser 28670158 Feb 10 19:30 server_mysql.tgz
-rwxrwxrwx. 
1 liveuser liveuser 5943229016 Feb 10 17:29 server_root_image.gz
-rwxrwxrwx. 
1 liveuser liveuser 373677732 Feb 10 19:34 www.tgz


七、重新啟動


分區修好了,fsck檢查各個分區也都沒問題了,該備份的都備份了??梢試L試重新啟動系統了,祈禱吧……

很不幸,沒起來。:(

啟動的過程,系統報錯:

Remounting root filesystem in read-write mode:
Setting up Logical Volume Management:
Checking filesystems
/boot: clean
, 38/26208 files, 15754/104420 blocks
/dev/VolGroup_ID_17253/LogVol4: clean
, 22/139392 files, 12950/278528 blocks
/dev/VolGroup_ID_17253/LogVol7: clean
, 132904/7028736 files, 882601/14041088 blocks
/dev/VolGroup_ID_17253/LogVol6: clean
, 22314/704512 files, 168941/1409024 blocks
/dev/VolGroup_ID_17253/LogVolHome contains a file system with errors
, check forced.
 /dev/VolGroup_ID_17253/LogVolHome:
 Inode 
1340876 is too big.
 
/dev/VolGroup_ID_17253/LogVolHome: UNEXPECTED INCONSISTENCY
; RUN fsck MANUALLY.
        (i.e., without -a or -p options)
                                                           
[FAILED]

*** An error occurred during the file system check.
*** Dropping you to a shell
; the system will reboot
*** when you leave the shell.
*** Warning -- SELinux is active
*** Disabling security enforcement for system recovery.
*** Run 'setenforce 
1' to reenable.
Give root password for maintenance
(or type Control-D to continue): _

經過Google,發現這是 e2fsprogs,也就是 fsck.ext3 所在包,早期版本的一個bug。如果inode節點很大,會觸發這個bug。1.40以后就沒有這個問題了,

這也看出來我一直堅持要升級的原因之一。越早的版本的軟件包含的bug就越多,每年新的版本都會修復大量的bug。而那些堅持版本越老越穩定的人,實際上是非常錯誤的。太新和太老都是不合理的,要取一個合適的折中。像 RHEL 4,甚至5,就太老了。其內很多版本包含了大量的bug,可是由于沒有升級到新的版本,RedHat不得不花大力氣去將修復bug的補丁打到老的軟件上,而有相當數量的補丁是完全基于新版本API的,那些補丁就沒有辦法打在老軟件上。RHEL/CentOS所謂的長期穩定,也就是因為RedHat有大量的人力在做這種將新軟件的補丁打到老軟件上的事情??墒牵行r候,我們直接用新的版本會更好。

我沒心思在LiveCD里面升級e2fsprogs,這是個危險的操作。觸發這個bug的條件是一個目錄下的文件太多,從而導致inode過大。了解了一下,那個目錄正好是服務器故障前正在清理的目錄。那么我們就先把這個目錄清理掉再說。

由于這個目錄包含有太多的文件,計算了一下清理這個目錄會花1-2個小時。已經是凌晨了,寫了個腳本,開始執行,清理完文件后,會自動重啟?;旧显撟龅亩甲隽?,應該沒有什么問題了。腳本執行后,就讓朋友回家好了。

很幸運,朋友到家后,給我發來消息,服務器正常啟動了,Web應用也都開始正常提供服務了。一切似乎都恢復正常了。很慶幸,沒有機會用上備份(那就意味著要重裝系統之類的大操作了)。

八、后記


這次系統故障導致我朋友很緊張的原因之一就是系統沒有備份。最近一次備份也是幾個月前,因此如果硬盤無法恢復,那么直接造成的結果就是這幾個月的工作全部丟失。其實使用Linux備份還是比較容易的。最簡單的辦法是用crontab,定義的壓縮一份重要數據,傳到別的服務器上去,或者復制到別的物理硬盤上??上в捎谒麄児緦?Linux 熟悉的人不多,因此沒有人去做而已。

這也反映了一個問題。我們經??吹筋愃朴冢?#8220;什么服務器最安全快速?”、“什么編程語言效率最高?”的問題。這類問題實際上問題本身就有問題。沒有最安全的服務器,沒有最好的編程語言,只有最合適你的。

很多人都說 Linux 如何如何安全,Windows 如何如何脆弱。真不知道這些人從哪得到的數據?還是大腦進水了?如果你說的是精心配置下的服務器,那么很難說誰更安全,Windows 的內核非常健壯,相比 Linux 而言,更穩定和安全。你只要查一下 Linux 內核在過去幾年內所出現的安全漏洞的數量,對比一下 Windows 2000/2003內核的漏洞的數量,你就會發現這個問題。而 IIS 出現的安全漏洞,和 Apache 比起來,誰也不敢說誰更安全。而就配置而言,我們都可以對每個服務器配置執行賬戶,限定用戶權限。相比而言,Windows 的 ACL 比 Linux 的要更復雜和完善。當然,Linux 也有 Linux 的優勢。它們是處于一個安全等級上的。無論哪個系統,都可以配置出安全、高效的服務器。

但是,你得精心配置啊。我想大多數人對二者的安全配置并不熟悉,也似乎沒有花大量的經歷和試驗去熟悉。那么對大多數人而言,似乎默認配置就是最好的。就像我這個朋友,問他各個配置為什么這樣,為什么那樣,他幾乎都是一個答案,不知道和默認就是這樣,沒改。這讓我很無語。

安全界上,凡是默認配置的,基本都是有隱患的。大多數入侵啊、蠕蟲啊,也都是針對默認配置的機器做的。不管你是 Linux 也好,Windows 也罷。只要是默認配置,你就不要提什么誰更安全,那是扯淡。

還有一個問題就是升級。這個服務器用的是 RHEL,貌似國內好像比較喜歡用這個。雖然其內的軟件很老,但是這個發布確實比較穩定,你要是用正版的,有售后支持,我也覺得沒什么。但是問題是,國人似乎用盜版成癮。覺得既然能買 RHEL的盜版盤(甚至是下載,都不用買),為什么還花錢?這個服務器就是如此??墒?,你用盜版,如何升級?而且,盜版的售后找誰?國外用RHEL的人多,那是沖著售后去的,人家有24小時應急響應,服務器出了問題很快就能解決。國內人用 RHEL,還不用帶售后,這是為啥?百思不得其解。哪怕你用CentOS呢,雖然沒有售后,但起碼可以升級啊。呵呵,也許人性使然。

不論如何,服務器修好了。一切似乎又恢復了正常。但是,真的如此么?造成這次故障的,致使那個累積了太多文件的php緩存代碼還在按照以往工作著,今天出現的問題,說不定什么時候就又會出現。問題需要進一步的挖掘,才能真正的讓服務器,健康的運行。當然,今天那個朋友可以好好睡個覺了,下一次出問題,起碼也是半個月后了,還有時間來分析和解決深層次的問題。

參考


[1] http://www.cyberciti.biz/tips/understanding-unixlinux-filesystem-superblock.html
[2] http://en.wikipedia.org/wiki/Ext3#Journaling_levels
[3] http://www.ibm.com/developerworks/cn/linux/filesystem/lvm/lvm-1/index.html