前幾天接到朋友聯(lián)系,說(shuō)他的服務(wù)器壞了,啟動(dòng)不起來(lái)了。這是一個(gè)RHEL 4的服務(wù)器,而且是那種盜版RHEL 4,也就是說(shuō)沒(méi)有售后服務(wù)的,聯(lián)系我問(wèn)問(wèn)能不能幫幫忙。我也很久沒(méi)有弄過(guò)Linux系統(tǒng)上的東西了。只好嘗試一下,慶幸的是,修好了,并幫朋友維護(hù)了一段時(shí)間,在此記錄一些修復(fù)和維護(hù)中碰到的問(wèn)題。修復(fù) superblock 本身并不復(fù)雜,我覺(jué)得值得記錄的是修復(fù)過(guò)程中的思考過(guò)程,和修復(fù)所需要注意的問(wèn)題。

一、啟動(dòng)故障


系統(tǒng)無(wú)法啟動(dòng),啟動(dòng)時(shí)內(nèi)核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!
 _


看到這個(gè)報(bào)錯(cuò),我Google了一下,很快就發(fā)現(xiàn),這很有可能是硬盤(pán)的superblock [1] 壞了,因此感覺(jué)需要修復(fù)superblock。

詢(xún)問(wèn)了一下,癱瘓之前都發(fā)生了些什么。朋友提到了一個(gè)情況,在癱瘓前,他發(fā)現(xiàn)有一個(gè)目錄存儲(chǔ)了太多的文件了(確實(shí)非常的多,大約是幾百萬(wàn)到上千萬(wàn)個(gè)文件,程序設(shè)計(jì)上有問(wèn)題),這是他寫(xiě)的一個(gè)php做緩存的腳本生成的后綴為.php的文件,絕大多數(shù)都已經(jīng)是垃圾文件了。他覺(jué)得太占磁盤(pán)空間了,想清理一下,于是用下面的命令刪除這些生成的文件:

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

可是執(zhí)行命令后,等了幾分鐘,發(fā)現(xiàn)系統(tǒng)沒(méi)有反應(yīng)。于是就Ctrl-C了,后來(lái)發(fā)現(xiàn)系統(tǒng)還是很慢,于是就執(zhí)行reboot了。接下來(lái),系統(tǒng)就啟動(dòng)不起來(lái)了。

可以推斷,其實(shí)并不是系統(tǒng)沒(méi)有反應(yīng),而是刪除如此大量的文件,需要相當(dāng)?shù)臅r(shí)間,當(dāng)Ctrl-C后,磁盤(pán)寫(xiě)入行為并沒(méi)有因此而立即停止,在如此密集磁盤(pán)寫(xiě)入時(shí)執(zhí)行reboot,確實(shí)比較容易引起磁盤(pán)上的故障。再加上這塊硬盤(pán)雖然是ext3,但是日志使用的是默認(rèn)的ordered [2],出問(wèn)題的幾率就更大了,所以懷疑是 superblock 的可能性就更大了。

二、修復(fù)環(huán)境


當(dāng)時(shí)朋友有些慌張了,因?yàn)樗J(rèn)為這是他操作失誤導(dǎo)致服務(wù)器癱瘓,有些不知道該怎么辦了,那天我有事情比較忙,打算晚些時(shí)候再回來(lái)幫他。隨后的操作中可以看到他做了很多危險(xiǎn)的操作,我會(huì)一一提出來(lái),大家有類(lèi)似情況的時(shí)候,一定要注意。

首先是他把硬盤(pán)直接拆下來(lái)來(lái)了,打算拿回公司備份。備份的想法是好的,如果有合適的服務(wù)器,拆下來(lái)接過(guò)去備份也是對(duì)的。但是問(wèn)題就在于,這是一塊SCSI接口的硬盤(pán),是一堆Linux分區(qū),使用的還是LVM [3],而他公司沒(méi)有一個(gè)SCSI接口的機(jī)器,他可能還需要去市場(chǎng)上買(mǎi)個(gè)SCSI卡,而且,他也沒(méi)有一臺(tái)Linux的機(jī)器,全是Windows,他甚至打算使用explore2fs之類(lèi)的不成熟的軟件來(lái)掛載這塊硬盤(pán)。

這問(wèn)題就大了。買(mǎi)的SCSI卡的穩(wěn)定性如何?別是雜牌的,卡再造成硬盤(pán)的二次數(shù)據(jù)損失。用Windows備份可能損壞的硬盤(pán)的數(shù)據(jù)是非常危險(xiǎn)的,explorer2fs這類(lèi)Windows掛載ext2/3分區(qū)的軟件從來(lái)就沒(méi)成熟過(guò),至今為止還有大量的特性不支持,只是試驗(yàn)產(chǎn)品。使用他們掛載分區(qū),很可能會(huì)造成數(shù)據(jù)損失。另外,之前說(shuō)過(guò),問(wèn)題很可能是superblock出問(wèn)題了,這種情況下,不修復(fù) superblock ,誰(shuí)也別想掛載成功,而Windows上顯然沒(méi)有這類(lèi)軟件。

碰到這類(lèi)問(wèn)題,比較好的辦法是使用另一臺(tái)具有SCSI接口的Linux,進(jìn)行修復(fù)、掛載、備份。當(dāng)然,對(duì)于朋友而言,這不現(xiàn)實(shí)。那就折中,還在原服務(wù)器上修復(fù),但是使用 Linux LiveCD 進(jìn)行修復(fù),將數(shù)據(jù)備份到外置 USB 硬盤(pán)上。

這里需要注意的是,即使硬盤(pán)有幾個(gè)分區(qū),只壞了一個(gè),備份到其它貌似還好的分區(qū)似乎也不是什么大問(wèn)題。但是,在修復(fù)、備份的時(shí)候,一定要盡可能的避免被修復(fù)磁盤(pán)的寫(xiě)操作,無(wú)論是哪個(gè)分區(qū)。因?yàn)樵趩?wèn)題確認(rèn)修復(fù)前,你并不能肯定只有那個(gè)報(bào)錯(cuò)的分區(qū)有故障,其它一切正常。

那天朋友在機(jī)房的時(shí)候,他什么都沒(méi)有帶,只能眼睜睜的一次次的重啟,看錯(cuò)誤日志,試著能不能進(jìn)系統(tǒng)。這是很不好的,如果懷疑硬盤(pán)出了故障,那么這么一次次重啟很容易加重問(wèn)題,因此一定要避免。

沒(méi)有任何修復(fù)環(huán)境是沒(méi)有辦法工作的。我讓朋友回去準(zhǔn)備幾張光盤(pán),都是可引導(dǎo)的修復(fù)盤(pán)。朋友對(duì) Linux 有一些經(jīng)驗(yàn)但不是很熟悉,折中起見(jiàn),我讓朋友準(zhǔn)備了 Fedora 14、Ubuntu 10.10、UBCD等光盤(pán)備用,并且打算使用 Fedora 14 的 Live CD 進(jìn)行修復(fù)。并且第二天帶一個(gè)大容量的,最好是空的USB硬盤(pán)來(lái),備份數(shù)據(jù)。并且,在家用 Fedora 14 啟動(dòng)一下,看看怎么進(jìn)入命令行模式,第二天啟動(dòng)的時(shí)候,不要進(jìn)入圖形界面。在命令行模式下修復(fù)。

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

首先是告訴我,在服務(wù)器上 Fedora 啟動(dòng)后直接進(jìn)桌面了,沒(méi)有選項(xiàng),點(diǎn)了點(diǎn)不知道怎么修復(fù),甚至打開(kāi)了故障硬盤(pán)的幾個(gè)分區(qū),沒(méi)找到需要備份的文件。于是乎,又啟動(dòng)了Ubuntu選擇了修復(fù)壞系統(tǒng),結(jié)果發(fā)現(xiàn)要安裝文件,然后報(bào)錯(cuò)說(shuō)沒(méi)有硬盤(pán),于是退出了。

敢情這哥們直接把我說(shuō)的話(huà)當(dāng)耳旁風(fēng),在故障服務(wù)器上直接啟動(dòng)圖形界面,更甚的是,他還嘗試讓 Ubuntu 覆蓋安裝 RHEL 4。幸好分區(qū)的 superblock 是壞的,不然全毀了。

這里面有三個(gè)錯(cuò)誤。首先是不應(yīng)該啟動(dòng)圖形界面,其次是錯(cuò)誤的理解了 Ubuntu 中修復(fù)系統(tǒng)選項(xiàng)的含義,然后是在菜單上點(diǎn)擊服務(wù)器分區(qū)從而激發(fā)了綁定操作,很可能直接造成寫(xiě)入操作。

這些都應(yīng)該是前一天晚上回家琢磨的,他顯然偷懶了,直接拿故障環(huán)境練手。如果不是這哥們命大,而且系統(tǒng)出的問(wèn)題沒(méi)有那么嚴(yán)重,那么這些連續(xù)的錯(cuò)誤,很可能造成不可挽回的結(jié)果。

雖然對(duì)于 Windows 用戶(hù)來(lái)說(shuō),看著純命令行覺(jué)得無(wú)從下手,但是,得到了美麗的界面往往意味著你得付出些什么。在以前的某些 LiveCD 中,加載圖形界面的時(shí)候,由于各種驅(qū)動(dòng)和程序的加載,錯(cuò)誤的進(jìn)行了硬盤(pán)的寫(xiě)操作,從而導(dǎo)致有些人抱怨過(guò)啟動(dòng) LiveCD 導(dǎo)致硬盤(pán)數(shù)據(jù)二次損壞,最終使得修復(fù)無(wú)望。雖然,最近這些版本的 LiveCD 可能沒(méi)有這類(lèi)問(wèn)題,但是為了避免萬(wàn)一,應(yīng)當(dāng)盡量減少對(duì)硬盤(pán)寫(xiě)入操作的可能性。既然所有修復(fù)行為都會(huì)在命令行模式下進(jìn)行,那就沒(méi)必要啟動(dòng)圖形界面冒風(fēng)險(xiǎn)。

我讓他帶著 Ubuntu 的盤(pán)就是以防萬(wàn)一,萬(wàn)一 Fedora 啟動(dòng)出現(xiàn)奇怪的問(wèn)題,我們可以用 Ubuntu 啟動(dòng)然后修復(fù)系統(tǒng)。而不是進(jìn)入 Ubuntu的修復(fù)系統(tǒng)選項(xiàng)。那個(gè)選項(xiàng)是給 Ubuntu 系統(tǒng)準(zhǔn)備的,是以光盤(pán)上的系統(tǒng)文件及配置覆蓋硬盤(pán)上的系統(tǒng)文件及配置,從而達(dá)到修復(fù)系統(tǒng)的目的。這顯然和我們要修復(fù)的 RHEL 驢唇不對(duì)馬嘴。修復(fù)系統(tǒng)所需要的只是一個(gè) Linux 環(huán)境而已。

至于最后在菜單上點(diǎn)擊硬盤(pán)分區(qū),甚至還打開(kāi)里面的文件看看,這就是純屬找死了。系統(tǒng)已經(jīng)報(bào)錯(cuò)了,即使能夠掛載成功,文件系統(tǒng)也很可能是有問(wèn)題的,必須在訪(fǎng)問(wèn)前先f(wàn)sck,否則很可能會(huì)引發(fā)更大的問(wèn)題。畢竟默認(rèn) Fedora 掛載可不是只讀,而是可讀寫(xiě),混亂后,誰(shuí)也無(wú)法預(yù)測(cè)會(huì)把硬盤(pán)寫(xiě)成啥樣。

三、確認(rèn)問(wèn)題


該準(zhǔn)備的光盤(pán)準(zhǔn)備了,不該操作的操作也做了,這讓我很無(wú)語(yǔ),雖然懷疑僅僅是邏輯錯(cuò)誤導(dǎo)致superblock壞掉,應(yīng)該不會(huì)有大問(wèn)題,但還是讓我對(duì)這次修復(fù)的可能性感到懷疑。至少這朋友完全不按照我說(shuō)的辦,經(jīng)常的做些自己覺(jué)得沒(méi)什么的危險(xiǎn)操作,哎,前景黯淡啊。

既然他已經(jīng)改點(diǎn)的都點(diǎn)了,該造成的損壞基本上也造成了。那就在 Fedora LiveCD 的圖形界面下修復(fù)吧,至少他還可以更方便的把命令返回結(jié)果通過(guò) firefox 給我發(fā)過(guò)來(lái)。比用 android 手機(jī)通訊好多了。

首先我需要知道,都有哪些文件系統(tǒng)被他掛載了,另外,系統(tǒng)上有哪些分區(qū)。

[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)


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

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

[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}是交換分區(qū),LogVol2肯定不是我們的目標(biāo),那么缺失的是LogVol3,這個(gè)分區(qū)出問(wèn)題了。如此,我們手動(dòng)綁定一下 LogVol3 看一下報(bào)錯(cuò)信息。

[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

這里我們可以直接看到報(bào)錯(cuò)說(shuō) 'bad superblock' 信息。
然后我們?cè)倏匆幌聝?nèi)核報(bào)錯(cuò)。

[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.

這里我們看到,內(nèi)核報(bào)錯(cuò)說(shuō)無(wú)法在 dm-2 上找到 ext3 文件系統(tǒng)。這很有可能就是 superblock 損壞造成的問(wèn)題。

另外,我們看到,正如我所擔(dān)心的那樣,不僅僅是 dm-2 (LogVol3) 有故障, dm-9 分區(qū)也有故障。很可能其它分區(qū)也有問(wèn)題,都需要在使用前,進(jìn)行磁盤(pán)檢查 fsck。冒失的訪(fǎng)問(wèn),很可能會(huì)造成數(shù)據(jù)損壞或丟失。

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

四、鏡像備份損壞的硬盤(pán)


執(zhí)行 fsck 會(huì)對(duì)磁盤(pán)進(jìn)行寫(xiě)操作,我們需要在此之前對(duì)磁盤(pán)進(jìn)行鏡像備份。這樣萬(wàn)一 fsck 的修復(fù)造成了更大的損失,我們還可以恢復(fù)原始狀態(tài)。

我讓朋友插上 USB 硬盤(pán),桌面上會(huì)自動(dòng)出現(xiàn)這個(gè)硬盤(pán)的圖標(biāo),如果沒(méi)有菜單上也會(huì)有,點(diǎn)擊菜單項(xiàng)打開(kāi)這個(gè) USB 硬盤(pán),會(huì)觸發(fā) Fedora 自動(dòng)綁定該硬盤(pán)。這么操作省的朋友敲命令了 (心里想,反正之前不該點(diǎn)的也都點(diǎn)了,破罐破摔吧~~)。

通過(guò) mount 命令找到新綁定的磁盤(pán)路徑:

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

然后,開(kāi)始鏡像 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

確認(rèn)一下文件確實(shí)存在:

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

五、修復(fù)


先進(jìn)行第一次修復(fù)嘗試。

[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>

這里面說(shuō)無(wú)法修復(fù),原因是 superblock 損壞了,所以 fsck 無(wú)法定位相關(guān)分區(qū)數(shù)據(jù)。建議使用備份的 superblok。

我們知道,superblock 對(duì)于分區(qū)而言非常重要,因此 ext2/3 文件系統(tǒng)將 superblock 備份到了磁盤(pán)的各個(gè)位置,如此多的備份,降低了所有 superblock 備份都損壞的概率。

可是問(wèn)題是,這些備份在哪里呢?superblock 的備份是和 block size 相關(guān)的。詢(xún)問(wèn)后得知,這個(gè)服務(wù)器上的分區(qū)的參數(shù)都是默認(rèn)設(shè)置,只是調(diào)整了一下大小和個(gè)數(shù)。既然如此,那么所有的分區(qū)都應(yīng)該是同樣的 block size,那么它們備份 superblock 的相對(duì)位置也都一樣。

鑒于此,我們打算通過(guò) LogVol7 分區(qū)給出一個(gè)superblock 備份相對(duì)位置的列表:

[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>


這個(gè)備份還是不行,再換一個(gè):

[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>?

不錯(cuò),98304 這個(gè)備份是好的。已經(jīng)修復(fù)了一些內(nèi)容了,只要繼續(xù)就很有可能修復(fù)系統(tǒng)。不過(guò),當(dāng)我讓朋友點(diǎn)擊 y 確認(rèn)的時(shí)候,悲劇又發(fā)生了。他在復(fù)制粘貼返回信息的時(shí)候,習(xí)慣了 Windows 的 Ctrl-C 和 Ctrl-V,呃,我們要知道,Ctrl-C 在 命令行下有另外的含義,就是終止程序運(yùn)行。結(jié)果,他按 Ctrl-C 了……

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

磁盤(pán)修復(fù)一半的時(shí)候強(qiáng)行終止退出?我現(xiàn)在非常不確定系統(tǒng)當(dāng)前的狀態(tài)和磁盤(pán)的狀態(tài),我只好讓朋友重新啟動(dòng),重來(lái)。重啟前跟他說(shuō),千萬(wàn)不要再做任何異常的操作了,否則可能系統(tǒng)會(huì)無(wú)法恢復(fù)的。

很不幸,我的話(huà)又變成了耳旁風(fēng)。重啟后,他興高采烈的告訴我說(shuō),可以看見(jiàn) LogVol3 啦,不過(guò)有些文件夾還是打不開(kāi)啊。我暈倒~~

我非常懷疑他是不是關(guān)心硬盤(pán)的數(shù)據(jù)。這個(gè)硬盤(pán)僅僅是恢復(fù)了 superblock,但是必然還有很多其它的問(wèn)題,冒然以可寫(xiě)形式綁定,磁盤(pán)很可能會(huì)丟數(shù)據(jù)的。我給了他嚴(yán)重警告,再這么做我就不幫忙了,我替你擔(dān)心半天,你反而不聽(tīng)我勸,混不在乎。

重新開(kāi)始修復(fù)硬盤(pán):

[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

經(jīng)過(guò)了一段時(shí)間的等待,LogVol3 修復(fù)終于完成了。由于得知當(dāng)時(shí)LogVolHome進(jìn)行了大量的讀寫(xiě),因此,雖然可以?huà)燧d,但是非常懷疑其中也有故障,因此也許進(jìn)行磁盤(pán)檢查和修復(fù):

[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

果然,確實(shí)有錯(cuò)誤,并且修復(fù)了。

然后,嘗試掛載 LogVol3,看這次是否沒(méi)有問(wèn)題了:

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

一切正常,沒(méi)有任何報(bào)錯(cuò)。磁盤(pán)修復(fù)基本可以宣告完成,接下來(lái)就是備份和重新啟動(dòng)了。

六、備份重要數(shù)據(jù)


重新啟動(dòng)系統(tǒng),如果一切正常,系統(tǒng)會(huì)正常加載所有的服務(wù)器,并且開(kāi)始提供服務(wù),那時(shí)數(shù)據(jù)就會(huì)發(fā)生改變了,在還不知道服務(wù)器是否正常的情況下貿(mào)然啟動(dòng)服務(wù)器,而沒(méi)有備份,這是危險(xiǎn)的。因此,我們先備份重要數(shù)據(jù)。

[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


最后確認(rèn)一下數(shù)據(jù)是否已經(jīng)備份好了。

[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


七、重新啟動(dòng)


分區(qū)修好了,fsck檢查各個(gè)分區(qū)也都沒(méi)問(wèn)題了,該備份的都備份了??梢試L試重新啟動(dòng)系統(tǒng)了,祈禱吧……

很不幸,沒(méi)起來(lái)。:(

啟動(dòng)的過(guò)程,系統(tǒng)報(bào)錯(cuò):

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): _

經(jīng)過(guò)Google,發(fā)現(xiàn)這是 e2fsprogs,也就是 fsck.ext3 所在包,早期版本的一個(gè)bug。如果inode節(jié)點(diǎn)很大,會(huì)觸發(fā)這個(gè)bug。1.40以后就沒(méi)有這個(gè)問(wèn)題了,

這也看出來(lái)我一直堅(jiān)持要升級(jí)的原因之一。越早的版本的軟件包含的bug就越多,每年新的版本都會(huì)修復(fù)大量的bug。而那些堅(jiān)持版本越老越穩(wěn)定的人,實(shí)際上是非常錯(cuò)誤的。太新和太老都是不合理的,要取一個(gè)合適的折中。像 RHEL 4,甚至5,就太老了。其內(nèi)很多版本包含了大量的bug,可是由于沒(méi)有升級(jí)到新的版本,RedHat不得不花大力氣去將修復(fù)bug的補(bǔ)丁打到老的軟件上,而有相當(dāng)數(shù)量的補(bǔ)丁是完全基于新版本API的,那些補(bǔ)丁就沒(méi)有辦法打在老軟件上。RHEL/CentOS所謂的長(zhǎng)期穩(wěn)定,也就是因?yàn)镽edHat有大量的人力在做這種將新軟件的補(bǔ)丁打到老軟件上的事情??墒?,有些時(shí)候,我們直接用新的版本會(huì)更好。

我沒(méi)心思在LiveCD里面升級(jí)e2fsprogs,這是個(gè)危險(xiǎn)的操作。觸發(fā)這個(gè)bug的條件是一個(gè)目錄下的文件太多,從而導(dǎo)致inode過(guò)大。了解了一下,那個(gè)目錄正好是服務(wù)器故障前正在清理的目錄。那么我們就先把這個(gè)目錄清理掉再說(shuō)。

由于這個(gè)目錄包含有太多的文件,計(jì)算了一下清理這個(gè)目錄會(huì)花1-2個(gè)小時(shí)。已經(jīng)是凌晨了,寫(xiě)了個(gè)腳本,開(kāi)始執(zhí)行,清理完文件后,會(huì)自動(dòng)重啟?;旧显撟龅亩甲隽?,應(yīng)該沒(méi)有什么問(wèn)題了。腳本執(zhí)行后,就讓朋友回家好了。

很幸運(yùn),朋友到家后,給我發(fā)來(lái)消息,服務(wù)器正常啟動(dòng)了,Web應(yīng)用也都開(kāi)始正常提供服務(wù)了。一切似乎都恢復(fù)正常了。很慶幸,沒(méi)有機(jī)會(huì)用上備份(那就意味著要重裝系統(tǒng)之類(lèi)的大操作了)。

八、后記


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

這也反映了一個(gè)問(wèn)題。我們經(jīng)??吹筋?lèi)似于,“什么服務(wù)器最安全快速?”、“什么編程語(yǔ)言效率最高?”的問(wèn)題。這類(lèi)問(wèn)題實(shí)際上問(wèn)題本身就有問(wèn)題。沒(méi)有最安全的服務(wù)器,沒(méi)有最好的編程語(yǔ)言,只有最合適你的。

很多人都說(shuō) Linux 如何如何安全,Windows 如何如何脆弱。真不知道這些人從哪得到的數(shù)據(jù)?還是大腦進(jìn)水了?如果你說(shuō)的是精心配置下的服務(wù)器,那么很難說(shuō)誰(shuí)更安全,Windows 的內(nèi)核非常健壯,相比 Linux 而言,更穩(wěn)定和安全。你只要查一下 Linux 內(nèi)核在過(guò)去幾年內(nèi)所出現(xiàn)的安全漏洞的數(shù)量,對(duì)比一下 Windows 2000/2003內(nèi)核的漏洞的數(shù)量,你就會(huì)發(fā)現(xiàn)這個(gè)問(wèn)題。而 IIS 出現(xiàn)的安全漏洞,和 Apache 比起來(lái),誰(shuí)也不敢說(shuō)誰(shuí)更安全。而就配置而言,我們都可以對(duì)每個(gè)服務(wù)器配置執(zhí)行賬戶(hù),限定用戶(hù)權(quán)限。相比而言,Windows 的 ACL 比 Linux 的要更復(fù)雜和完善。當(dāng)然,Linux 也有 Linux 的優(yōu)勢(shì)。它們是處于一個(gè)安全等級(jí)上的。無(wú)論哪個(gè)系統(tǒng),都可以配置出安全、高效的服務(wù)器。

但是,你得精心配置啊。我想大多數(shù)人對(duì)二者的安全配置并不熟悉,也似乎沒(méi)有花大量的經(jīng)歷和試驗(yàn)去熟悉。那么對(duì)大多數(shù)人而言,似乎默認(rèn)配置就是最好的。就像我這個(gè)朋友,問(wèn)他各個(gè)配置為什么這樣,為什么那樣,他幾乎都是一個(gè)答案,不知道和默認(rèn)就是這樣,沒(méi)改。這讓我很無(wú)語(yǔ)。

安全界上,凡是默認(rèn)配置的,基本都是有隱患的。大多數(shù)入侵啊、蠕蟲(chóng)啊,也都是針對(duì)默認(rèn)配置的機(jī)器做的。不管你是 Linux 也好,Windows 也罷。只要是默認(rèn)配置,你就不要提什么誰(shuí)更安全,那是扯淡。

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

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

參考


[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