Commit 688423d0 authored by Magnus Hagander's avatar Magnus Hagander

Exit from base backups when shutdown is requested

When the exit waits until the whole backup completes, it may take
a very long time.

In passing, add back an error check in the main loop so we detect
clients that disconnect much earlier if the backup is large.
parent 52948169
...@@ -308,6 +308,15 @@ sendDir(char *path, int basepathlen, bool sizeonly) ...@@ -308,6 +308,15 @@ sendDir(char *path, int basepathlen, bool sizeonly)
strlen(PG_TEMP_FILE_PREFIX)) == 0) strlen(PG_TEMP_FILE_PREFIX)) == 0)
continue; continue;
/*
* Check if the postmaster has signaled us to exit, and abort
* with an error in that case. The error handler further up
* will call do_pg_abort_backup() for us.
*/
if (walsender_shutdown_requested || walsender_ready_to_stop)
ereport(ERROR,
(errmsg("shutdown requested, aborting active base backup")));
snprintf(pathbuf, MAXPGPATH, "%s/%s", path, de->d_name); snprintf(pathbuf, MAXPGPATH, "%s/%s", path, de->d_name);
/* Skip postmaster.pid in the data directory */ /* Skip postmaster.pid in the data directory */
...@@ -462,7 +471,10 @@ sendFile(char *filename, int basepathlen, struct stat * statbuf) ...@@ -462,7 +471,10 @@ sendFile(char *filename, int basepathlen, struct stat * statbuf)
while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0) while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0)
{ {
/* Send the chunk as a CopyData message */ /* Send the chunk as a CopyData message */
pq_putmessage('d', buf, cnt); if (pq_putmessage('d', buf, cnt))
ereport(ERROR,
(errmsg("base backup could not send data, aborting backup")));
len += cnt; len += cnt;
if (len >= statbuf->st_size) if (len >= statbuf->st_size)
......
...@@ -88,8 +88,8 @@ static XLogRecPtr sentPtr = {0, 0}; ...@@ -88,8 +88,8 @@ static XLogRecPtr sentPtr = {0, 0};
/* Flags set by signal handlers for later service in main loop */ /* Flags set by signal handlers for later service in main loop */
static volatile sig_atomic_t got_SIGHUP = false; static volatile sig_atomic_t got_SIGHUP = false;
static volatile sig_atomic_t shutdown_requested = false; volatile sig_atomic_t walsender_shutdown_requested = false;
static volatile sig_atomic_t ready_to_stop = false; volatile sig_atomic_t walsender_ready_to_stop = false;
/* Signal handlers */ /* Signal handlers */
static void WalSndSigHupHandler(SIGNAL_ARGS); static void WalSndSigHupHandler(SIGNAL_ARGS);
...@@ -426,16 +426,16 @@ WalSndLoop(void) ...@@ -426,16 +426,16 @@ WalSndLoop(void)
* When SIGUSR2 arrives, we send all outstanding logs up to the * When SIGUSR2 arrives, we send all outstanding logs up to the
* shutdown checkpoint record (i.e., the latest record) and exit. * shutdown checkpoint record (i.e., the latest record) and exit.
*/ */
if (ready_to_stop) if (walsender_ready_to_stop)
{ {
if (!XLogSend(output_message, &caughtup)) if (!XLogSend(output_message, &caughtup))
break; break;
if (caughtup) if (caughtup)
shutdown_requested = true; walsender_shutdown_requested = true;
} }
/* Normal exit from the walsender is here */ /* Normal exit from the walsender is here */
if (shutdown_requested) if (walsender_shutdown_requested)
{ {
/* Inform the standby that XLOG streaming was done */ /* Inform the standby that XLOG streaming was done */
pq_puttextmessage('C', "COPY 0"); pq_puttextmessage('C', "COPY 0");
...@@ -461,7 +461,7 @@ WalSndLoop(void) ...@@ -461,7 +461,7 @@ WalSndLoop(void)
if (!XLogSend(output_message, &caughtup)) if (!XLogSend(output_message, &caughtup))
break; break;
if (caughtup && !got_SIGHUP && !ready_to_stop && !shutdown_requested) if (caughtup && !got_SIGHUP && !walsender_ready_to_stop && !walsender_shutdown_requested)
{ {
/* /*
* XXX: We don't really need the periodic wakeups anymore, * XXX: We don't really need the periodic wakeups anymore,
...@@ -841,7 +841,7 @@ WalSndSigHupHandler(SIGNAL_ARGS) ...@@ -841,7 +841,7 @@ WalSndSigHupHandler(SIGNAL_ARGS)
static void static void
WalSndShutdownHandler(SIGNAL_ARGS) WalSndShutdownHandler(SIGNAL_ARGS)
{ {
shutdown_requested = true; walsender_shutdown_requested = true;
if (MyWalSnd) if (MyWalSnd)
SetLatch(&MyWalSnd->latch); SetLatch(&MyWalSnd->latch);
} }
...@@ -889,7 +889,7 @@ WalSndXLogSendHandler(SIGNAL_ARGS) ...@@ -889,7 +889,7 @@ WalSndXLogSendHandler(SIGNAL_ARGS)
static void static void
WalSndLastCycleHandler(SIGNAL_ARGS) WalSndLastCycleHandler(SIGNAL_ARGS)
{ {
ready_to_stop = true; walsender_ready_to_stop = true;
if (MyWalSnd) if (MyWalSnd)
SetLatch(&MyWalSnd->latch); SetLatch(&MyWalSnd->latch);
} }
......
...@@ -53,6 +53,8 @@ extern WalSndCtlData *WalSndCtl; ...@@ -53,6 +53,8 @@ extern WalSndCtlData *WalSndCtl;
/* global state */ /* global state */
extern bool am_walsender; extern bool am_walsender;
extern volatile sig_atomic_t walsender_shutdown_requested;
extern volatile sig_atomic_t walsender_ready_to_stop;
/* user-settable parameters */ /* user-settable parameters */
extern int WalSndDelay; extern int WalSndDelay;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment