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:
parent
cf23b75b4d
commit
c979a1fefa
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user