[bug fix] psql \copy doesn't end if backend is killed

From: "MauMau" <maumau307(at)gmail(dot)com>
To: <pgsql-hackers(at)postgresql(dot)org>
Subject: [bug fix] psql \copy doesn't end if backend is killed
Date: 2013-12-20 14:13:03
Message-ID: 0FC2D1C4CBA64A649C8C31E9419313E4@maumau
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello,

I've encountered a bug on PG 9.2 and fixed it for 9.4. Please find attached
the patch. I'd like it to be backported to at least 9.2.

[Problem]
If the backend is terminated with SIGKILL while psql is running "\copy
table_name from file_name", the \copy didn't end forever. I expected \copy
to be cancelled because the corresponding server process vanished.

[Cause]
psql could not get out of the loop below in handleCopyIn():

while (res = PQgetResult(conn), PQresultStatus(res) == PGRES_COPY_IN)
{
OK = false;
PQclear(res);

PQputCopyEnd(pset.db, _("trying to exit copy mode"));
}

This situation is reached as follows:

1. handleCopyIn() calls PQputCopyData().
2. PQputCopyData() calls pqPutMsgEnd().
3. pqPutMsgEnd() calls pqFlush(), which calls pqSendSome().
4. pqSendSome() calls pqReadData().
5. At this moment, the backend is killed with SIGKILL.
6. pqReadData() fails to read the socket, receiving ECONNRESET. It closes
the socket.
7. As a result, PQputCopyData() fails in 2.
8. handleCopyIn() then calls PQputCopyEnd().
9. PQputCopyEnd() calls pqPutMsgENd(), which calls pqFlush(), which in turn
calls pqSendSome().
10. pqSendSome() fails because the socket is not open.
11. As a result, PQputCopyENd() returns an error, leaving conn->asyncStatus
PGASYNC_COPY_IN.
12. Because conn->asyncStatus remains PGASYNC_COPY_IN, PQgetResult()
continues to return pgresult whose status is PGRES_COPY_IN.

[Fix]
If the message transmission fails in PQputCopyEnd(), switch
conn->asyncStatus back to PGASYNC_BUSY. That causes PQgetResult() to try to
read data with pqReadData(). pqReadData() fails and PQgetResult() returns
NULL. As a consequence, the loop in question terminates.

Regards
MauMau

Attachment Content-Type Size
failed_copy_loops.patch application/octet-stream 2.5 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alvaro Herrera 2013-12-20 14:39:33 Re: pgsql: Upgrade to Autoconf 2.69
Previous Message Alvaro Herrera 2013-12-20 14:06:16 Re: Logging WAL when updating hintbit