From: | Andres Freund <andres(at)2ndquadrant(dot)com> |
---|---|
To: | Daniele Varrazzo <daniele(dot)varrazzo(at)gmail(dot)com> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: libpq connection status and closed fd |
Date: | 2014-09-22 08:57:10 |
Message-ID: | 20140922085710.GA10971@awork2.anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On 2014-09-22 07:42:01 +0100, Daniele Varrazzo wrote:
> Hello,
>
> a psycopg user is reporting [1] that the library is not marking the
> connection as closed and/or bad after certain errors, such as a
> connection timeout. He is emulating the error by closing the
> connection fd (I don't know if the two conditions result in the same
> effect, but I'll stick to this hypothesis for now).
>
> [1] https://github.com/psycopg/psycopg2/issues/263
>
> Testing with a short C program [2] it seems that indeed, after closing
> the fd and causing an error in `PQconsumeInput`, the connection is
> deemed in good state by `PQstatus`. A similar test gives the same
> result after `PQexec` is attempted on a connection whose fd is closed
> (tests performed with PostgreSQL 9.3.5).
>
> [2] https://gist.github.com/dvarrazzo/065f343c95f8ea67cf8f
>
> Is this intentional? Is there a better way to check for a broken connection?
Note that the libpq code treats connection resets differently from
other, arbitrary, errors:
int
pqReadData(PGconn *conn)
{
...
nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
conn->inBufSize - conn->inEnd);
if (nread < 0)
{
if (SOCK_ERRNO == EINTR)
goto retry3;
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
if (SOCK_ERRNO == EAGAIN)
return someread;
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
if (SOCK_ERRNO == EWOULDBLOCK)
return someread;
#endif
/* We might get ECONNRESET here if using TCP and backend died */
#ifdef ECONNRESET
if (SOCK_ERRNO == ECONNRESET)
goto definitelyFailed;
#endif
/* pqsecure_read set the error message for us */
return -1;
}
I.e. if the kernel returns that the connection has been closed it'll do
different stuff.
So I'm not convinced that the testcaseq is valid. This isn't the error
you'd get after a timeout or similar. We could add a special case path
for EBADFD, but why?
> If we mark the connection as closed every time `PQconsumeInput`
> returns 0 (or `PQexec` returns null, which are the two code paths
> affecting psycopg) would it be too aggressive and cause false
> positives?
Likely, yes.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
From | Date | Subject | |
---|---|---|---|
Next Message | Marko Tiikkaja | 2014-09-22 09:13:36 | Re: libpq connection status and closed fd |
Previous Message | Dmitriy Igrishin | 2014-09-22 08:45:51 | Re: libpq connection status and closed fd |