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

一、啟動故障


系統(tǒng)無法啟動,啟動時內(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!
 _


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

三、確認(rèn)問題


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

既然他已經(jīng)改點(diǎn)的都點(diǎn)了,該造成的損壞基本上也造成了。那就在 Fedora LiveCD 的圖形界面下修復(fù)吧,至少他還可以更方便的把命令返回結(jié)果通過 firefox 給我發(fā)過來。比用 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個綁定目錄的分區(qū),LogVol{3,4,6,7,Home},LogVol3 好像就是那個壞的分區(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,這個分區(qū)出問題了。如此,我們手動綁定一下 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' 信息。
然后我們再看一下內(nèi)核報錯。

[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)核報錯說無法在 dm-2 上找到 ext3 文件系統(tǒng)。這很有可能就是 superblock 損壞造成的問題。

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

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

四、鏡像備份損壞的硬盤


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

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

通過 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

確認(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>

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

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

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

鑒于此,我們打算通過 LogVol7 分區(qū)給出一個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 這個備份是好的。已經(jīng)修復(fù)了一些內(nèi)容了,只要繼續(xù)就很有可能修復(fù)系統(tǒng)。不過,當(dāng)我讓朋友點(diǎn)擊 y 確認(rèn)的時候,悲劇又發(fā)生了。他在復(fù)制粘貼返回信息的時候,習(xí)慣了 Windows 的 Ctrl-C 和 Ctrl-V,呃,我們要知道,Ctrl-C 在 命令行下有另外的含義,就是終止程序運(yùn)行。結(jié)果,他按 Ctrl-C 了……

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

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

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

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

重新開始修復(fù)硬盤:

[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)過了一段時間的等待,LogVol3 修復(fù)終于完成了。由于得知當(dāng)時LogVolHome進(jìn)行了大量的讀寫,因此,雖然可以掛載,但是非常懷疑其中也有故障,因此也許進(jì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í)有錯誤,并且修復(fù)了。

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

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

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

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


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


七、重新啟動


分區(qū)修好了,fsck檢查各個分區(qū)也都沒問題了,該備份的都備份了。可以嘗試重新啟動系統(tǒng)了,祈禱吧……

很不幸,沒起來。:(

啟動的過程,系統(tǒng)報錯:

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)過Google,發(fā)現(xiàn)這是 e2fsprogs,也就是 fsck.ext3 所在包,早期版本的一個bug。如果inode節(jié)點(diǎn)很大,會觸發(fā)這個bug。1.40以后就沒有這個問題了,

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

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

由于這個目錄包含有太多的文件,計算了一下清理這個目錄會花1-2個小時。已經(jīng)是凌晨了,寫了個腳本,開始執(zhí)行,清理完文件后,會自動重啟。基本上該做的都做了,應(yīng)該沒有什么問題了。腳本執(zhí)行后,就讓朋友回家好了。

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

八、后記


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

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

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

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

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

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

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

參考


[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