diff options
author | Simon Riggs <simon@2ndQuadrant.com> | 2013-03-27 11:45:42 +0000 |
---|---|---|
committer | Simon Riggs <simon@2ndQuadrant.com> | 2013-03-27 11:45:42 +0000 |
commit | bc5334d8679c428a709d150666b288171795bd76 (patch) | |
tree | fc964f441b4dd08a483987762771c936bcaf7959 | |
parent | f7f210b5c4c9c76e87fffc5abef7dea752d1ac9a (diff) | |
download | postgresql-bc5334d8679c428a709d150666b288171795bd76.tar.gz postgresql-bc5334d8679c428a709d150666b288171795bd76.zip |
Allow external recovery_config_directory
If required, recovery.conf can now be located outside of the data directory.
Server needs read/write permissions on this directory.
-rw-r--r-- | doc/src/sgml/config.sgml | 17 | ||||
-rw-r--r-- | src/backend/access/transam/xlog.c | 18 | ||||
-rw-r--r-- | src/backend/utils/init/globals.c | 1 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 19 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 24 | ||||
-rw-r--r-- | src/include/miscadmin.h | 2 | ||||
-rw-r--r-- | src/include/utils/guc.h | 1 |
7 files changed, 75 insertions, 7 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index d750f0800b7..6488399708f 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -330,6 +330,23 @@ include 'filename' </listitem> </varlistentry> + <variablelist> + <varlistentry id="guc-recovery-config-directory" xreflabel="recovery_config_directory"> + <term><varname>recovery_config_directory</varname> (<type>string</type>)</term> + <indexterm> + <primary><varname>recovery_config_directory</> configuration parameter</primary> + </indexterm> + <listitem> + <para> + Specifies the directory to use for the recovery.conf file. Note + the server requires read and write permission on this directory + because the file will be renamed to recovery.done at the end of + recovery. + This parameter can only be set at server start. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-config-file" xreflabel="config_file"> <term><varname>config_file</varname> (<type>string</type>)</term> <indexterm> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 07c68adf0bc..2f91bc88eaa 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -62,6 +62,7 @@ extern bool bootstrap_data_checksums; +char recoveryConfPath[MAXPGPATH]; /* File path names (all relative to $PGDATA) */ #define RECOVERY_COMMAND_FILE "recovery.conf" #define RECOVERY_COMMAND_DONE "recovery.done" @@ -4163,7 +4164,8 @@ readRecoveryCommandFile(void) *head = NULL, *tail = NULL; - fd = AllocateFile(RECOVERY_COMMAND_FILE, "r"); + snprintf(recoveryConfPath, MAXPGPATH, "%s/%s", RecoveryConfDir, RECOVERY_COMMAND_FILE); + fd = AllocateFile(recoveryConfPath, "r"); if (fd == NULL) { if (errno == ENOENT) @@ -4171,7 +4173,7 @@ readRecoveryCommandFile(void) ereport(FATAL, (errcode_for_file_access(), errmsg("could not open recovery command file \"%s\": %m", - RECOVERY_COMMAND_FILE))); + recoveryConfPath))); } /* @@ -4345,7 +4347,7 @@ readRecoveryCommandFile(void) if (PrimaryConnInfo == NULL && recoveryRestoreCommand == NULL) ereport(WARNING, (errmsg("recovery command file \"%s\" specified neither primary_conninfo nor restore_command", - RECOVERY_COMMAND_FILE), + recoveryConfPath), errhint("The database server will regularly poll the pg_xlog subdirectory to check for files placed there."))); } else @@ -4353,7 +4355,7 @@ readRecoveryCommandFile(void) if (recoveryRestoreCommand == NULL) ereport(FATAL, (errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled", - RECOVERY_COMMAND_FILE))); + recoveryConfPath))); } /* Enable fetching from archive recovery area */ @@ -4395,6 +4397,7 @@ static void exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo) { char recoveryPath[MAXPGPATH]; + char recoveryDonePath[MAXPGPATH]; char xlogpath[MAXPGPATH]; /* @@ -4459,12 +4462,13 @@ exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo) * Rename the config file out of the way, so that we don't accidentally * re-enter archive recovery mode in a subsequent crash. */ - unlink(RECOVERY_COMMAND_DONE); - if (rename(RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE) != 0) + snprintf(recoveryDonePath, MAXPGPATH, "%s/%s", RecoveryConfDir, RECOVERY_COMMAND_DONE); + unlink(recoveryDonePath); + if (rename(recoveryConfPath, recoveryDonePath) != 0) ereport(FATAL, (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", - RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE))); + recoveryConfPath, recoveryDonePath))); ereport(LOG, (errmsg("archive recovery complete"))); diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 9f51929191d..8bf70219173 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -46,6 +46,7 @@ int MyPMChildSlot; * explicitly. */ char *DataDir = NULL; +char *RecoveryConfDir = NULL; char OutputFileName[MAXPGPATH]; /* debugging output file */ diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 24ca97d55c7..3d48eb8c9d3 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -100,6 +100,25 @@ SetDataDir(const char *dir) } /* + * Set recovery config directory, but make sure it's an absolute path. Use this, + * never set RecoveryConfDir directly. + */ +void +SetRecoveryConfDir(const char *dir) +{ + char *new; + + AssertArg(dir); + + /* If presented path is relative, convert to absolute */ + new = make_absolute_path(dir); + + if (RecoveryConfDir) + free(RecoveryConfDir); + RecoveryConfDir = new; +} + +/* * Change working directory to DataDir. Most of the postmaster and backend * code assumes that we are in DataDir so it can use relative paths to access * stuff in and under the data directory. For convenience during path diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 22ba35fef93..0459dd1c09b 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -424,6 +424,7 @@ int temp_file_limit = -1; int num_temp_buffers = 1024; char *data_directory; +char *recovery_config_directory; char *ConfigFileName; char *HbaFileName; char *IdentFileName; @@ -2961,6 +2962,17 @@ static struct config_string ConfigureNamesString[] = }, { + {"recovery_config_directory", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's recovery configuration directory."), + NULL, + GUC_SUPERUSER_ONLY + }, + &recovery_config_directory, + NULL, + NULL, NULL, NULL + }, + + { {"config_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Sets the server's main configuration file."), NULL, @@ -4182,6 +4194,18 @@ SelectConfigFiles(const char *userDoption, const char *progname) SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE); /* + * If the recovery_config_directory GUC variable has been set, use that, + * otherwise use DataDir. + * + * Note: SetRecoveryConfDir will copy and absolute-ize its argument, + * so we don't have to. + */ + if (recovery_config_directory) + SetRecoveryConfDir(recovery_config_directory); + else + SetRecoveryConfDir(DataDir); + + /* * If timezone_abbreviations wasn't set in the configuration file, install * the default value. We do it this way because we can't safely install a * "real" value until my_exec_path is set, which may not have happened diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 99858a765f1..2bc513045d7 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -137,6 +137,7 @@ extern bool IsBinaryUpgrade; extern bool ExitOnAnyError; extern PGDLLIMPORT char *DataDir; +extern PGDLLIMPORT char *RecoveryConfDir; extern PGDLLIMPORT int NBuffers; extern int MaxBackends; @@ -301,6 +302,7 @@ extern Oid GetCurrentRoleId(void); extern void SetCurrentRoleId(Oid roleid, bool is_superuser); extern void SetDataDir(const char *dir); +extern void SetRecoveryConfDir(const char *dir); extern void ChangeToDataDir(void); extern char *make_absolute_path(const char *path); diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index d497b1f6546..42428cbd435 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -220,6 +220,7 @@ extern int temp_file_limit; extern int num_temp_buffers; extern char *data_directory; +extern char *recovery_config_directory; extern char *ConfigFileName; extern char *HbaFileName; extern char *IdentFileName; |