aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2013-03-27 11:45:42 +0000
committerSimon Riggs <simon@2ndQuadrant.com>2013-03-27 11:45:42 +0000
commitbc5334d8679c428a709d150666b288171795bd76 (patch)
treefc964f441b4dd08a483987762771c936bcaf7959
parentf7f210b5c4c9c76e87fffc5abef7dea752d1ac9a (diff)
downloadpostgresql-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.sgml17
-rw-r--r--src/backend/access/transam/xlog.c18
-rw-r--r--src/backend/utils/init/globals.c1
-rw-r--r--src/backend/utils/init/miscinit.c19
-rw-r--r--src/backend/utils/misc/guc.c24
-rw-r--r--src/include/miscadmin.h2
-rw-r--r--src/include/utils/guc.h1
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;