]> granicus.if.org Git - postgresql/commitdiff
Allow external recovery_config_directory
authorSimon Riggs <simon@2ndQuadrant.com>
Wed, 27 Mar 2013 11:45:42 +0000 (11:45 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Wed, 27 Mar 2013 11:45:42 +0000 (11:45 +0000)
If required, recovery.conf can now be located outside of the data directory.
Server needs read/write permissions on this directory.

doc/src/sgml/config.sgml
src/backend/access/transam/xlog.c
src/backend/utils/init/globals.c
src/backend/utils/init/miscinit.c
src/backend/utils/misc/guc.c
src/include/miscadmin.h
src/include/utils/guc.h

index d750f0800b70083311112904c90658110d33b96c..6488399708f2db3cb4d1d574cc3b2925db1c1e5c 100644 (file)
@@ -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>
index 07c68adf0bcda74ddd6ae102e6da281733d792e7..2f91bc88eaa884ba14054c31b99c14aadbb0ba4e 100644 (file)
@@ -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")));
index 9f51929191d5b23d12e13068843117a988df3436..8bf702191730472cfad72f0a7a1f750592cf4548 100644 (file)
@@ -46,6 +46,7 @@ int                   MyPMChildSlot;
  * explicitly.
  */
 char      *DataDir = NULL;
+char      *RecoveryConfDir = NULL;
 
 char           OutputFileName[MAXPGPATH];      /* debugging output file */
 
index 24ca97d55c73ab5072de0bc29d629fce2145c769..3d48eb8c9d35740dbdd8112ed3d74eec64a85a76 100644 (file)
@@ -99,6 +99,25 @@ SetDataDir(const char *dir)
        DataDir = new;
 }
 
+/*
+ * 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
index 22ba35fef93fda2d13f0058cee1085ea6f3e416b..0459dd1c09bc7bf1c981a98cc484185ee27b72aa 100644 (file)
@@ -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;
@@ -2960,6 +2961,17 @@ static struct config_string ConfigureNamesString[] =
                NULL, NULL, NULL
        },
 
+       {
+               {"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."),
@@ -4181,6 +4193,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
index 99858a765f1a0e18ff32c973eccb04ba196a7dc5..2bc513045d766aa40b250dff3810a04bb7a6f5d3 100644 (file)
@@ -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);
 
index d497b1f6546d2dd0d41a34285c066e2a11b19748..42428cbd4351cfdcf79b0844018220b530581ff9 100644 (file)
@@ -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;