*** a/src/backend/libpq/be-secure.c --- b/src/backend/libpq/be-secure.c *************** *** 36,42 **** #include "tcop/tcopprot.h" #include "utils/memutils.h" #include "storage/proc.h" ! char *ssl_cert_file; char *ssl_key_file; --- 36,42 ---- #include "tcop/tcopprot.h" #include "utils/memutils.h" #include "storage/proc.h" ! #include "storage/ipc.h" char *ssl_cert_file; char *ssl_key_file; *************** *** 144,152 **** retry: Assert(waitfor); w = WaitLatchOrSocket(MyLatch, ! WL_LATCH_SET | waitfor, port->sock, 0); /* Handle interrupt. */ if (w & WL_LATCH_SET) { --- 144,174 ---- Assert(waitfor); w = WaitLatchOrSocket(MyLatch, ! WL_LATCH_SET | WL_POSTMASTER_DEATH | waitfor, port->sock, 0); + /* + * If the postmaster has died, it's not safe to continue running, + * because it is the postmaster's job to kill us if some other backend + * exists uncleanly. Moreover, we won't run very well in this state; + * helper processes like walwriter and the bgwriter will exit, so + * performance may be poor. Finally, if we don't exit, pg_ctl will + * be unable to restart the postmaster without manual intervention, + * so no new connections can be accepted. Exiting clears the deck + * for a postmaster restart. + * + * (Note that we only make this check when we would otherwise sleep + * on our latch. We might still continue running for a while if the + * postmaster is killed in mid-query, or even through multiple queries + * if we never have to wait for read. We don't want to burn too many + * cycles checking for this very rare condition, and this shouuld cause + * us to exit quickly in most cases.) + */ + if (w & WL_POSTMASTER_DEATH) + ereport(FATAL, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection due to unexpected postmaster exit"))); + /* Handle interrupt. */ if (w & WL_LATCH_SET) { *************** *** 223,231 **** retry: Assert(waitfor); w = WaitLatchOrSocket(MyLatch, ! WL_LATCH_SET | waitfor, port->sock, 0); /* Handle interrupt. */ if (w & WL_LATCH_SET) { --- 245,259 ---- Assert(waitfor); w = WaitLatchOrSocket(MyLatch, ! WL_LATCH_SET | WL_POSTMASTER_DEATH | waitfor, port->sock, 0); + /* See comments in secure_read. */ + if (w & WL_POSTMASTER_DEATH) + ereport(FATAL, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection due to unexpected postmaster exit"))); + /* Handle interrupt. */ if (w & WL_LATCH_SET) { *** a/src/interfaces/libpq/fe-exec.c --- b/src/interfaces/libpq/fe-exec.c *************** *** 1567,1573 **** pqHandleSendFailure(PGconn *conn) * our side of the socket --- that's just what we want here. */ while (pqReadData(conn) > 0) ! /* loop until no more data readable */ ; /* * Parse any available input messages. Since we are in PGASYNC_IDLE --- 1567,1583 ---- * our side of the socket --- that's just what we want here. */ while (pqReadData(conn) > 0) ! { ! /* There is a possiblity that this failure handler is called incase ! * server side backend has already closed the connection and hence ! * query can not be processed. But before the connection was closed, ! * some data (mostly error message) have been sent on this connection ! * channel but client did not get opportunity to process same as it was ! * busy waiting for new command from application. ! * So instead of ignoring available data, process them. ! */ ! parseInput(conn); ! } /* * Parse any available input messages. Since we are in PGASYNC_IDLE