Why does a query time-out when it is within it'

2019-02-20 16:47发布

I have a long running query that times out after about 48 minutes.

The command time-out is set to 2 hours and the connection time-out is set to 17 minutes.

What would cause the query to raise a time-out? (I'm assuming there must be something else that I've overlooked?)

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

Additional information:

  • Postgres Version: 8.3
  • NpgSql: 2.0.11.0

The postgres log shows the following "ERROR":

cancelling statement due to user request

The query ran twice last night at different times for different date ranges, both times it failed with the same error, and after running for the same amount of time - "00:48:24.909" and "00:48:24.936"

Also, previous queries have taken no longer than 00:47:40, so this suggests something else is causing the time-out at around 48 minutes.

I can't see anything in the postgres configuration file, is there anywhere else I could look?

2条回答
做个烂人
2楼-- · 2019-02-20 17:14

I'm unsure why this is the answer, perhaps a bug in NpgSQL? I also can't explain what makes the CommandTimeOut at 48 minutes (this must be defaulted somewhere, but not in my code, more strange that is doesn't default to the 20 second as specified in the documentation).

But to solve the problem, you need to set the CommandTimeOut on the command object itself before running the query rather than on the connection object.

查看更多
虎瘦雄心在
3楼-- · 2019-02-20 17:19

It's a bug in Npgsql. I just verified it. It was fixed on 03/10/2013, but there hasn't been a stable release since then. As it currently stands you'll have to build from current sources to get around this.

It is caused by a combination of the fact that Socket.Poll() takes an Int32 microseconds argument, and by what appears to be a bug in Socket.Poll() itself.

First, 2 hours converts to -1,389,934,592 microseconds (7200 seconds * 1,000,000), the absolute value of which is about 48 minutes.

Second, the Socket.Poll() documentation states:

set the microSeconds parameter to a negative integer if you would like to wait indefinitely for a response.

Instead, it appears to convert to the absolute value, about 48 minutes, so there's your odd but predictable timeout.

查看更多
登录 后发表回答