aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorMagnus Hagander <magnus@hagander.net>2011-01-14 12:36:45 +0100
committerMagnus Hagander <magnus@hagander.net>2011-01-14 12:36:45 +0100
commit688423d004f4092aed73c73a3281c281d476436d (patch)
treef57cc33f0accf32a7c75e1d725f48e5e40e11bfb /src/backend
parent52948169bcddf443b76d6ff1806259b153a2ac04 (diff)
downloadpostgresql-688423d004f4092aed73c73a3281c281d476436d.tar.gz
postgresql-688423d004f4092aed73c73a3281c281d476436d.zip
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.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/replication/basebackup.c14
-rw-r--r--src/backend/replication/walsender.c16
2 files changed, 21 insertions, 9 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 144b17c66b6..7929f855f6d 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -308,6 +308,15 @@ sendDir(char *path, int basepathlen, bool sizeonly)
strlen(PG_TEMP_FILE_PREFIX)) == 0)
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);
/* Skip postmaster.pid in the data directory */
@@ -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)
{
/* 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;
if (len >= statbuf->st_size)
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index cacd577acce..2347567ccd6 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -88,8 +88,8 @@ static XLogRecPtr sentPtr = {0, 0};
/* Flags set by signal handlers for later service in main loop */
static volatile sig_atomic_t got_SIGHUP = false;
-static volatile sig_atomic_t shutdown_requested = false;
-static volatile sig_atomic_t ready_to_stop = false;
+volatile sig_atomic_t walsender_shutdown_requested = false;
+volatile sig_atomic_t walsender_ready_to_stop = false;
/* Signal handlers */
static void WalSndSigHupHandler(SIGNAL_ARGS);
@@ -426,16 +426,16 @@ WalSndLoop(void)
* When SIGUSR2 arrives, we send all outstanding logs up to the
* shutdown checkpoint record (i.e., the latest record) and exit.
*/
- if (ready_to_stop)
+ if (walsender_ready_to_stop)
{
if (!XLogSend(output_message, &caughtup))
break;
if (caughtup)
- shutdown_requested = true;
+ walsender_shutdown_requested = true;
}
/* Normal exit from the walsender is here */
- if (shutdown_requested)
+ if (walsender_shutdown_requested)
{
/* Inform the standby that XLOG streaming was done */
pq_puttextmessage('C', "COPY 0");
@@ -461,7 +461,7 @@ WalSndLoop(void)
if (!XLogSend(output_message, &caughtup))
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,
@@ -841,7 +841,7 @@ WalSndSigHupHandler(SIGNAL_ARGS)
static void
WalSndShutdownHandler(SIGNAL_ARGS)
{
- shutdown_requested = true;
+ walsender_shutdown_requested = true;
if (MyWalSnd)
SetLatch(&MyWalSnd->latch);
}
@@ -889,7 +889,7 @@ WalSndXLogSendHandler(SIGNAL_ARGS)
static void
WalSndLastCycleHandler(SIGNAL_ARGS)
{
- ready_to_stop = true;
+ walsender_ready_to_stop = true;
if (MyWalSnd)
SetLatch(&MyWalSnd->latch);
}