summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/transam/xlog.c52
-rw-r--r--src/backend/postmaster/postmaster.c37
2 files changed, 83 insertions, 6 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 33c912ebaa4..d23fc9b5614 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -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)));
+ }
+}
+
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 7c6692b2a5d..f3bcdd968c7 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -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.