Exit from base backups when shutdown is requested
authorMagnus Hagander <magnus@hagander.net>
Fri, 14 Jan 2011 11:36:45 +0000 (12:36 +0100)
committerMagnus Hagander <magnus@hagander.net>
Fri, 14 Jan 2011 11:36:45 +0000 (12:36 +0100)
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.

src/backend/replication/basebackup.c
src/backend/replication/walsender.c
src/include/replication/walsender.h

index 144b17c66b69e7f371310dcb7816283095b3e4ca..7929f855f6d17c65eec9eeb65f0c1f127f141848 100644 (file)
@@ -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)
index cacd577acce1b28a7c4a6f1ed9e2385a576ae3fd..2347567ccd621ad2e8e64d0c0a4ad969caf72918 100644 (file)
@@ -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);
 }
index 0b4a143f827e78a38bc855bbff7c10e41b714735..9039b240c44e450c8d1a7e16e0c0131fc0c2d0b6 100644 (file)
@@ -53,6 +53,8 @@ extern WalSndCtlData *WalSndCtl;
 
 /* global state */
 extern bool am_walsender;
+extern volatile sig_atomic_t walsender_shutdown_requested;
+extern volatile sig_atomic_t walsender_ready_to_stop;
 
 /* user-settable parameters */
 extern int WalSndDelay;