On Wed, 2011-09-07 at 14:46 +0800, Craig Ringer wrote:
> > Right now, PostgreSQL doesn't seem to make an effort to detect a client
> > cancellation. For instance, if you do a "select pg_sleep(1000)" and then
> > kill -9 the client, the SELECT will remain running.
> 
> pg_sleep isn't a good test. In fact, Pg _does_ make an effort to detect 
> when a client dies, and will try to terminate the query. It does this 
> via explicit checks at various points, none of which are reached while 
> Pg is idling in a sleep() syscall. During more typical query processing 
> you'll usually find that a query gets terminated when the client dies.

pg_sleep is not merely a wrapper around the sleep system call, it does
call CHECK_FOR_INTERRUPTS() periodically. Also, you can see that
pg_sleep can be easily canceled if the signal arrives while the query is
actually running (try in psql, or try removing the SIGSTOP/SIGCONT
signals from the C code I attached to the first message).

Try with a large cartesian product and you should get the same problem.

> Pg must find out when the client dies, though. If the client just goes 
> away - such as with a laptop on wifi that wanders out of range - it 
> won't know about it until it next attempts to send data to the client.

How does it know, even on a good network connection, when the client
disconnects? I attached a reproducible case, so you should see what I'm
talking about.

> To address this, if you want reliable client dropout detection, you need 
> to enable tcp keepalives and set them to quite aggressive so the OS will 
> periodically test the connection for aliveness.

I'd be happy if it just detected a disconnect that the OS already knows
about, e.g. explicitly closing the socket.

> I'd love to see Pg accept OOB cancel requests done via lightweight 
> connections that don't go through the whole setup process.

It does that for cancel (see PQcancel), but there is no equivalent for
termination.

>  If the server 
> sent a statement "cookie" when executing a statement, the client could 
> hang onto that and use it to issue a cancel for that statement and only 
> that statement by establishing a new connection to the server and 
> sending that cookie rather than the usual negotiation and auth process. 
> There'd be no need to go through full auth or even bother with SSL, 
> because it's a one-time random (or hash-based) code. Pooling systems 
> could send this to _all_ servers, or it could be prefixed with a server 
> identifier that helped poolers route it to the right server.

That's not too far from what's already done -- again, see the source for
PQcancel() and processCancelRequest().

Regards,
        Jeff Davis


-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

Reply via email to