sqlite3搭配Rails 1.2.2會神秘爆炸的問題
最近發現某個在Rails 1.2.2環境下跑的應用程式會經不起疲勞轟炸,用一用就爛掉了。一開始以為是雜種狗(Mongrel)惹的禍,後來又開始懷疑是不是 Ruby 的 Io class 會 leak file handle (如果是,就嚴重了啊…)。
百思不得其解之下,結果反而是在找和 Ruby / Rails 無關的討論中,想起來可以用 “lsof” 這個 UNIX 工具。結果一跑之下,妖魔就現了形:原來是 sqlite3 爆炸了,開了許多 DB file 卻佔著不放。怎麼會這樣呢?再繼續搜尋,原來竟然是 Rails 的 sqlite3 connection 沒有把 DB connection (對sqlite3來說就是file handle) 給釋放!這樣就算是鐵打的作業系統,也會山窮水盡吧…
根據這張TRAC ticket,問題早在2007年一月時就解決了。不過奇怪的是當時雖然標明是Edge,但patch過的程式卻完全沒進到tagged release,當然也就沒進到released package了。
Fix方法,要不就是改用Edge Rails(不過可能有其他風險),否則就是照著剛剛那張ticket的方法,自行修改ActiveRecord中的 connection_adapters/sqlite_adapter.rb ,在第 108 行附近,ActiveRecord#supports_reloading? 後面加上:
def disconnect! @connection.close rescue nil end
藥到病除。
從這個故事我們可以知道:
- lsof 是你的好朋友
- 不要相信released package就一定把狗皮藥膏都貼過一遍
- 不要隨便懷疑雜種狗的忠誠度(雖然偶爾還是要來踢一下就是…)
lukhnos :: Mar.09.2007 :: :: 2 Comments »
這種資料庫用到爆的行為, 有名小站的 mypage 也發生過啊 XD
上次好像有什麼新聞說 RoR 還是 Mongrel 有 connection pool 了,怎麼還…