libpq: Handle OOM by disconnecting instead of hanging or skipping msgs

In most cases, if an out-of-memory situation happens, we attach the
error message to the connection and report it at the next
PQgetResult() call. However, there are a few cases, while processing
messages that are not associated with any particular query, where we
handled failed allocations differently and not very nicely:

- If we ran out of memory while processing an async notification,
  getNotify() either returned EOF, which stopped processing any
  further data until more data was received from the server, or
  silently dropped the notification. Returning EOF is problematic
  because if more data never arrives, e.g. because the connection was
  used just to wait for the notification, or because the next
  ReadyForQuery was already received and buffered, it would get stuck
  forever. Silently dropping a notification is not nice either.

- (New in v18) If we ran out of memory while receiving BackendKeyData
  message, getBackendKeyData() returned EOF, which has the same issues
  as in getNotify().

- If we ran out of memory while saving a received a ParameterStatus
  message, we just skipped it. A later call to PQparameterStatus()
  would return NULL, even though the server did send the status.

Change all those cases to terminate the connnection instead. Our
options for reporting those errors are limited, but it seems better to
terminate than try to soldier on. Applications should handle
connection loss gracefully, whereas silently missing a notification,
parameter status, or cancellation key could cause much weirder
problems.

This also changes the error message on OOM while expanding the input
buffer. It used to report "cannot allocate memory for input buffer",
followed by "lost synchronization with server: got message type ...".
The "lost synchronization" message seems unnecessary, so remove that
and report only "cannot allocate memory for input buffer". (The
comment speculated that the out of memory could indeed be caused by
loss of sync, but that seems highly unlikely.)

This evolved from a more narrow patch by Jelte Fennema-Nio, which was
reviewed by Jacob Champion.

Somewhat arbitrarily, backpatch to v18 but no further. These are
long-standing issues, but we haven't received any complaints from the
field. We can backpatch more later, if needed.

Co-authored-by: Jelte Fennema-Nio <postg...@jeltef.nl>
Reviewed-by: Jelte Fennema-Nio <postg...@jeltef.nl>
Reviewed-by: Jacob Champion <jchamp...@postgresql.org>
Discussion: 
https://www.postgresql.org/message-id/df892f9f-5923-4046-9d6f-8c48d8980...@iki.fi
Backpatch-through: 18

Branch
------
REL_18_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/8aa287c9061b719c53e331ea7af019cb4d4509c5

Modified Files
--------------
src/interfaces/libpq/fe-exec.c      |  13 +++-
src/interfaces/libpq/fe-protocol3.c | 114 ++++++++++++++++++++++++------------
src/interfaces/libpq/libpq-int.h    |   2 +-
3 files changed, 89 insertions(+), 40 deletions(-)

Reply via email to