C# 在Windows重新启动后,Postgresql在特定查询中失败一次

C# 在Windows重新启动后,Postgresql在特定查询中失败一次,c#,postgresql,npgsql,C#,Postgresql,Npgsql,我正在Windows上的C应用程序中使用Postgresql。我遇到的问题非常奇怪,可以描述如下: 我重新启动我的Windows 我运行这个程序 一个特定的查询失败:从total_bytes不为NULL的文件中选择COUNT*AS c 我再次运行程序,一切正常 奇怪的音符: 在此之前,我尝试使用同一个表进行另一个查询,结果成功了:从文件中选择COUNT*AS c 我无法重现重新启动Postgresql时出现的错误。它只在Windows重新启动时发生。它只发生一次。 异常回溯: Npgsql.Np

我正在Windows上的C应用程序中使用Postgresql。我遇到的问题非常奇怪,可以描述如下:

我重新启动我的Windows 我运行这个程序 一个特定的查询失败:从total_bytes不为NULL的文件中选择COUNT*AS c 我再次运行程序,一切正常 奇怪的音符:

在此之前,我尝试使用同一个表进行另一个查询,结果成功了:从文件中选择COUNT*AS c 我无法重现重新启动Postgresql时出现的错误。它只在Windows重新启动时发生。它只发生一次。 异常回溯:

Npgsql.NpgsqlException: Exception while reading from stream

   at Npgsql.ReadBuffer.Ensure(Int32 count, Boolean dontBreakOnTimeouts)
   at Npgsql.NpgsqlConnector.DoReadMessage(DataRowLoadingMode dataRowLoadingMode, Boolean isPrependedMessage)
   at Npgsql.NpgsqlConnector.ReadMessageWithPrepended(DataRowLoadingMode dataRowLoadingMode)
   at Npgsql.NpgsqlConnector.ReadMessage(DataRowLoadingMode dataRowLoadingMode)
   at Npgsql.NpgsqlConnector.ReadExpecting[T]()
   at Npgsql.NpgsqlDataReader.NextResultInternal()
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.Execute(CommandBehavior behavior)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReaderInternal(CommandBehavior behavior)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Npgsql.NpgsqlCommand.ExecuteReader()
   at DriveShare.Database.Postgresql.ExecuteQuery(NpgsqlCommand command) in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\Postgresql.cs:line 216
   at DriveShare.Database.Postgresql.Query(String sql, Object[] args) in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\Postgresql.cs:line 72
   at DriveShare.Database.Postgresql.QueryOne(String sql, Object[] args) in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\Postgresql.cs:line 83
   at DriveShare.Database.Postgresql.QueryValue(String key, String sql, Object[] args) in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\Postgresql.cs:line 97
   at DriveShare.Database.Postgresql.QueryValue(String key, String sql) in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\Postgresql.cs:line 92
   at DriveShare.Database.FileIndexDataSet.CountIndexedFiles() in c:\projetos\driveshareclient\DriveShare\DriveShare\Database\FileIndexDataSet.cs:line 89
   at DriveShare.Engine.DriveShareEngine.Start() in c:\projetos\driveshareclient\DriveShare\DriveShare\Engine\DriveShareEngine.cs:line 156
   at DriveShareWebService.Program.Main(String[] args) in c:\projetos\driveshareclient\DriveShare\DriveShareWebService\Program.cs:line 19
因为我必须让程序继续工作,所以我编写了一个变通方法,让应用程序在继续之前重试该查询。我并不为此感到骄傲:

public void WaitForConnection()
{
    int limitSeconds = 3 * 60;
    var start = DateTime.Now;
    while (true)
    {
        try
        {
            Log.WaitingForDatabaseConnection();
            Query("SELECT COUNT(*) AS c FROM files WHERE total_bytes IS NOT NULL");
            Log.DatabaseConnectionAquired();
            break;
        }
        catch (Exception e)
        {
            var wastedTime = DateTime.Now - start;
            if (wastedTime.TotalSeconds > limitSeconds)
                throw;
            else
                Log.Exception(e);
        }
        Thread.Sleep(1000);
    }
}
我在一个精简的抽象类中使用Npgsql连接到Postgresql。Postgresql日志显示了一些关于winsock错误的条目,我还不了解这些条目:

2016-08-16 10:14:34 BRT LOG:  database system was shut down at 2016-08-16 10:12:07 BRT
2016-08-16 10:14:34 BRT FATAL:  the database system is starting up
2016-08-16 10:14:34 BRT LOG:  MultiXact member wraparound protections are now enabled
2016-08-16 10:14:34 BRT LOG:  sistema de banco de dados está pronto para aceitar conexões
2016-08-16 10:14:34 BRT LOG:  autovacuum launcher started
2016-08-16 10:17:16 BRT LOG:  could not receive data from client: unrecognized winsock error 10053
2016-08-16 10:17:27 BRT LOG:  could not send data to client: unrecognized winsock error 10054
2016-08-16 10:17:27 BRT STATEMENT:  SELECT path FROM files
2016-08-16 10:17:27 BRT FATAL:  connection to client lost
2016-08-16 10:17:27 BRT STATEMENT:  SELECT path FROM files
2016-08-16 10:17:27 BRT LOG:  could not receive data from client: unrecognized winsock error 10053
2016-08-16 10:17:27 BRT LOG:  unexpected EOF on client connection with an open transaction
2016-08-16 10:17:33 BRT LOG:  unexpected EOF on client connection with an open transaction
2016-08-16 10:25:14 BRT LOG:  could not receive data from client: unrecognized winsock error 10053
2016-08-16 10:25:15 BRT LOG:  could not receive data from client: unrecognized winsock error 10053
2016-08-16 10:25:15 BRT LOG:  unexpected EOF on client connection with an open transaction
2016-08-16 10:26:30 BRT LOG:  could not send data to client: unrecognized winsock error 10054
2016-08-16 10:26:30 BRT FATAL:  connection to client lost
2016-08-16 10:26:50 BRT LOG:  could not send data to client: unrecognized winsock error 10054
2016-08-16 10:26:50 BRT FATAL:  connection to client lost
2016-08-16 10:26:50 BRT LOG:  could not receive data from client: unrecognized winsock error 10053
2016-08-16 10:26:50 BRT LOG:  unexpected EOF on client connection with an open transaction
2016-08-16 10:27:06 BRT LOG:  could not send data to client: unrecognized winsock error 10054
2016-08-16 10:27:06 BRT FATAL:  connection to client lost
2016-08-16 10:27:06 BRT LOG:  could not send data to client: unrecognized winsock error 10054
2016-08-16 10:27:06 BRT FATAL:  connection to client lost
2016-08-16 10:27:30 BRT LOG:  pedido de desligamento rápido foi recebido
2016-08-16 10:27:30 BRT LOG:  interrompendo quaisquer transações ativas
2016-08-16 10:27:30 BRT LOG:  autovacuum launcher shutting down
2016-08-16 10:27:30 BRT ERROR:  canceling statement due to user request
2016-08-16 10:27:30 BRT LOG:  autovacuum launcher shutting down
2016-08-16 10:27:30 BRT LOG:  shutting down
2016-08-16 10:27:30 BRT LOG:  database system is shut down

我不希望有人知道我到底有什么问题。我只是希望有人可能有一些类似的问题,可以从中有所启发。

在一些帮助下,我在Npgsql文档中找到了解决方案

默认情况下,Npgsql带有一些用于连接和命令的超时参数。Windows重新启动后,第一次访问表的速度非常慢,导致命令超时

通过连接字符串上的其他参数,我可以将这些设置更改得更高,并解决我的问题:

connectionString += ";Timeout=180;Command Timeout=180";
额外提示:Postgresql函数pg_sleepseconds帮助我在不重新启动的情况下重现问题。非常有帮助:

SELECT pg_sleep(60);

如果使用不同的客户机(如PgAdmin)查询数据库,是否会出现相同的奇怪行为?还是这种奇怪的行为只发生在你的应用程序中?@sstan刚刚测试过。该查询在PgAdmin上运行,但在第一次运行时耗时超过34秒。秒686ms。我猜这可能与Windows启动混乱和Npgsql中的某种超时有关。此查询可能会慢到足以触发它。听起来像是其他人建议的第一次超时,但如果您可以简单地发布完整的异常详细信息,我们可以更确定-您的NpgsqlException似乎缺少一个内部异常。