From 22195f136440fdadae0c6a0bf04c23fa16b4031c Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Wed, 26 Apr 2023 15:25:03 +0000 Subject: [PATCH v4] Fix pg_recvlogical error message upon SIGINT/SIGTERM When pg_recvlogical gets SIGINT/SIGTERM, it emits "unexpected termination of replication stream" error, which is meant for really unexpected termination or a crash, but not for SIGINT/SIGTERM. Upon SIGINT/SIGTERM, we want pg_recvlogical to fsync the output file before exiting cleanly. This commit changes pg_recvlogical to that. Reported-by: Andres Freund Author: Bharath Rupireddy Reviewed-by: Kyotaro Horiguchi, Andres Freund Reviewed-by: Cary Huang Discussion: https://www.postgresql.org/message-id/20221019213953.htdtzikf4f45ywil%40awork3.anarazel.de --- src/bin/pg_basebackup/pg_recvlogical.c | 29 ++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c index f3c7937a1d..337076647b 100644 --- a/src/bin/pg_basebackup/pg_recvlogical.c +++ b/src/bin/pg_basebackup/pg_recvlogical.c @@ -54,7 +54,8 @@ static const char *plugin = "test_decoding"; /* Global State */ static int outfd = -1; -static volatile sig_atomic_t time_to_abort = false; +static bool time_to_abort = false; +static volatile sig_atomic_t ready_to_exit = false; static volatile sig_atomic_t output_reopen = false; static bool output_isfile; static TimestampTz output_last_fsync = -1; @@ -283,6 +284,23 @@ StreamLogicalLog(void) copybuf = NULL; } + /* When we get SIGINT/SIGTERM, we exit */ + if (ready_to_exit) + { + /* + * Try informing the server about our exit, but don't wait around + * or retry on failure. + */ + PQputCopyEnd(conn, NULL); + PQflush(conn); + time_to_abort = true; + + if (verbose) + pg_log_info("received interrupt signal, exiting"); + + break; + } + /* * Potentially send a status message to the primary. */ @@ -614,7 +632,10 @@ StreamLogicalLog(void) res = PQgetResult(conn); } - if (PQresultStatus(res) != PGRES_COMMAND_OK) + + /* It is not unexepected termination error when Ctrl-C'ed. */ + if (!ready_to_exit && + PQresultStatus(res) != PGRES_COMMAND_OK) { pg_log_error("unexpected termination of replication stream: %s", PQresultErrorMessage(res)); @@ -656,7 +677,7 @@ error: static void sigexit_handler(SIGNAL_ARGS) { - time_to_abort = true; + ready_to_exit = true; } /* @@ -976,7 +997,7 @@ main(int argc, char **argv) while (true) { StreamLogicalLog(); - if (time_to_abort) + if (ready_to_exit || time_to_abort) { /* * We've been Ctrl-C'ed or reached an exit limit condition. That's -- 2.34.1