如何優雅的搞垮伺服器,再優雅的救活

入門到入墳發表於2020-10-15

故事事故是這樣的

新開發的jar包部署在老伺服器上,版本是Red Hat Enterprise Linux AS release 4 (Nahant Update 5),提示需要高版本jdk,高版本jdk提示glibc版本太低得升級,是的,就像套娃。
使用編譯原始碼的方式將glibc由2.3升級到2.9,升級完ls命令不好使了。 用LD_PRELOAD方法解決了ls命令不好使的問題後還挺有成就感的呢!
輕度強迫症的我當然要重啟,然後

#reboot

就沒有然後了。。
作業系統起不來了。各種嘗試,最好的結果是卡死在

Starting cups-config-daemon:
Starting HAL daemon:

再也不往下走了。007的伺服器被996的程式設計師幹進了ICU。
看到了吧,搞垮伺服器可以顯得很無辜。刪庫顯得太刻意了,會被人指責性格有問題。

搶救思路

像《信條》一樣進行一次逆過程,把glibc相關的靜態庫、動態庫都用原來的低版本覆蓋回來。cp覆蓋和安裝rpm覆蓋一起上。

必要條件

  • 能進機房,直接操作伺服器,因為ssh此時已經連不上了。
  • 有相同版本的Linux系統光碟,Linux搶救模式需要光碟引導。
  • 有相同版本的Linux系統的iso映象檔案,用來獲取rpm 【或者替代方法】
  • 有相同版本的Linux系統的伺服器或者虛擬機器,用來下載.a檔案 【或者替代方法】

準備工作

rpm安裝包

將iso檔案解壓,在

RHEL4.6-i386-AS-DVD\RedHat\RPMS

目錄下就包括所有需要的rpm包。
需要準備的安裝包是下面這些:

.a靜態庫檔案

到好用的版本一致的伺服器對應目錄下載下面的庫檔案
目錄/lib

目錄/usr/lib

將這些安裝包和靜態庫放入一個U盤中,U盤插到伺服器上。

搶救過程

進入光碟系統

將光碟放入光碟機。
開機快速按F2,進入

通過+-號調整開機啟動順序,將CD-ROM調整到最上面

按回車,系統重新啟動,進入光碟引導介面

按F5,進入

輸入 linux rescue

按回車,稍等一會,進入

按回車,進入

按回車,進入

按回車,進入

將游標移動到No,按回車,進入

按回車,進入

提示原有系統已經掛載到/mnt/sysimage,按回車進入,目前所處的就是光碟搶救模式(rescue mode),環境是光碟系統,原系統所有檔案都在光碟系統的子目錄/mnt/sysimage裡。

可以看到原有系統的所有目錄結構在/mnt/sysimage下都是可以看見的。

掛載U盤

首先將U盤掛載到光碟系統,

mount -t vfat /dev/sdb1 /mnt/usb/

不同環境中U盤的識別符號不一定是sdb1,在物理機上可能是sda1, 可以通過
fdisk –l 命令看各個目錄容量大小來判定哪個是U盤。

如果掛載U盤提示格式錯誤,U盤可能是fat16格式,執行
mount -t msdos /dev/sdb1 /mnt/usb/ 試試

此時,U盤裡的檔案都在/mnt/usb/目錄下, 原系統所有檔案都在/mnt/sysimage下。將usb目錄下的檔案拷貝到/mnt/sysimage下面你能記住的任意目錄,本文拷貝到/mnt/sysimage/home下。

cp /mnt/usb/* /mnt/sysimage/home

切換到原系統

執行

#chroot  /mnt/sysimage

這個指令使你由當前光碟系統切換到原系統(就是我們要搶救的那個系統),執行pwd和ls可以看到,你所處的目錄就是原系統的根目錄,賬號是原系統的root賬號。

一句話,原系統直接進進不去,但是從光碟系統跳,是能跳進去的。

安裝rpm

進入/home,

rpm -ivh --force rpm包名

一個一個安裝U盤的rpm包。裝失敗的就等把成功的都裝完了回頭重試,和答卷子題不會一個玩法,都是依賴關係導致失敗的。

rpm最好自己重新命名,改成簡短的名字(glibccomm.rpm這種),一定要去掉“-”。我當時看見顯示器上顯示的名字包括亂碼和問號,靠猜來判斷是哪個包,後悔之前沒重新命名。

替換靜態庫檔案

然後手動cp指令替換/lib 和 /usr/lib的靜態庫(*.a檔案)。

cp /home/libpthread.a  /lib
cp /home/*.a  /usr/lib

修改動態庫軟連線

手動修改動態庫的軟連線

無論安裝rpm包時是否自動修改過軟連線,都最好手動修改一遍。
到/lib目錄裡,先

rm  *2.9*  #刪除高版本的庫

然後

ln -sf libutil-2.3.4.solibutil.so.1  
ln -sf libresolv-2.3.4.solibresolv.so.2  
ln -sf libnss_nis-2.3.4.solibnss_nis.so.2  
ln -sf libnss_nisplus-2.3.4.solibnss_nisplus.so.2  
ln -sf libnss_hesiod-2.3.4.solibnss_hesiod.so.2  
ln -sf libnss_files-2.3.4.so  libnss_files.so.2  
ln -sf libnss_dns-2.3.4.so  libnss_dns.so.2  
ln -sf libnss_compat-2.3.4.solibnss_compat.so.2  
ln -sf libnsl-2.3.4.solibnsl.so.1  
ln -sf libdl-2.3.4.solibdl.so.2  
ln -sf libcrypt-2.3.4.solibcrypt.so.1  
ln -sf libBrokenLocale-2.3.4.solibBrokenLocale.so.1  
ln -sf libanl-2.3.4.solibanl.so.1  
ln -sf libc-2.3.4.solibc.so.6  
ln -sf librt-2.3.4.solibrt.so.1  
ln -sf libpthread-0.10.so libpthread.so.0  
ln -sf libm-2.3.4.solibm.so.6  

跳回光碟系統

執行exit跳回到光碟系統,

在上圖游標處再一次輸入exit,按回車 ,系統會重新啟動。
立刻修改BIOS,設定系統從硬碟啟動,原系統可以正常啟動了。

完結撒花

搶救成功還挺有成就感的呢!其它操作搞垮伺服器,也可以試試,只要那個操作能逆向來一遍,問題都不大。
為什麼不重灌?上面部署的東西是多年前放的,物是人非,沒辦法重頭再來。
為什麼敢升級?親眼看見過別人把RHEL6.6的glibc升級了沒出事。真不知道會出這麼嚴重的問題。
如果沒有版本一致的光碟,接近的也可以。我實際用的光碟是RHEL4.6,和原系統差了一個小號。
rpm和.a檔案能拿到就行,不用非按本文方法。
網友提供的替換so的方案不靠譜,必須rpm安裝。
2.3升級到2.9不可以,不代表升級到2.4也不可以,版本離的近可能成功。
這個伺服器至今還在跑著,那些jar包部署到別的伺服器上了。

相關文章