What have you found for these years?

2008-11-08

之前 redmine 停擺的狀況

呃,過程我只簡單說一下好了。總之就是我搞不清楚發生了什麼事,
redmine 的 thin server 就是停擺了。查看 log, 裡面無止盡
說什麼無法寫入無法連接之類的訊息。log 變得非常肥大,記得有上 1GB.

接著我發現有很多事情都沒辦法做,例如用 vim 改寫文字,存檔時就會問:
device space full? 之類的。結果我只好砍掉一些 server 上的檔案。
然後查詢一下到底我的 storage quota 是多少?發現是 10GB 耶,我上傳的檔案
頂多只有 2GB 吧,絕對不可能塞滿磁碟才對。接著我發現 /tmp 無法寫入,
對他下 ls /tmp 發現根本沒反應。du /tmp 同樣沒有任何反應。cd /tmp
同樣不會動............

這時大概就可以確定是 /tmp 根本就被塞爆了。沒辦法用 shell wildcard,
要用 find /tmp | xargs rm 也不行,因為檔案太多了....
最後我決定狠下心來,乾脆下 rm -rf /tmp

就這樣讓他跑「好幾個小時」後,總算把整個 /tmp 砍掉了 @_@

然後 postgres 重啟,thin 重啟之後,看起來就正常了。

期間因為沒辦法連上 postgres, 又讓 /tmp 塞滿了好幾萬個檔案....
都是 ruby_sess 開頭的檔案。不過好幾萬個還不足以癱瘓,跑 ls 或是
cd 或是 find /tmp -name "ruby_sess*" | xargs rm 都還動得了。

所以我估計,原本的那個狀態,應該是 /tmp 塞滿了「幾億個」ruby session,
然後吃掉約 8GB 左右的空間吧。我不知道造成這樣的原因是什麼。
不過就在老林說他又掛掉,我再去查看後,我想我大概知道兇手是誰了。

我個人認為這是 Rails 的錯。然後 Redmine 算是有一點點錯吧...
因為他的 stable release 不支援 Rails 2, 所以我只好去跑 trunk 上的。
而既然用他 trunk 上的程式,當然沒事就要更新一下了。這樣導致 environment.rb
也在他的 version control 之下。svn rebase 又不支援 dirty 狀態下 rebase.
所以我就在一個沒注意之下,跑了 PStore session!(我原本都是用 db session)

PStore session 是啥鬼?就是把 filesystem 當 session 用。rails 的 session,
沒有自動清除的功能,的樣子。結果時間久了,當然就把 filesystem 塞壞了啊...

當然,我猜會在這麼短的時間內,造成幾億個 session, 很可能是有誰在瘋狂讀取
server, 例如 google bot, 或是百度之類的。如果他們又沒有丟 cookie 回來,
那每個 request 都是獨立 session, 當然可能幾秒鐘就產生幾萬個 session...

filesystem 又沒辦法在一個目錄下跑上億個檔案,而且磁碟被吃滿了,
新的 session 無法建立,log 無法寫入,根本完全卡死........

昏倒。

總之改回 db session, 跑:
> find /tmp -type f -name "ruby_sess*" -exec rm -f "{}" ";"
看看又要跑幾個小時才能砍乾淨吧...

nginx error log 也爆了,2GB 的 log...

我開始發覺,其實程式沒寫好,系統沒細心照顧,要被操壞其實是很容易的事。
像之前 nginx error log 暴走,也只是因為沒有寫入 /tmp 的 permission,
這樣隨便上傳一個檔案,error log 就會長大好幾 MB...

用 mongrel 當 upstream 還會更慘。我猜 thin 死掉就死掉了,
mongrel 會一直 retry? 導致 log 噴更大更多 @_@b

以後真的要非常小心 log 和 session 的問題...

另外我把 redmine 上的 svn repository 都砍了,
有空再去弄 git, 寫個 cron 定期 pull.

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0