]> granicus.if.org Git - postgresql/commitdiff
Prevent shutdown in normal mode if online backup is running, and
authorMagnus Hagander <magnus@hagander.net>
Wed, 23 Apr 2008 13:44:59 +0000 (13:44 +0000)
committerMagnus Hagander <magnus@hagander.net>
Wed, 23 Apr 2008 13:44:59 +0000 (13:44 +0000)
have pg_ctl warn about this.

Cancel running online backups (by renaming the backup_label file,
thus rendering the backup useless) when shutting down in fast mode.

Laurenz Albe

doc/src/sgml/ref/pg_ctl-ref.sgml
doc/src/sgml/runtime.sgml
src/backend/access/transam/xlog.c
src/backend/postmaster/postmaster.c
src/bin/pg_ctl/pg_ctl.c
src/include/miscadmin.h

index f4200718c7a412d68d0c2da1ac9b4f006ea71146..2d0b8a33ee29872d0cc41b32f3489b4af45631cb 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.44 2007/11/10 21:48:51 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.45 2008/04/23 13:44:58 mha Exp $
 PostgreSQL documentation
 -->
 
@@ -133,9 +133,10 @@ PostgreSQL documentation
    In <option>stop</option> mode, the server that is running in
    the specified data directory is shut down.  Three different
    shutdown methods can be selected with the <option>-m</option>
-   option: <quote>Smart</quote> mode waits for all the clients to
-   disconnect.  This is the default.  <quote>Fast</quote> mode does
-   not wait for clients to disconnect.  All active transactions are
+   option: <quote>Smart</quote> mode waits for online backup mode
+   to finish and all the clients to disconnect.  This is the default.
+   <quote>Fast</quote> mode does not wait for clients to disconnect and
+   will terminate an online backup in progress.  All active transactions are
    rolled back and clients are forcibly disconnected, then the
    server is shut down.  <quote>Immediate</quote> mode will abort
    all server processes without a clean shutdown.  This will lead to 
index 63259faff5a3793d58f65292c9d29c0049451e7e..5c36f9fce003a67ff7d9b19399806e936519839b 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.414 2008/04/17 20:56:41 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.415 2008/04/23 13:44:58 mha Exp $ -->
 
 <chapter Id="runtime">
  <title>Operating System Environment</title>
@@ -1307,6 +1307,7 @@ sysctl -w vm.overcommit_memory=2
      <listitem>
       <para>
        After receiving <systemitem>SIGTERM</systemitem>, the server
+       waits until online backup mode is no longer active. It then
        disallows new connections, but lets existing sessions end their
        work normally. It shuts down only after all of the sessions
        terminate normally. This is the <firstterm>Smart
@@ -1322,7 +1323,9 @@ sysctl -w vm.overcommit_memory=2
        The server disallows new connections and sends all existing
        server processes <systemitem>SIGTERM</systemitem>, which will cause them
        to abort their current transactions and exit promptly. It then
-       waits for the server processes to exit and finally shuts down. This is the
+       waits for the server processes to exit and finally shuts down.
+       If the server is in online backup mode, backup mode will be
+       terminated, rendering the backup useless.  This is the
        <firstterm>Fast Shutdown</firstterm>.
       </para>
      </listitem>
index 33c912ebaa45a745e9701d626b8fc3ce0987493f..d23fc9b5614c696fe19e7a36aa58db8f175b0db5 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.298 2008/04/21 00:26:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.299 2008/04/23 13:44:58 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -6577,6 +6577,7 @@ pg_start_backup_callback(int code, Datum arg)
  * create a backup history file in pg_xlog (whence it will immediately be
  * archived).  The backup history file contains the same info found in
  * the label file, plus the backup-end time and WAL location.
+ * Note: different from CancelBackup which just cancels online backup mode.
  */
 Datum
 pg_stop_backup(PG_FUNCTION_ARGS)
@@ -7063,3 +7064,52 @@ rm_redo_error_callback(void *arg)
 
        pfree(buf.data);
 }
+
+/*
+ * BackupInProgress: check if online backup mode is active
+ *
+ * This is done by checking for existence of the "backup_label" file.
+ */
+bool
+BackupInProgress(void)
+{
+       struct stat stat_buf;
+
+       return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
+}
+
+/*
+ * CancelBackup: rename the "backup_label" file to cancel backup mode
+ *
+ * If the "backup_label" file exists, it will be renamed to "backup_label.old".
+ * Note that this will render an online backup in progress useless.
+ * To correctly finish an online backup, pg_stop_backup must be called.
+ */
+void
+CancelBackup(void)
+{
+       struct stat stat_buf;
+
+       /* if the file is not there, return */
+       if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
+               return;
+
+       /* remove leftover file from previously cancelled backup if it exists */
+       unlink(BACKUP_LABEL_OLD);
+
+       if (rename(BACKUP_LABEL_FILE, BACKUP_LABEL_OLD) == 0)
+       {
+               ereport(LOG,
+                               (errmsg("online backup mode cancelled"),
+                                errdetail("\"%s\" renamed to \"%s\"",
+                                               BACKUP_LABEL_FILE, BACKUP_LABEL_OLD)));
+       }
+       else
+       {
+               ereport(WARNING,
+                               (errcode_for_file_access(),
+                                errmsg("could not rename \"%s\" to \"%s\", backup mode not cancelled: %m",
+                                               BACKUP_LABEL_FILE, BACKUP_LABEL_OLD)));
+       }
+}
+
index 7c6692b2a5dfd5a7ed5e587f2d497148a7dfe6b2..f3bcdd968c73cd6b0d9aec4f2b25747a690f8349 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.554 2008/03/31 02:43:14 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.555 2008/04/23 13:44:59 mha Exp $
  *
  * NOTES
  *
@@ -253,6 +253,7 @@ typedef enum
        PM_INIT,                                        /* postmaster starting */
        PM_STARTUP,                                     /* waiting for startup subprocess */
        PM_RUN,                                         /* normal "database is alive" state */
+       PM_WAIT_BACKUP,                         /* waiting for online backup mode to end */
        PM_WAIT_BACKENDS,                       /* waiting for live backends to exit */
        PM_SHUTDOWN,                            /* waiting for bgwriter to do shutdown ckpt */
        PM_SHUTDOWN_2,                          /* waiting for archiver to finish */
@@ -1724,8 +1725,12 @@ processCancelRequest(Port *port, void *pkt)
 static enum CAC_state
 canAcceptConnections(void)
 {
-       /* Can't start backends when in startup/shutdown/recovery state. */
-       if (pmState != PM_RUN)
+       /*
+        * Can't start backends when in startup/shutdown/recovery state.
+        * In state PM_WAIT_BACKUP we must allow connections so that
+        * a superuser can end online backup mode.
+        */
+       if ((pmState != PM_RUN) && (pmState != PM_WAIT_BACKUP))
        {
                if (Shutdown > NoShutdown)
                        return CAC_SHUTDOWN;    /* shutdown is pending */
@@ -1965,11 +1970,12 @@ pmdie(SIGNAL_ARGS)
                                /* and the walwriter too */
                                if (WalWriterPID != 0)
                                        signal_child(WalWriterPID, SIGTERM);
-                               pmState = PM_WAIT_BACKENDS;
+                               pmState = PM_WAIT_BACKUP;
                        }
 
                        /*
-                        * Now wait for backends to exit.  If there are none,
+                        * Now wait for online backup mode to end and
+                        * backends to exit.  If that is already the case,
                         * PostmasterStateMachine will take the next step.
                         */
                        PostmasterStateMachine();
@@ -2011,6 +2017,13 @@ pmdie(SIGNAL_ARGS)
                         * PostmasterStateMachine will take the next step.
                         */
                        PostmasterStateMachine();
+
+                       /*
+                        * Terminate backup mode to avoid recovery after a
+                        * clean fast shutdown.
+                        */
+                       CancelBackup();
+
                        break;
 
                case SIGQUIT:
@@ -2552,6 +2565,20 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
 static void
 PostmasterStateMachine(void)
 {
+       if (pmState == PM_WAIT_BACKUP)
+       {
+               /*
+                * PM_WAIT_BACKUP state ends when online backup mode is no longer
+                * active.  In this state canAcceptConnections() will still allow
+                * client connections, which is necessary because a superuser
+                * has to call pg_stop_backup() to end online backup mode.
+                */
+               if (!BackupInProgress())
+               {
+                       pmState = PM_WAIT_BACKENDS;
+               }
+       }
+
        /*
         * If we are in a state-machine state that implies waiting for backends to
         * exit, see if they're all gone, and change state if so.
index 89fc34d68608b3b27c7823a3a63054c3f04f7fc9..55319c6262b68528ae9334cd8666829a778e2783 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.96 2008/02/29 23:31:20 adunstan Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.97 2008/04/23 13:44:59 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -144,6 +144,7 @@ static char def_postopts_file[MAXPGPATH];
 static char postopts_file[MAXPGPATH];
 static char pid_file[MAXPGPATH];
 static char conf_file[MAXPGPATH];
+static char backup_file[MAXPGPATH];
 
 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
 static void unlimit_core_size(void);
@@ -731,6 +732,7 @@ do_stop(void)
 {
        int                     cnt;
        pgpid_t         pid;
+       struct stat     statbuf;
 
        pid = get_pgpid();
 
@@ -763,6 +765,12 @@ do_stop(void)
        }
        else
        {
+               if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
+               {
+                       print_msg(_("WARNING: online backup mode is active; must be ended\n"
+                                               "   with pg_stop_backup() for shutdown to complete\n\n"));
+               }
+
                print_msg(_("waiting for server to shut down..."));
 
                for (cnt = 0; cnt < wait_seconds; cnt++)
@@ -799,6 +807,7 @@ do_restart(void)
 {
        int                     cnt;
        pgpid_t         pid;
+       struct stat     statbuf;
 
        pid = get_pgpid();
 
@@ -833,6 +842,12 @@ do_restart(void)
                        exit(1);
                }
 
+               if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
+               {
+                       print_msg(_("WARNING: online backup mode is active; must be ended\n"
+                                               "   with pg_stop_backup() for shutdown to complete\n\n"));
+               }
+
                print_msg(_("waiting for server to shut down..."));
 
                /* always wait for restart */
@@ -1883,6 +1898,7 @@ main(int argc, char **argv)
                snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
                snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
                snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
+               snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
        }
 
        switch (ctl_command)
index d06b34be437401705a9b3a69008ecae6a50bc140..3d1511e58a525a585fc567f7544c766c1a89308a 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.201 2008/02/20 22:46:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.202 2008/04/23 13:44:59 mha Exp $
  *
  * NOTES
  *       some of the information in this file should be moved to other files.
@@ -330,4 +330,8 @@ extern void ValidatePgVersion(const char *path);
 extern void process_shared_preload_libraries(void);
 extern void process_local_preload_libraries(void);
 
+/* in access/transam/xlog.c */
+extern bool BackupInProgress(void);
+extern void CancelBackup(void);
+
 #endif   /* MISCADMIN_H */