@@ -66,6 +66,11 @@ typedef struct TablespaceList
66
66
*/
67
67
#define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
68
68
69
+ /*
70
+ * recovery.conf is integrated into postgresql.conf from version 12.
71
+ */
72
+ #define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000
73
+
69
74
/*
70
75
* Different ways to include WAL
71
76
*/
@@ -974,6 +979,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
974
979
bool basetablespace = PQgetisnull (res , rownum , 0 );
975
980
bool in_tarhdr = true;
976
981
bool skip_file = false;
982
+ bool is_recovery_guc_supported = true;
977
983
bool is_postgresql_auto_conf = false;
978
984
bool found_postgresql_auto_conf = false;
979
985
int file_padding_len = 0 ;
@@ -984,6 +990,10 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
984
990
gzFile ztarfile = NULL ;
985
991
#endif
986
992
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
+
987
997
if (basetablespace )
988
998
{
989
999
/*
@@ -1130,30 +1140,47 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1130
1140
{
1131
1141
char header [512 ];
1132
1142
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 )
1134
1151
{
1135
1152
int padding ;
1136
1153
1137
- tarCreateHeader (header , "postgresql.auto.conf" , NULL ,
1154
+ tarCreateHeader (header ,
1155
+ is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf" ,
1156
+ NULL ,
1138
1157
recoveryconfcontents -> len ,
1139
1158
pg_file_create_mode , 04000 , 02000 ,
1140
1159
time (NULL ));
1141
1160
1142
1161
padding = ((recoveryconfcontents -> len + 511 ) & ~511 ) - recoveryconfcontents -> len ;
1143
1162
1144
1163
WRITE_TAR_DATA (header , sizeof (header ));
1145
- WRITE_TAR_DATA (recoveryconfcontents -> data , recoveryconfcontents -> len );
1164
+ WRITE_TAR_DATA (recoveryconfcontents -> data ,
1165
+ recoveryconfcontents -> len );
1146
1166
if (padding )
1147
1167
WRITE_TAR_DATA (zerobuf , padding );
1148
1168
}
1149
1169
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 ));
1154
1180
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
+ }
1157
1184
}
1158
1185
1159
1186
/* 2 * 512 bytes empty data at end of file */
@@ -1252,16 +1279,24 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1252
1279
* We have the complete header structure in tarhdr,
1253
1280
* look at the file metadata: we may want append
1254
1281
* 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.
1257
1285
*/
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 );
1260
1293
1261
1294
filesz = read_tar_number (& tarhdr [124 ], 12 );
1262
1295
file_padding_len = ((filesz + 511 ) & ~511 ) - filesz ;
1263
1296
1264
- if (is_postgresql_auto_conf && writerecoveryconf )
1297
+ if (is_recovery_guc_supported &&
1298
+ is_postgresql_auto_conf &&
1299
+ writerecoveryconf )
1265
1300
{
1266
1301
/* replace tar header */
1267
1302
char header [512 ];
@@ -1313,7 +1348,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1313
1348
pos += bytes2write ;
1314
1349
filesz -= bytes2write ;
1315
1350
}
1316
- else if (is_postgresql_auto_conf && writerecoveryconf )
1351
+ else if (is_recovery_guc_supported &&
1352
+ is_postgresql_auto_conf &&
1353
+ writerecoveryconf )
1317
1354
{
1318
1355
/* append recovery config to postgresql.auto.conf */
1319
1356
int padding ;
@@ -1690,6 +1727,13 @@ GenerateRecoveryConf(PGconn *conn)
1690
1727
exit (1 );
1691
1728
}
1692
1729
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
+
1693
1737
connOptions = PQconninfo (conn );
1694
1738
if (connOptions == NULL )
1695
1739
{
@@ -1756,21 +1800,29 @@ GenerateRecoveryConf(PGconn *conn)
1756
1800
1757
1801
/*
1758
1802
* 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.
1761
1807
*/
1762
1808
static void
1763
1809
WriteRecoveryConf (void )
1764
1810
{
1765
1811
char filename [MAXPGPATH ];
1766
1812
FILE * cf ;
1813
+ bool is_recovery_guc_supported = true;
1767
1814
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;
1769
1817
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" );
1771
1822
if (cf == NULL )
1772
1823
{
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 ));
1774
1826
exit (1 );
1775
1827
}
1776
1828
@@ -1784,15 +1836,18 @@ WriteRecoveryConf(void)
1784
1836
1785
1837
fclose (cf );
1786
1838
1787
- snprintf (filename , MAXPGPATH , "%s/%s" , basedir , "standby.signal" );
1788
- cf = fopen (filename , "w" );
1789
- if (cf == NULL )
1839
+ if (is_recovery_guc_supported )
1790
1840
{
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
+ }
1794
1848
1795
- fclose (cf );
1849
+ fclose (cf );
1850
+ }
1796
1851
}
1797
1852
1798
1853
0 commit comments