aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMagnus Hagander <magnus@hagander.net>2008-04-23 13:44:59 +0000
committerMagnus Hagander <magnus@hagander.net>2008-04-23 13:44:59 +0000
commitc979a1fefafcc83553bf218c7f2270cad77ea31d (patch)
tree7bbf70239a28d7bd5bf239fd93ebc1f37a85c39e /src
parentcf23b75b4dce75151df7164ed72263e66b758ae9 (diff)
downloadpostgresql-c979a1fefafcc83553bf218c7f2270cad77ea31d.tar.gz
postgresql-c979a1fefafcc83553bf218c7f2270cad77ea31d.zip
Prevent shutdown in normal mode if online backup is running, and
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c52
-rw-r--r--src/backend/postmaster/postmaster.c37
-rw-r--r--src/bin/pg_ctl/pg_ctl.c18
-rw-r--r--src/include/miscadmin.h6
4 files changed, 105 insertions, 8 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.
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 89fc34d6860..55319c6262b 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -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)
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index d06b34be437..3d1511e58a5 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -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 */