6個(gè)Linux運(yùn)維典型問(wèn)題,大牛的分析解決思路在這里
作為一名合格的 Linux 運(yùn)維工程師,一定要有一套清晰、明確的解決故障思路,當(dāng)問(wèn)題出現(xiàn)時(shí),才能迅速定位、解決問(wèn)題,這里給出一個(gè)處理問(wèn)題的一般思路:
- 重視報(bào)錯(cuò)提示信息:每個(gè)錯(cuò)誤的出現(xiàn),都是給出錯(cuò)誤提示信息,一般情況下這個(gè)提示基本定位了問(wèn)題的所在,因此一定要重視這個(gè)報(bào)錯(cuò)信息,如果對(duì)這些錯(cuò)誤信息視而不見(jiàn),問(wèn)題永遠(yuǎn)得不到解決。
- 查閱日志文件:有時(shí)候報(bào)錯(cuò)信息只是給出了問(wèn)題的表面現(xiàn)象,要想更深入的了解問(wèn)題,必須查看相應(yīng)的日志文件,而日志文件又分為系統(tǒng)日志文件(/var/log)和應(yīng)用的日志文件,結(jié)合這兩個(gè)日志文件,一般就能定位問(wèn)題所在。
- 分析、定位問(wèn)題:這個(gè)過(guò)程是比較復(fù)雜的,根據(jù)報(bào)錯(cuò)信息,結(jié)合日志文件,同時(shí)還要考慮其它相關(guān)情況,最終找到引起問(wèn)題的原因。
- 解決問(wèn)題:找到了問(wèn)題出現(xiàn)的原因,解決問(wèn)題就是很簡(jiǎn)單的事情了。
從這個(gè)流程可以看出,解決問(wèn)題的過(guò)程就是分析、查找問(wèn)題的過(guò)程,一旦確定問(wèn)題產(chǎn)生的原因,故障也就隨之解決了。
結(jié)合上面介紹的 Linux 運(yùn)維問(wèn)題的解決思路后,下面我們挑選了6個(gè)比較典型的 Linux 運(yùn)維問(wèn)題,來(lái)看看是如何分析和解決的:
問(wèn)題 1:文件系統(tǒng)破壞導(dǎo)致系統(tǒng)無(wú)法啟動(dòng)
- Checking root filesystem
- /dev/sda6 contains a file system with errors, check forced
- An error occurred during the file system check
這個(gè)錯(cuò)誤可以看出,操作系統(tǒng) / dev/sda6 分區(qū)文件系統(tǒng)出現(xiàn)了問(wèn)題,這個(gè)問(wèn)題發(fā)生的機(jī)率很高,通常引起這個(gè)問(wèn)題的原因主要是系統(tǒng)突然斷電,引起文件系統(tǒng)結(jié)構(gòu)不一致,一般情況下,解決此問(wèn)題的方法是采用 fsck 命令,進(jìn)行強(qiáng)制修復(fù)。
- # umount /dev/sda6
- # fsck.ext3 -y /dev/sda6
問(wèn)題 2:“Argument list too long” 錯(cuò)誤與解決方法
- # crontab -e
編輯完后保存退出后,報(bào)錯(cuò) no space left on device
根據(jù)上面的報(bào)錯(cuò)了解到是磁盤(pán)空間滿了,那么首先是檢查磁盤(pán)空間,
- # df -h
查看到是 / var 磁盤(pán)分區(qū)空間已經(jīng)達(dá)到 100%,至此定位了問(wèn)題所在。是 / var 磁盤(pán)空間飽滿導(dǎo)致,因?yàn)?crontab 會(huì)在保存時(shí)將文件信息寫(xiě)到 / var 目錄下面,然而這個(gè)磁盤(pán)沒(méi)有空間了,所以報(bào)錯(cuò)。
接著通過(guò)命令 du –sh * 命令檢查 / var 目錄下面的所有文件或者目錄的大小,發(fā)現(xiàn) / var/spool/clientmqueue 目錄占用了 / var 整個(gè)分區(qū)大小的 90%,那么 / var/spool/clientmqueue 目錄下的文件都是怎么產(chǎn)生的,能否刪除,基本上都是郵件信息,可以刪除
- # rm *
- /bin/rm :argument list too long
當(dāng)在 linux 系統(tǒng)中試圖傳遞太多參數(shù)給一個(gè)命令時(shí),就會(huì)出現(xiàn) “argument list too long” 錯(cuò)誤,這是 linux 系統(tǒng)一直以來(lái)都有的限制,查看這個(gè)限制可以通過(guò)命令 “getconf ARG_MAX” 來(lái)實(shí)現(xiàn),
# getconf ARG_MAX
# more /etc/issue 查看版本
解決方法:
1、
- # rm [a-n]* -rf
- # rm [o-z]* -rf
2、使用 find 命令來(lái)刪除
- # find /var/spool/clientmqueue –type f –print –exec rm –f {} ;
3、通過(guò) shell 腳本
- #/bin/bash
- RM_DIR=’/var/spool/clientmqueue’
- cd $RM_DIR
- for I in `ls`
- do
- rm –f $i
- done
4、重新編譯內(nèi)核
需要手動(dòng)增加內(nèi)核中分配給命令行參數(shù)的頁(yè)數(shù),打開(kāi) kernel source 下面的 include/linux/binfmts.h 文件,找到如下行:
- #denfine MAX_ARG_PAGES 32
將 32 改為更大的值,例如 64 或者 128,然后重新編譯內(nèi)核
問(wèn)題 3:inode 耗盡導(dǎo)致應(yīng)用故障
客戶的一臺(tái) Oracle 數(shù)據(jù)庫(kù)如武器在關(guān)機(jī)重啟后,Oracle 監(jiān)聽(tīng)無(wú)法啟動(dòng),提示報(bào)錯(cuò) Linux error : No space left on device
從輸出信息看出來(lái)是因?yàn)榇疟P(pán)耗盡導(dǎo)致監(jiān)聽(tīng)無(wú)法啟動(dòng),因?yàn)?Oracle 在啟動(dòng)監(jiān)聽(tīng)時(shí)需要?jiǎng)?chuàng)建監(jiān)聽(tīng)日志文件,于是首先查看磁盤(pán)空間使用情況
- # df -h
從磁盤(pán)輸出信息可知,所有的分區(qū)磁盤(pán)空間都還有剩余不少,而 Oracle 監(jiān)聽(tīng)寫(xiě)日志的路徑在 / var 分區(qū)下,/var 下分區(qū)空間足夠。
解決思路:
既然錯(cuò)誤提示語(yǔ)磁盤(pán)空間有關(guān),那就深入研究關(guān)于磁盤(pán)空間的問(wèn)題,在 linux 系統(tǒng)中對(duì)磁盤(pán)空間的占用分為三個(gè)部分:第一個(gè)是物理磁盤(pán)空間,第二個(gè)是 inode 節(jié)點(diǎn)所占用的磁盤(pán)空間,第三個(gè)是 linux 用來(lái)存放信號(hào)量的空間,而平時(shí)接觸較多的是物理磁盤(pán)空間。既然不是物理磁盤(pán)空間的問(wèn)題,接著就檢查是否是 inode 節(jié)點(diǎn)耗盡的問(wèn)題,通過(guò)執(zhí)行命令 “df -i” 查看可用的 inode 節(jié)點(diǎn)。由輸出結(jié)果看出確實(shí)是因?yàn)?inode 耗盡導(dǎo)致無(wú)法寫(xiě)入文件。
可以通過(guò)下面的命令查看某個(gè)磁盤(pán)分區(qū) inode 的總數(shù)
- # dumpe2fs -h /dev/sda3 |grep ‘Inode count’
每個(gè) inode 都有一個(gè)號(hào)碼,操作系統(tǒng)用 inode 號(hào)碼來(lái)區(qū)分不同的文件,通過(guò)‘ls -i’命令可以查看文件名對(duì)應(yīng)的 inode 號(hào)
如果要查看這個(gè)文件更詳細(xì)的 inode 信息,可以通過(guò) stat 命令來(lái)實(shí)現(xiàn)
- # stat install.log
解決問(wèn)題
- # find /var/spool/clientmqueue/ -name “*” -exec rm -rf {} ;
問(wèn)題 4:文件已經(jīng)刪除,但是空間沒(méi)有釋放的原因
運(yùn)維監(jiān)控系統(tǒng)發(fā)來(lái)通知,報(bào)告一臺(tái)服務(wù)器空間滿了,登陸服務(wù)器查看,根分區(qū)確實(shí)滿了,這里先說(shuō)一下服務(wù)器的一些刪除策略,由于 linux 沒(méi)有回收站功能,所以線上服務(wù)器上所有要?jiǎng)h除的文件都會(huì)先移到系統(tǒng) / tmp 目錄下,然后定期清除 / tmp 目錄下的數(shù)據(jù)。這個(gè)策略本身沒(méi)有什么問(wèn)題,但是通過(guò)檢查發(fā)現(xiàn)這臺(tái)服務(wù)器的系統(tǒng)分區(qū)中并沒(méi)有單獨(dú)劃分 / tmp 分區(qū),這樣 / tmp 下的數(shù)據(jù)其實(shí)占用根分區(qū)的空間,既然找到了問(wèn)題,那么刪除 / tmp 目錄下一些占用空間較大的數(shù)據(jù)文件即可。
- # du -sh /tmp/* | sort -nr |head -3
通過(guò)命令發(fā)現(xiàn)在 / tmp 目錄下有個(gè) 66G 大小的文件 access_log,這個(gè)文件應(yīng)該是 apache 產(chǎn)生的訪問(wèn)日志文件,從日志大小來(lái)看,應(yīng)該是很久沒(méi)有清理的 apache 日志文件了,基本判定是這個(gè)文件導(dǎo)致的根空間爆滿,在確認(rèn)此文件可以刪除后,執(zhí)行如下刪除命令,
- # rm /tmp/access_Iog
- # df -h
從輸出來(lái)看,根分區(qū)空間仍然沒(méi)有釋放,這是怎么回事
一般來(lái)說(shuō)不會(huì)出現(xiàn)刪除文件后空間不釋放的情況,但是也存在例外,比如文件進(jìn)程鎖定,或者有進(jìn)程一直在向這個(gè)文件寫(xiě)數(shù)據(jù),要理解這個(gè)問(wèn)題,就需要知道 linux 下文件的存儲(chǔ)機(jī)制和存儲(chǔ)結(jié)構(gòu)。
一個(gè)文件在文件系統(tǒng)中存放分為兩個(gè)部分:數(shù)據(jù)部分和指針部分,指針位于文件系統(tǒng)的 meta-data 中,在將數(shù)據(jù)刪除后,這個(gè)指針就從 meta-data 中清除了,而數(shù)據(jù)部分存儲(chǔ)在磁盤(pán)中。在將數(shù)據(jù)對(duì)應(yīng)的指針從 meta-data 中清除后,文件數(shù)據(jù)部分占用的空間就可以被覆蓋并寫(xiě)入新的內(nèi)容,之所以出現(xiàn)刪除 access_log 文件后,空間還沒(méi)有釋放,就是因?yàn)?httpd 進(jìn)程還在一直向這個(gè)文件寫(xiě)入內(nèi)容,導(dǎo)致雖然刪除了 access_Ilog 文件,但是由于進(jìn)程鎖定,文件對(duì)應(yīng)的指針部分并未從 meta-data 中清除,而由于指針并未刪除,系統(tǒng)內(nèi)核就認(rèn)為文件并未被刪除,因此通過(guò) df 命令查詢空間并未釋放。
問(wèn)題排查:
既然有了解決思路,那么接下來(lái)看看是否有進(jìn)程一直在向 access_log 文件中寫(xiě)入數(shù)據(jù),這里需要用到 linux 下的 losf 命令,通過(guò)這個(gè)命令可以獲取一個(gè)仍然被應(yīng)用程序占用的已刪除文件列表
- # lsof | grep delete
從輸出可以看出,/tmp/access_log 文件被進(jìn)程 httpd 鎖定,而 httpd 進(jìn)程還一直向這個(gè)文件寫(xiě)入日志數(shù)據(jù),最后一列的‘deleted’狀態(tài)說(shuō)明這個(gè)日志文件已經(jīng)被刪除,但是由于進(jìn)程還在一直向此文件寫(xiě)入數(shù)據(jù),因此空間并未釋放。
解決問(wèn)題:
到這里問(wèn)題就基本排查清楚了,解決這一類問(wèn)題的方法有很多,最簡(jiǎn)單的方法就是關(guān)閉或者重啟 httpd 進(jìn)程,當(dāng)然重啟操作系統(tǒng)也可以。不過(guò)這些并不是最好的辦法,對(duì)待這種進(jìn)程不停對(duì)文件寫(xiě)日志的操作,要釋放文件占用的磁盤(pán)空間,最好的方法是在線清空這個(gè)文件,具體可以通過(guò)如下命令完成:
- # echo “”>/tmp/access_log
通過(guò)這種方法,磁盤(pán)空間不但可以馬上釋放,也可以保障進(jìn)城繼續(xù)向文件寫(xiě)入日志,這種方法經(jīng)常用于在線清理 apache /tomcat/nginx 等 web 服務(wù)產(chǎn)生的日志文件。
問(wèn)題 5:"too many open files" 錯(cuò)誤與解決方法
問(wèn)題現(xiàn)象:這是一個(gè)基于 java 的 web 應(yīng)用系統(tǒng),在后臺(tái)添加數(shù)據(jù)時(shí)提示無(wú)法添加,于是登陸服務(wù)器查看 tomcat 日志,發(fā)現(xiàn)如下異常信息,java.io.IOException: Too many open files
通過(guò)這個(gè)報(bào)錯(cuò)信息,基本判斷是系統(tǒng)可以用的文件描述符不夠了,由于 tomcat 服務(wù)室系統(tǒng) www 用戶啟動(dòng)的,于是以 www 用戶登陸系統(tǒng),通過(guò) ulimit –n 命令查看系統(tǒng)可以打開(kāi)最大文件描述符的數(shù)量,輸出如下:
- $ ulimit -n
- 65535
可以看到這臺(tái)服務(wù)器設(shè)置的最大可以打開(kāi)的文件描述符已經(jīng)是 65535 了,這么大的值應(yīng)該夠用了,但是為什么提示這樣的錯(cuò)誤呢
解決思路,這個(gè)案例涉及 ulimit 命令的使用
在使用 ulimit 時(shí),有以下幾種使用方法:
1、 在用戶環(huán)境變量中加入
如果用戶使用的是 bash,那么可以在用戶目錄的環(huán)境變量文件. bashrc 或者. bash_profile 中加入 “ulimit –u128” 來(lái)限制用戶最多可以使用 128 個(gè)進(jìn)程
2、 在應(yīng)用程序的啟動(dòng)腳本中加入
如果應(yīng)用程序是 tomcat,那么可以再 tomcat 的啟動(dòng)腳本 startup.sh 中加入‘ulimit -n 65535’來(lái)限制用戶最多可以使用 65535 個(gè)文件描述符
3、 直接在 shell 命令終端執(zhí)行 ulimit 命令
這種方法的資源限制僅僅在執(zhí)行命令的終端生效,在退出或者和關(guān)閉終端后,設(shè)置失效,并且這個(gè)設(shè)置不影響其他 shell 終端
解決問(wèn)題:
在了解 ulimit 知識(shí)后,接著上面的案例,既然 ulimit 設(shè)置沒(méi)有問(wèn)題,那么一定是設(shè)置沒(méi)有生效導(dǎo)致的,接下來(lái)檢查下啟動(dòng) tomcat 的 www 用戶環(huán)境變量是否添加 ulimit 限制,檢查后發(fā)現(xiàn),www 用戶并無(wú) ulimit 限制。于是繼續(xù)檢查 tomcat 啟動(dòng)腳本 startup.sh 文件是否添加了 ulimit 限制,檢查后發(fā)現(xiàn)也沒(méi)有添加。最后考略是否將限制加到了 limits.conf 文件中,于是檢查 limits.conf 文件,操作如下
- # cat /etc/security/limits.conf | grep www
- www soft nofile 65535
- www hard nofile 65535
從輸出可知,ulimit 限制加在 limits.conf 文件中,既然限制已經(jīng)添加了,配置也沒(méi)有什么錯(cuò),為何還會(huì)報(bào)錯(cuò),經(jīng)過(guò)思考,判斷只有一種可能,那就是 tomcat 的啟動(dòng)時(shí)間早于 ulimit 資源限制的添加時(shí)間,于是首先查看下 tomcat 啟動(dòng)時(shí)間,操作如下
- # uptime
- Up 283 days
- # pgrep -f tomcat
- 4667
- # ps -eo pid,lstart,etime|grep 4667
- 4667 Sat Jul 6 09;33:39 2013 77-05:26:02
從輸出可以看出,這臺(tái)服務(wù)器已經(jīng)有 283 沒(méi)有重啟了,而 tomcat 是在 2013 年 7 月 6 日 9 點(diǎn)啟動(dòng)的,啟動(dòng)了將近 77 天,接著繼續(xù)看看 limits.conf 文件的修改時(shí)間,
- # stat /etc/security/limits.conf
通過(guò) stat 命令清除的看到,limits.conf 文件最后的修改時(shí)間是 2013 年 7 月 12,晚于 tomcat 啟動(dòng)時(shí)間,清楚問(wèn)題后,解決問(wèn)題的方法很簡(jiǎn)單,重啟一下 tomcat 就可以了。
問(wèn)題 6:Read-only file system 錯(cuò)誤與解決方法
解析:出現(xiàn)這個(gè)問(wèn)題的原因有很多種,可能是文件系統(tǒng)數(shù)據(jù)塊出現(xiàn)不一致導(dǎo)致的,也可能是磁盤(pán)故障造成的,主流 ext3/ext4 文件系統(tǒng)都有很強(qiáng)的自我修復(fù)機(jī)制,對(duì)于簡(jiǎn)單的錯(cuò)誤,文件系統(tǒng)一般都可以自行修復(fù),當(dāng)遇到致命錯(cuò)誤無(wú)法修復(fù)的時(shí)候,文件系統(tǒng)為了保證數(shù)據(jù)一致性和安全,會(huì)暫時(shí)屏蔽文件系統(tǒng)的寫(xiě)操作,講文件系統(tǒng) 變?yōu)橹蛔x,今兒出現(xiàn)了上面的 “read-only file system” 現(xiàn)象。
手工修復(fù)文件系統(tǒng)錯(cuò)誤的命令式 fsck,在修復(fù)文件系統(tǒng)前,最好卸載文件系統(tǒng)所在的磁盤(pán)分區(qū)
- # umount /www/data
- Umount : /www/data: device is busy
提示無(wú)法卸載,可能是這個(gè)磁盤(pán)中還有文件對(duì)應(yīng)的進(jìn)程在運(yùn)行,檢查如下:
- # fuser -m /dev/sdb1
- /dev/sdb1: 8800
接著檢查一下 8800 端口對(duì)應(yīng)的什么進(jìn)程,
- # ps -ef |grep 8800
檢查后發(fā)現(xiàn)時(shí) apache 沒(méi)有關(guān)閉,停止 apache
- # /usr/local/apache2/bin/apachectl stop
- # umount /www/data
- # fsck -V -a /dev/sdb1
- # mount /dev/sdb1 /www/data