2016-04-17 50 views
1

我們有Postgres作爲我們的後端數據庫。我們的流程運行一些工作(即它在數據庫中進行一些插入/更新),然後睡眠一小時postgres中的空閒連接導致進程卡住或導致錯誤

這是我們已經注意到的。當我們的進程正在休眠時,我們的Postgres連接狀態被視爲空閒。

postgres 5045 0.3 0.4 231220 33780 ?  Ss 12:13 0:16 postgres: scp scp_test x.x.x.x(60400) idle  

現在我的問題是?

如果我有一個進程,睡了一個小時

Postgres在一段時間後關閉閒置連接嗎?

因爲在接下來的運行過程中無法插入/更新DB中的任何記錄。

這裏是我的代碼的樣子。

$logger = Logger.new('log/checker.log') 
    last_modified = Time.now 
    while 
    if (last_modified == File.mtime(file_path)) 
     $logger.info "Sleeping for 1 hour" 
     sleep 3600 
    else 
     $logger.info "Inserting the file mtime changed .." 
     last_modified = File.mtime(file_path) 
     $logger.info "File modified ....." 
     attributes = Test.testFile(file_path) 
     index = 0 
     $logger.info "........Index set......" 
     header_attributes = attributes.shift 
     $logger.info "...........Header removed..........." 
     trailer_attributes = attributes.pop 
     $logger.info "...Trailer removed......." 
     count = attributes.count 
     $logger.info "............Count calculated #{count} ........." 
     attributes.each_slice(50000) { |records| 
     _records = initialize_records(records) 
     _records.each { |record| 
      record.save 
      index += 1 
      $logger.info "Inserting ...... [#{index}/#{count}]" 
     } 
    } 
    $logger.info "Completed insertion of #{count}" 
    end 
end 

Ruby-2.2.2 - ActiveRecord-4.2.6 - pg-0.18.0 
Ruby-2.3.0 - ActiveRecord-4.2.6 - pg-0.18.0 
Jruby-9.0.5.0 - ActiveRecord-4.2.6 - activerecord-jdbc-adapter 

Postgres的版本測試了這個。

PostgreSQL 9.4.5 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit 
(1 row) 

Ruby和JRuby輸出有一個區別?

雖然這兩個進程會被卡住,他們從睡眠

紅寶石進程死掉醒來後PG::UnableToSend: SSL SYSCALL error: EOF detected錯誤

但JRuby的過程中被永遠困(不會死)。

不知道問題出在哪裏,因爲在這一點上我不能指向任何特定的庫或代碼。

注意:在回送接口上工作得很好。有問題的postgres服務器是遠程的..

回答

0

在數據文件夾內有一個名爲postgresql.conf的文件,您必須將其配置爲將keepalive消息發送給客戶端。閱讀this瞭解更多信息。

配置postgresql.conf

postgresql.conf文件應該有這樣tcp_keepalives_idle線。 如果您想每5分鐘發送一次keepalive消息到客戶端計算機;更新tcp_keepalives_idle線這樣

tcp_keepalives_idle = 300

確保通過刪除#標誌取消註釋該行。

+0

如果這是Keepalive的問題,爲什麼我看不到任何超時加上它在環回接口上工作得很好。我很確定loopback連接在* TCP socket *和** not ** * unix socket *上工作,因爲我可以通過* tcpdump *通過TCP嗅探數據包。 – Viren

+0

這是一個很好的答案,當時會建議檢查Java套接字超時。無法解釋爲什麼它使用** lo **,但也許它處理so-timeout的方式不同。已經在JRuby之前看到了過時的DB連接套接字,雖然從未使用localhost,所以如果您可以確認測試並確認發生了什麼(超時),那將會很有趣。 – kares