diff options
| author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-09-25 14:35:24 -0300 |
|---|---|---|
| committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-09-25 14:35:24 -0300 |
| commit | caba97a9d9f4d4fa2531985fd12d3cd823da06f3 (patch) | |
| tree | 3632584cec7896bea0c611a01b07fdcb3b21f197 /src/bin/pg_basebackup/pg_basebackup.c | |
| parent | f5daf7f3266ff5a92f1bf8d386bd5ac3d7d042d6 (diff) | |
Split out recovery confing-writing code from pg_basebackup
... into a new file, fe_utils/recovery_gen.c.
This can later be used by pg_rewind.
Authors: Paul Guo, Jimmy Yih, Ashwin Agrawal. A few tweaks by Álvaro Herrera
Reviewed-by: Michaël Paquier
Discussion: https://postgr.es/m/CAEET0ZEffUkXc48pg2iqARQgGRYDiiVxDu+yYek_bTwJF+q=Uw@mail.gmail.com
Diffstat (limited to 'src/bin/pg_basebackup/pg_basebackup.c')
| -rw-r--r-- | src/bin/pg_basebackup/pg_basebackup.c | 162 |
1 files changed, 3 insertions, 159 deletions
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 7986872f106..55ef13926da 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -31,6 +31,7 @@ #include "common/file_utils.h" #include "common/logging.h" #include "common/string.h" +#include "fe_utils/recovery_gen.h" #include "fe_utils/string_utils.h" #include "getopt_long.h" #include "libpq-fe.h" @@ -68,11 +69,6 @@ typedef struct TablespaceList #define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000 /* - * recovery.conf is integrated into postgresql.conf from version 12. - */ -#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000 - -/* * Different ways to include WAL */ typedef enum @@ -147,8 +143,6 @@ static void progress_report(int tablespacenum, const char *filename, bool force) static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum); static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum); -static void GenerateRecoveryConf(PGconn *conn); -static void WriteRecoveryConf(void); static void BaseBackup(void); static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, @@ -1629,7 +1623,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) PQfreemem(copybuf); if (basetablespace && writerecoveryconf) - WriteRecoveryConf(); + WriteRecoveryConfig(conn, basedir, recoveryconfcontents); /* * No data is synced here, everything is done for all tablespaces at the @@ -1637,156 +1631,6 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) */ } -/* - * Escape a string so that it can be used as a value in a key-value pair - * a configuration file. - */ -static char * -escape_quotes(const char *src) -{ - char *result = escape_single_quotes_ascii(src); - - if (!result) - { - pg_log_error("out of memory"); - exit(1); - } - return result; -} - -/* - * Create a configuration file in memory using a PQExpBuffer - */ -static void -GenerateRecoveryConf(PGconn *conn) -{ - PQconninfoOption *connOptions; - PQconninfoOption *option; - PQExpBufferData conninfo_buf; - char *escaped; - - recoveryconfcontents = createPQExpBuffer(); - if (!recoveryconfcontents) - { - pg_log_error("out of memory"); - exit(1); - } - - /* - * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by - * standby.signal to trigger a standby state at recovery. - */ - if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) - appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n"); - - connOptions = PQconninfo(conn); - if (connOptions == NULL) - { - pg_log_error("out of memory"); - exit(1); - } - - initPQExpBuffer(&conninfo_buf); - for (option = connOptions; option && option->keyword; option++) - { - /* Omit empty settings and those libpqwalreceiver overrides. */ - if (strcmp(option->keyword, "replication") == 0 || - strcmp(option->keyword, "dbname") == 0 || - strcmp(option->keyword, "fallback_application_name") == 0 || - (option->val == NULL) || - (option->val != NULL && option->val[0] == '\0')) - continue; - - /* Separate key-value pairs with spaces */ - if (conninfo_buf.len != 0) - appendPQExpBufferChar(&conninfo_buf, ' '); - - /* - * Write "keyword=value" pieces, the value string is escaped and/or - * quoted if necessary. - */ - appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword); - appendConnStrVal(&conninfo_buf, option->val); - } - - /* - * Escape the connection string, so that it can be put in the config file. - * Note that this is different from the escaping of individual connection - * options above! - */ - escaped = escape_quotes(conninfo_buf.data); - appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped); - free(escaped); - - if (replication_slot) - { - /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */ - appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", - replication_slot); - } - - if (PQExpBufferBroken(recoveryconfcontents) || - PQExpBufferDataBroken(conninfo_buf)) - { - pg_log_error("out of memory"); - exit(1); - } - - termPQExpBuffer(&conninfo_buf); - - PQconninfoFree(connOptions); -} - - -/* - * Write the configuration file into the directory specified in basedir, - * with the contents already collected in memory appended. Then write - * the signal file into the basedir. If the server does not support - * recovery parameters as GUCs, the signal file is not necessary, and - * configuration is written to recovery.conf. - */ -static void -WriteRecoveryConf(void) -{ - char filename[MAXPGPATH]; - FILE *cf; - bool is_recovery_guc_supported = true; - - if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) - is_recovery_guc_supported = false; - - snprintf(filename, MAXPGPATH, "%s/%s", basedir, - is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf"); - - cf = fopen(filename, is_recovery_guc_supported ? "a" : "w"); - if (cf == NULL) - { - pg_log_error("could not open file \"%s\": %m", filename); - exit(1); - } - - if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1) - { - pg_log_error("could not write to file \"%s\": %m", filename); - exit(1); - } - - fclose(cf); - - if (is_recovery_guc_supported) - { - snprintf(filename, MAXPGPATH, "%s/%s", basedir, "standby.signal"); - cf = fopen(filename, "w"); - if (cf == NULL) - { - pg_log_error("could not create file \"%s\": %m", filename); - exit(1); - } - - fclose(cf); - } -} - static void BaseBackup(void) @@ -1843,7 +1687,7 @@ BaseBackup(void) * Build contents of configuration file if requested */ if (writerecoveryconf) - GenerateRecoveryConf(conn); + recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot); /* * Run IDENTIFY_SYSTEM so we can get the timeline |
