2013-11-28 36 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,而不是在连接对象上。