1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +03:00

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
This commit is contained in:
Magnus Hagander
2008-04-23 13:44:59 +00:00
parent cf23b75b4d
commit c979a1fefa
6 changed files with 115 additions and 14 deletions

View 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)));
}
}

View 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.

View 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)

View 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 */