2013-11-28 37 views
1

我有一個長時間運行的查詢,大約48分鐘後超時。爲什麼查詢在超時限制內超時?

命令超時設置爲2小時,連接超時設置爲17分鐘。

什麼會導致查詢引發超時? (我假設必須有別的東西,我已經忽略了?)

Npgsql.NpgsqlException: 
    A timeout has occured. If you were establishing a connection, increase Timeout value in ConnectionString. If you were executing a command, increase the CommandTimeout value in ConnectionString or in your NpgsqlCommand object. 
     at Npgsql.NpgsqlState.ProcessBackendResponsesEnum(NpgsqlConnector context) in C:\projects\Npgsql2\src\Npgsql\NpgsqlState.cs:line 384 
     at Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb) in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 611 
     at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior cb) in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 591 
     at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 538 

其他信息:

  • Postgres的版本:8.3
  • Npgsql的:2.0.11.0

postgres日誌顯示以下「錯誤」:

cancelling statement due to user request 

查詢在不同的日期範圍內的不同時間運行了兩次,這兩次運行失敗的時間都是相同的錯誤,運行了相同的時間後 - 「00:48:24.909」 和「00:48:24.936 「

此外,以前的查詢時間不超過00:47:40,所以這表明其他情況會導致48分鐘左右的超時時間。

我在postgres配置文件中看不到任何東西,有沒有其他地方我可以看?

+1

PostgreSQL版本,nPgSQL版本,命令文本和服務器錯誤日誌輸出?在猜測你實際上得到了_network_超時(可能通過NAT連接跟蹤到期問題?)而不是語句超時。無論如何,當您編輯問題以添加該信息時,請在此處評論。 –

+0

Postgres 8.3,NpgSql 2.0.11.0(無法更改版本),無法提供命令文本,也無法訪問數據庫服務器的日誌。服務器和db位於專用交換機上的數據中心中。我雖然超時是由客戶控制,只需計算需要多長時間?我有其他查詢運行時間更長,不超時。 –

+0

在這種情況下 - 是否還有更多的nPgSQL堆棧跟蹤,像Java中的任何「由......引起的」?在你的位置上,我會(a)向DBA詢問日誌,(b)儘可能多地在nPgSQL中啓用跟蹤日誌;和/或(c)使用Wireshark來檢查網絡通信並準確瞭解發生了什麼。 –

回答

2

這是Npgsql中的一個錯誤。我只是驗證它。這是fixed on 03/10/2013,但從那以後一直沒有穩定的版本。就目前來看,你必須從當前的資源中構建來解決這個問題。

它是由Socket.Poll()接受一個I​​nt32微秒參數以及Socket.Poll()本身中出現錯誤的事實的組合引起的。

首先,2小時轉換爲-1,389,934,592微秒(7200秒* 1,000,000),絕對值約爲48分鐘。

二,Socket.Poll() documentation狀態:

設置微秒參數爲負整數,如果你願意無限期地等待響應。

相反,它似乎轉換爲絕對值,大約48分鐘,所以有你奇怪的但可預測的超時。

+0

我正在將它用於生產環境。它通常在壓力下隨機出現這樣的錯誤。或者一些請求永遠丟失。沒有壓力它從來沒有錯誤。奇怪 – GorillaApe

0

我不確定爲什麼這是答案,也許是NpgSQL中的一個錯誤?我也無法解釋什麼使得CommandTimeOut在48分鐘(這必須默認在某處,但不是在我的代碼中,更奇怪的是,它不默認爲在documentation中指定的20秒)。

但是要解決該問題,需要在運行查詢之前在命令對象本身上設置CommandTimeOut,而不是在連接對象上。