Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+82-27
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)