diff options
author | Magnus Hagander <magnus@hagander.net> | 2008-04-23 13:44:59 +0000 |
---|---|---|
committer | Magnus Hagander <magnus@hagander.net> | 2008-04-23 13:44:59 +0000 |
commit | c979a1fefafcc83553bf218c7f2270cad77ea31d (patch) | |
tree | 7bbf70239a28d7bd5bf239fd93ebc1f37a85c39e /src | |
parent | cf23b75b4dce75151df7164ed72263e66b758ae9 (diff) | |
download | postgresql-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.c | 52 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 37 | ||||
-rw-r--r-- | src/bin/pg_ctl/pg_ctl.c | 18 | ||||
-rw-r--r-- | src/include/miscadmin.h | 6 |
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 */ |