解析:出現這個問題的緣由有不少種,多是文件系統數據塊出現不一致致使的,也多是磁盤故障形成的,主流ext3/ext4文件系統都有很強的自我修復機制,對於簡單的錯誤,文件系統通常均可以自行修復,當遇到致命錯誤沒法修復的時候,文件系統爲了保證數據一致性和安全,會暫時屏蔽文件系統的寫操做,講文件系統變爲只讀,今兒出現了上面的「read-only file system」現象。java
手工修復文件系統錯誤的命令式fsck,在修復文件系統前,最好卸載文件系統所在的磁盤分區node
1
2
3
4
5
6
7
8
9
10
11
12
|
# umount /www/data
Umount :
/www/data
: device is busy
提示沒法卸載,多是這個磁盤中還有文件對應的進程在運行,檢查以下:
# fuser -m /dev/sdb1
/dev/sdb1
: 8800
接着檢查一下8800端口對應的什麼進程,
# ps –ef |grep 8800
檢查後發現時apache沒有關閉,中止apache
#/usr/local/apache2/bin/apachectl stop
# umount /www/data
# fsck –V –a /dev/sdb1
# mount /dev/sdb1/www/data
|
# crontab –emysql
編輯完後保存退出後,報錯nospace left on devicelinux
根據上面的報錯了解到是磁盤空間滿了,那麼首先是檢查磁盤空間,nginx
# df –hweb
查看到是/var磁盤分區空間已經達到100%,至此定位了問題所在。是/var磁盤空間飽滿致使,由於crontab會在保存時將文件信息寫到/var目錄下面,然而這個磁盤沒有空間了,因此報錯。sql
接着經過命令du –sh * 命令檢查/var目錄下面的全部文件或者目錄的大小,發現/var/spool/clientmqueue目錄佔用了/var整個分區大小的90%,那麼/var/spool/clientmqueue目錄下的文件都是怎麼產生的,可否刪除,基本上都是郵件信息,能夠刪除shell
# rm *數據庫
/bin/rm :argumentlist too longapache
當在linux 系統中試圖傳遞太多參數給一個命令時,就會出現「argument list too long 」錯誤,這是linux系統一直以來都有的限制,查看這個限制能夠經過命令「getconf ARG_MAX」來實現,
# getconf ARG_MAX
# more/etc/issue 查看版本
解決方法:一、
# rm [a-n]* -rf
# rm [o-z]* -rf
二、使用find命令來刪除
# find/var/spool/clientmqueue –type f –print –exec rm –f {} \;
三、經過shell腳本
#/bin/bash
RM_DIR=’/var/spool/clientmqueue’
cd $RM_DIR
for I in `ls`
do
rm –f $i
done
四、從新編譯內核
須要手動增長內核中分配給命令行參數的頁數,打開kernel source 下面的include/linux/binfmts.h文件,找到以下行:
#denfineMAX_ARG_PAGES 32
將32改成更大的值,例如64或者128,而後從新編譯內核
客戶的一臺Oracle數據庫如武器在關機重啓後,Oracle監聽沒法啓動,提示報錯 Linux error : No spaceleft on device
從輸出信息看出來是由於磁盤耗盡致使監聽沒法啓動,由於Oracle在啓動監聽時須要建立監聽日誌文件,因而首先查看磁盤空間使用狀況
# df –h
從磁盤輸出信息可知,全部的分區磁盤空間都還有剩餘很多,而Oracle監聽寫日誌的路徑在/var分區下,/var下分區空間足夠。
解決思路:
既然錯誤提示語磁盤空間有關,那就深刻研究關於磁盤空間的問題,在linux系統中對磁盤空間的佔用分爲三個部分:第一個是物理磁盤空間,第二個是inode節點所佔用的磁盤空間,第三個是linux用來存放信號量的空間,而平時接觸較多的是物理磁盤空間。既然不是物理磁盤空間的問題,接着就檢查是不是inode節點耗盡的問題,經過執行命令「df -i」查看可用的inode節點。由輸出結果看出確實是由於inode耗盡致使沒法寫入文件。
能夠經過下面的命令查看某個磁盤分區inode的總數
# dumpe2fs –h/dev/sda3 |grep ‘Inode count’
每一個inode都有一個號碼,操做系統用inode號碼來區分不一樣的文件,經過‘ls -i’命令能夠查看文件名對應的inode號
若是要查看這個文件更詳細的inode信息,能夠經過stat命令來實現
# stat install.log
解決問題
# find/var/spool/clientmqueue/ -name 「*」 –exec rm –rf {} \;
運維監控系統發來通知,報告一臺服務器空間滿了,登錄服務器查看,根分區確實滿了,這裏先說一下服務器的一些刪除策略,因爲linux沒有回收站功能,因此線上服務器上全部要刪除的文件都會先移到系統/tmp目錄下,而後按期清除/tmp目錄下的數據。這個策略自己沒有什麼問題,可是經過檢查發現這臺服務器的系統分區中並無單獨劃分/tmp分區,這樣/tmp下的數據其實佔用根分區的空間,既然找到了問題,那麼刪除/tmp目錄下一些佔用空間較大的數據文件便可。
# du –sh /tmp/* |sort –nr |head -3
經過命令發如今/tmp目錄下有個66G大小的文件access_log,這個文件應該是apache產生的訪問日誌文件,從日誌大小來看,應該是好久沒有清理的apache日誌文件了,基本斷定是這個文件致使的根空間爆滿,在確認此文件能夠刪除後,執行以下刪除命令,
# rm/tmp/access_Iog
# df –h
從輸出來看,根分區空間仍然沒有釋放,這是怎麼回事
通常來講不會出現刪除文件後空間不釋放的狀況,可是也存在例外,好比文件進程鎖定,或者有進程一直在向這個文件寫數據,要理解這個問題,就須要知道linux下文件的存儲機制和存儲結構。
一個文件在文件系統中存放分爲兩個部分:數據部分和指針部分,指針位於文件系統的meta-data中,在將數據刪除後,這個指針就從meta-data中清除了,而數據部分存儲在磁盤中。在將數據對應的指針從meta-data中清除後,文件數據部分佔用的空間就能夠被覆蓋並寫入新的內容,之因此出現刪除access_log文件後,空間尚未釋放,就是由於httpd進程還在一直向這個文件寫入內容,致使雖然刪除了access_Ilog文件,可是因爲進程鎖定,文件對應的指針部分並未從meta-data中清除,而因爲指針並未刪除,系統內核就認爲文件並未被刪除,所以經過df命令查詢空間並未釋放。
問題排查:
既然有了解決思路,那麼接下來看看是否有進程一直在向access_log文件中寫入數據,這裏須要用到linux下的losf命令,經過這個命令能夠獲取一個仍然被應用程序佔用的已刪除文件列表
# lsof |grepdelete
從輸出能夠看出,/tmp/access_log文件被進程httpd鎖定,而httpd進程還一直向這個文件寫入日誌數據,最後一列的‘deleted’狀態說明這個日誌文件已經被刪除,可是因爲進程還在一直向此文件寫入數據,所以空間並未釋放。
解決問題:
到這裏問題就基本排查清楚了,解決這一類問題的方法有不少,最簡單的方法就是關閉或者重啓httpd進程,固然重啓操做系統也能夠。不過這些並非最好的辦法,對待這種進程不停對文件寫日誌的操做,要釋放文件佔用的磁盤空間,最好的方法是在線清空這個文件,具體能夠經過以下命令完成:
# echo 「 」>/tmp/access_log
經過這種方法,磁盤空間不但能夠立刻釋放,也能夠保障進城繼續向文件寫入日誌,這種方法常常用於在線清理apache /tomcat/nginx等web服務產生的日誌文件。
問題五、「too many open files」錯誤與解決方法。
問題現象:這是一個基於java的web應用系統,在後臺添加數據時提示沒法添加,因而登錄服務器查看tomcat日誌,發現以下異常信息,java.io.IOException: Too many open files
經過這個報錯信息,基本判斷是系統能夠用的文件描述符不夠了,因爲tomcat服務室系統www用戶啓動的,因而以www用戶登錄系統,經過ulimit –n 命令查看系統能夠打開最大文件描述符的數量,輸出以下:
$ ulimit –n
65535
能夠看到這臺服務器設置的最大能夠打開的文件描述符已是65535了,這麼大的值應該夠用了,可是爲何提示這樣的錯誤呢
解決思路,這個案例涉及ulimit命令的使用
在使用ulimit時,有如下幾種使用方法:
一、 在用戶環境變量中加入
若是用戶使用的是bash,那麼能夠在用戶目錄的環境變量文件.bashrc或者.bash_profile中加入「ulimit –u128」來限制用戶最多可使用128個進程
二、 在應用程序的啓動腳本中加入
若是應用程序是tomcat,那麼能夠再tomcat的啓動腳本startup.sh中加入‘ulimit –n 65535’來限制用戶最多可使用65535個文件描述符
三、 直接在shell命令終端執行ulimit命令
這種方法的資源限制僅僅在執行命令的終端生效,在退出或者和關閉終端後,設置失效,而且這個設置不影響其餘shell終端
解決問題:
在瞭解ulimit知識後,接着上面的案例,既然ulimit設置沒有問題,那麼必定是設置沒有生效致使的,接下來檢查下啓動tomcat的www用戶環境變量是否添加ulimit限制,檢查後發現,www用戶並沒有ulimit限制。因而繼續檢查tomcat啓動腳本startup.sh文件是否添加了ulimit限制,檢查後發現也沒有添加。最後考略是否將限制加到了limits.conf文件中,因而檢查limits.conf文件,操做以下
# cat/etc/security/limits.conf |grep www
www soft nofile65535
www hard nofile65535
從輸出可知,ulimit限制加在limits.conf文件中,既然限制已經添加了,配置也沒有什麼錯,爲什麼還會報錯,通過思考,判斷只有一種可能,那就是tomcat的啓動時間早於ulimit資源限制的添加時間,因而首先查看下tomcat啓動時間,操做以下
# uptime
Up 283 days
# pgrep –f tomcat
4667
# ps –eopid,lstart,etime|grep 4667
4667 Sat Jul 6 09;33:39 2013 77-05:26:02
從輸出能夠看出,這臺服務器已經有283沒有重啓了,而tomcat是在2013年7月6日9點啓動的,啓動了將近77天,接着繼續看看limits.conf文件的修改時間,
# stat/etc/security/limits.conf
經過stat命令清除的看到,limits.conf文件最後的修改時間是2013年7月12,晚於tomcat啓動時間,清楚問題後,解決問題的方法很簡單,重啓一下tomcat就能夠了。
錯誤現象: 客戶反映在執行」apachectl start 「啓動Apache是無報錯信息,可是仍是不能訪問網頁,客戶的網站是基於Apache+PHP+mysql 的在線交易平臺,聽到客戶描述的現象後,第一反應就是防火牆屏蔽了HTTP端口或selinux的問題,因而登錄服務器查看相關信息,從輸出信息能夠看出,防火牆全部的策略都處於開放狀態,並未作出任何限制,而selinux也處於關閉狀態,應該不是防火牆致使的。既然不是防火牆致使的,那麼看看httpd進程是否存在及httpd端口是否正常啓動
# ps –ef |grep httpd|grep –v 「grep」 |wc –l
0
# netstat –nultp|grep 80
# /usr/local/apache2/bin/apachectlstart
# ps –ef |grpe httpd |grep –v 「grep」 |wc –l
0
這個操做首先查看了服務器上的httpd進程,發現並無HTTP進程運行,同時httpd對應的端口80也並無啓動,因而重啓Apache,在啓動Apache的過程當中並無報錯,啓動完成後發現仍然HTTP進程沒有運行,由此看來,應該是Apache內部出現了問題
解決思路:
在判斷Apache問題後,首先要看的就是Apache的啓動日誌,在查看Apache的error日誌後,發現了一個可疑輸出,內容爲:
No space left ondevice : mod_rewrite: could not create rewrite_log_lock configuration failed
看到這個錯誤提示,感受應該是磁盤空間耗盡致使,因而趕忙查看系統系統全部磁盤分區,結果發現全部磁盤分區都還有不少可用空間,這就奇怪了,在前面的案例介紹中,詳細介紹了linux對磁盤空間的佔用分爲三個部分:物理磁盤、inode節點磁盤空間和信號量磁盤空間。經過檢查服務器的物理磁盤空間,發現仍有不少剩餘,所以排除物理空間的問題,接着經過」df -i」命令查看系統可用的inode節點,發現每一個分區能夠用的inode還有不少,這樣inode節點問題也被排除了,那麼應該是信號量磁盤空間耗盡致使的。
這裏簡單的介紹下linux信號量相關知識。信號量是一種鎖機制,用於協調進程之間互斥的訪問臨界資源,以確保某種共享資源不被多個進程同時訪問。Linux系統的信號量是用於進程間通訊的。它有兩種標準實現,分別是POSIX及System v ,如今大多數linux系統都實現了這兩種標準,這兩種標準均可用於進行線程間的通訊,只是系統調用方式略有不一樣。
System v 信號量經過系統調用semget來建立,經過linux命令ipcs便可顯示進程間通訊用的system v 類型信號量及共享內存。
Posix 信號量可用於線程和進程間通訊,並可分爲有名和無名兩種,也能夠理解爲是否保存在磁盤上。
解決問題:
# cat/proc/sys/kernel/sem
# ipcs –s |grepdaemon
Daemon是啓動Apache進程的用戶,默認是daemon,也多是nobody用戶,根據實際環境而定。解決信號量耗盡的方法很簡單,經過ipcrm命令清除便可,最簡單方法是執行以下命令組合:
# ipcs –s |grepnobody |perl –e ‘while (<STDIN>) { @a=split(/\s+/);print `ipcrmsem $a[1]`}’
這是linux最多見的故障,系統在掉電,以及執行配置更新、軟件升級、內核升級後都有可能致使系統沒法啓動,究其緣由,可能有不少種,常見的以下幾種:
1) 文件系統破壞,通常是linux的根分區文件系統遭到破壞,致使系統沒法啓動,這種狀況通常是有系統忽然掉電或者非法關機引發的。
2) 文件系統配置不當,好比/etc/inittab文件、/etc/fstab文件等配置錯誤或丟失,致使系統錯誤,沒法啓動,這種狀況通常是執行配置更新時人爲致使的
3) Linux內核文件丟失或者崩潰,從而致使系統沒法引導啓動,這種狀況多是內核升級錯誤或者內核存在bug引發的
4) 系統引導程序出現問題,好比grub丟失或者損壞,致使系統沒法引導啓動,這種狀況通常是人爲修改錯誤或者文件系統故障致使的。
5) 系統硬件故障,好比主板、電源、硬盤等出現問題,致使linux系統沒法正常啓動,這種狀況基本都是因爲服務器硬件問題致使的。
Checking rootfilesystem
/dev/sda6 containsa file system with errors, check forced
An error occurredduring the file system check
這個錯誤能夠看出,操做系統/dev/sda6分區文件系統出現了問題,這個問題發生的機率很高,一般引發這個問題的緣由主要是系統忽然斷電,引發文件系統結構不一致,通常狀況下,解決此問題的方法是採用fsck命令,進行強制修復。
# umount /dev/sda6
# fsck.ext3 -y /dev/sda6
當某些服務不能訪問的時候,必定要檢查是否被linux本機防火牆iptables屏蔽了,能夠經過iptables –L –n 命令檢查iptables的配置策略。
# iptables –L –n
# iptables –AINPUT –i eth0 –p tcp --dport 80 –j ACCEPT
# iptables –AOUTPUT –p tcp --sport 80 –m state –state ESTABLISHED –j ACCEPT