Skip to content

Commit beeb8e2

Browse files
committed
Fix compatibility of pg_basebackup -R with 11 and older versions
When 2dedf4d has integrated recovery.conf into postgresql.conf, it also changed pg_basebackup -R in the way recovery configuration is generated. However this implementation forgot the fact that pg_basebackup needs to keep compatibility with older server versions as well. Reported-by: Devrim Gündüz Author: Sergei Kornilov, Michael Paquier Discussion: https://postgr.es/m/3458f7cd12d74acd90180a671c8d5a081d60e162.camel@gunduz.org
1 parent 251cf2e commit beeb8e2

File tree

1 file changed

+82
-27
lines changed

1 file changed

+82
-27
lines changed

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ typedef struct TablespaceList
6666
*/
6767
#define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
6868

69+
/*
70+
* recovery.conf is integrated into postgresql.conf from version 12.
71+
*/
72+
#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000
73+
6974
/*
7075
* Different ways to include WAL
7176
*/
@@ -974,6 +979,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
974979
bool basetablespace = PQgetisnull(res, rownum, 0);
975980
bool in_tarhdr = true;
976981
bool skip_file = false;
982+
bool is_recovery_guc_supported = true;
977983
bool is_postgresql_auto_conf = false;
978984
bool found_postgresql_auto_conf = false;
979985
int file_padding_len = 0;
@@ -984,6 +990,10 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
984990
gzFile ztarfile = NULL;
985991
#endif
986992

993+
/* recovery.conf is integrated into postgresql.conf in 12 and newer */
994+
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC)
995+
is_recovery_guc_supported = false;
996+
987997
if (basetablespace)
988998
{
989999
/*
@@ -1130,30 +1140,47 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
11301140
{
11311141
char header[512];
11321142

1133-
if (!found_postgresql_auto_conf)
1143+
/*
1144+
* If postgresql.auto.conf has not been found in the streamed
1145+
* data, add recovery configuration to postgresql.auto.conf if
1146+
* recovery parameters are GUCs. If the instance connected to
1147+
* is older than 12, create recovery.conf with this data
1148+
* otherwise.
1149+
*/
1150+
if (!found_postgresql_auto_conf || !is_recovery_guc_supported)
11341151
{
11351152
int padding;
11361153

1137-
tarCreateHeader(header, "postgresql.auto.conf", NULL,
1154+
tarCreateHeader(header,
1155+
is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf",
1156+
NULL,
11381157
recoveryconfcontents->len,
11391158
pg_file_create_mode, 04000, 02000,
11401159
time(NULL));
11411160

11421161
padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len;
11431162

11441163
WRITE_TAR_DATA(header, sizeof(header));
1145-
WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len);
1164+
WRITE_TAR_DATA(recoveryconfcontents->data,
1165+
recoveryconfcontents->len);
11461166
if (padding)
11471167
WRITE_TAR_DATA(zerobuf, padding);
11481168
}
11491169

1150-
tarCreateHeader(header, "standby.signal", NULL,
1151-
0, /* zero-length file */
1152-
pg_file_create_mode, 04000, 02000,
1153-
time(NULL));
1170+
/*
1171+
* standby.signal is supported only if recovery parameters are
1172+
* GUCs.
1173+
*/
1174+
if (is_recovery_guc_supported)
1175+
{
1176+
tarCreateHeader(header, "standby.signal", NULL,
1177+
0, /* zero-length file */
1178+
pg_file_create_mode, 04000, 02000,
1179+
time(NULL));
11541180

1155-
WRITE_TAR_DATA(header, sizeof(header));
1156-
WRITE_TAR_DATA(zerobuf, 511);
1181+
WRITE_TAR_DATA(header, sizeof(header));
1182+
WRITE_TAR_DATA(zerobuf, 511);
1183+
}
11571184
}
11581185

11591186
/* 2 * 512 bytes empty data at end of file */
@@ -1252,16 +1279,24 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
12521279
* We have the complete header structure in tarhdr,
12531280
* look at the file metadata: we may want append
12541281
* recovery info into postgresql.auto.conf and skip
1255-
* standby.signal file. In both cases we must
1256-
* calculate tar padding
1282+
* standby.signal file if recovery parameters are
1283+
* integrated as GUCs, and recovery.conf otherwise. In
1284+
* both cases we must calculate tar padding.
12571285
*/
1258-
skip_file = (strcmp(&tarhdr[0], "standby.signal") == 0);
1259-
is_postgresql_auto_conf = (strcmp(&tarhdr[0], "postgresql.auto.conf") == 0);
1286+
if (is_recovery_guc_supported)
1287+
{
1288+
skip_file = (strcmp(&tarhdr[0], "standby.signal") == 0);
1289+
is_postgresql_auto_conf = (strcmp(&tarhdr[0], "postgresql.auto.conf") == 0);
1290+
}
1291+
else
1292+
skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0);
12601293

12611294
filesz = read_tar_number(&tarhdr[124], 12);
12621295
file_padding_len = ((filesz + 511) & ~511) - filesz;
12631296

1264-
if (is_postgresql_auto_conf && writerecoveryconf)
1297+
if (is_recovery_guc_supported &&
1298+
is_postgresql_auto_conf &&
1299+
writerecoveryconf)
12651300
{
12661301
/* replace tar header */
12671302
char header[512];
@@ -1313,7 +1348,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
13131348
pos += bytes2write;
13141349
filesz -= bytes2write;
13151350
}
1316-
else if (is_postgresql_auto_conf && writerecoveryconf)
1351+
else if (is_recovery_guc_supported &&
1352+
is_postgresql_auto_conf &&
1353+
writerecoveryconf)
13171354
{
13181355
/* append recovery config to postgresql.auto.conf */
13191356
int padding;
@@ -1690,6 +1727,13 @@ GenerateRecoveryConf(PGconn *conn)
16901727
exit(1);
16911728
}
16921729

1730+
/*
1731+
* In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by
1732+
* standby.signal to trigger a standby state at recovery.
1733+
*/
1734+
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC)
1735+
appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
1736+
16931737
connOptions = PQconninfo(conn);
16941738
if (connOptions == NULL)
16951739
{
@@ -1756,21 +1800,29 @@ GenerateRecoveryConf(PGconn *conn)
17561800

17571801
/*
17581802
* Write the configuration file into the directory specified in basedir,
1759-
* with the contents already collected in memory.
1760-
* Then write the signal file into the basedir also.
1803+
* with the contents already collected in memory appended. Then write
1804+
* the signal file into the basedir. If the server does not support
1805+
* recovery parameters as GUCs, the signal file is not necessary, and
1806+
* configuration is written to recovery.conf.
17611807
*/
17621808
static void
17631809
WriteRecoveryConf(void)
17641810
{
17651811
char filename[MAXPGPATH];
17661812
FILE *cf;
1813+
bool is_recovery_guc_supported = true;
17671814

1768-
snprintf(filename, MAXPGPATH, "%s/%s", basedir, "postgresql.auto.conf");
1815+
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC)
1816+
is_recovery_guc_supported = false;
17691817

1770-
cf = fopen(filename, "a");
1818+
snprintf(filename, MAXPGPATH, "%s/%s", basedir,
1819+
is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf");
1820+
1821+
cf = fopen(filename, is_recovery_guc_supported ? "a" : "w");
17711822
if (cf == NULL)
17721823
{
1773-
fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, filename, strerror(errno));
1824+
fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1825+
progname, filename, strerror(errno));
17741826
exit(1);
17751827
}
17761828

@@ -1784,15 +1836,18 @@ WriteRecoveryConf(void)
17841836

17851837
fclose(cf);
17861838

1787-
snprintf(filename, MAXPGPATH, "%s/%s", basedir, "standby.signal");
1788-
cf = fopen(filename, "w");
1789-
if (cf == NULL)
1839+
if (is_recovery_guc_supported)
17901840
{
1791-
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1792-
exit(1);
1793-
}
1841+
snprintf(filename, MAXPGPATH, "%s/%s", basedir, "standby.signal");
1842+
cf = fopen(filename, "w");
1843+
if (cf == NULL)
1844+
{
1845+
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1846+
exit(1);
1847+
}
17941848

1795-
fclose(cf);
1849+
fclose(cf);
1850+
}
17961851
}
17971852

17981853

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy