Re: BUG #5837: PQstatus() fails to report lost connection

From: "Murray S(dot) Kucherawy" <msk(at)cloudmark(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: "pgsql-bugs(at)postgresql(dot)org" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: BUG #5837: PQstatus() fails to report lost connection
Date: 2011-01-24 03:59:04
Message-ID: F5833273385BB34F99288B3648C4F06F1341E73FC4@EXCH-C2.corp.cloudmark.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

> -----Original Message-----
> From: Tom Lane [mailto:tgl(at)sss(dot)pgh(dot)pa(dot)us]
> Sent: Saturday, January 22, 2011 7:44 PM
> To: Robert Haas
> Cc: Murray S. Kucherawy; pgsql-bugs(at)postgresql(dot)org
> Subject: Re: [BUGS] BUG #5837: PQstatus() fails to report lost connection
>
> Robert Haas <robertmhaas(at)gmail(dot)com> writes:
> > On Thu, Jan 13, 2011 at 8:36 PM, Murray S. Kucherawy <msk(at)cloudmark(dot)com> wrote:
> >> 1) establish a connection to postgresql
> >> 2) initiate a query, collect results, etc.; all normal
> >> 3) while client is idle, restart the server
> >> 4) initiate the very same query as before
> >> 5) call PQgetResult(), returns non-NULL
> >> 6) call PQresultStatus(), returns PGRES_FATAL_ERROR
> >> 7) call PQstatus(), returns CONNECTION_OK
>
> I think the OP's mistake is to assume that the first PQgetResult ought
> to set this. As you say, it hasn't discovered the EOF condition at the
> time it returns that error-message result, and we are certainly not
> going to add another kernel call to every query cycle to check for EOF.
>
> The reason I don't see a problem when using PQexec is that PQexec will
> internally do another PQgetResult, and it's the second one that will
> fail and reset the connection status. In a non-connection-termination
> situation, the second internal PQgetResult call consumes the
> ReadyForQuery message, and at that point we fall out of PQexec (without
> any extra kernel call). Here, though, there won't be a ReadyForQuery,
> and it's the read() to try to collect one that discovers the loss of
> connection.
>
> In short: I don't think there's a bug here, just failure to understand
> proper use of PQgetResult.

For the sake of context, I'm using opendbx which is a layer between my application and any SQL backend it can support. The code that hits this problem is in there. See http://www.linuxnetworks.de/doc/index.php/OpenDBX. I'll forward this thread to that code's maintainer.

As for the reply above, I disagree. PQstatus(), as documented, doesn't say anything about certain conditions in which it won't report that the connection is dead, when it actually is, once the connection was already established and working.

I would also suggest that everything you're describing is internal details of libpq implementation and not stuff that should be visible to consumers of libpq. The level of knowledge described strikes me as the kind of thing your average libpq consumer shouldn't need to have; it's exactly why you want to have a library providing this sort of service in the first place.

Moreover, the description of PQgetResult() doesn't say or illustrate anything about proper use of it in this context, so how would a reader know he/she got it wrong? The documentation I can find online of PQgetResult() doesn't enumerate the conditions where PQstatus() gives a false indication of whether or not a reconnect is required, nor does any part of the documentation I could find state that PGRES_FATAL_ERROR always implies the connection is no longer usable and must be re-established; "FATAL" could be referring to the transaction/request, not the connection.

So, if this isn't a bug, then I think the documentation needs a bit of work in this area.

-MSK

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Xiaobo Gu 2011-01-24 04:11:18 Re: Is there a way to build PostgreSQL client libraries with MinGW
Previous Message Andrew Dunstan 2011-01-24 03:45:27 Re: Is there a way to build PostgreSQL client libraries with MinGW