@@ -842,7 +842,10 @@ restore_files(void *arg)
842842 return NULL ;
843843}
844844
845- /* Create recovery.conf with given recovery target parameters */
845+ /*
846+ * Create recovery.conf (probackup_recovery.conf in case of PG12)
847+ * with given recovery target parameters
848+ */
846849static void
847850create_recovery_conf (time_t backup_id ,
848851 pgRecoveryTarget * rt ,
@@ -851,9 +854,17 @@ create_recovery_conf(time_t backup_id,
851854{
852855 char path [MAXPGPATH ];
853856 FILE * fp ;
854- bool need_restore_conf ;
857+ bool pitr_requested ;
855858 bool target_latest ;
856859 bool target_immediate ;
860+ bool restore_command_provided = false;
861+ char restore_command_guc [16384 ];
862+
863+ if (instance_config .restore_command &&
864+ (pg_strcasecmp (instance_config .restore_command , "none" ) != 0 ))
865+ {
866+ restore_command_provided = true;
867+ }
857868
858869 /* restore-target='latest' support */
859870 target_latest = rt -> target_stop != NULL &&
@@ -862,16 +873,39 @@ create_recovery_conf(time_t backup_id,
862873 target_immediate = rt -> target_stop != NULL &&
863874 strcmp (rt -> target_stop , "immediate" ) == 0 ;
864875
865- need_restore_conf = !backup -> stream || rt -> time_string ||
876+ /*
877+ * Note that setting restore_command alone interpreted
878+ * as PITR with target - "until all available WAL is replayed".
879+ * We do this because of the following case:
880+ * The user is restoring STREAM backup as replica but
881+ * also relies on WAL archive to catch-up with master.
882+ * If restore_command is provided, then it should be
883+ * added to recovery config.
884+ * In this scenario, "would be" replica will replay
885+ * all WAL segments available in WAL archive, after that
886+ * it will try to connect to master via repprotocol.
887+ *
888+ * The risk is obvious, what if masters current state is
889+ * in "the past" relatively to latest state in the archive?
890+ * We will get a replica that is "in the future" to the master.
891+ * We accept this risk because its probability is low.
892+ */
893+ pitr_requested = !backup -> stream || rt -> time_string ||
866894 rt -> xid_string || rt -> lsn_string || rt -> target_name ||
867- target_immediate || target_latest ;
895+ target_immediate || target_latest || restore_command_provided ;
868896
869897 /* No need to generate recovery.conf at all. */
870- if (!(need_restore_conf || params -> restore_as_replica ))
898+ if (!(pitr_requested || params -> restore_as_replica ))
871899 {
872900 /*
873901 * Restoring STREAM backup without PITR and not as replica,
874902 * recovery.signal and standby.signal for PG12 are not needed
903+ *
904+ * We do not add "include" option in this case because
905+ * here we are creating empty "probackup_recovery.conf"
906+ * to handle possible already existing "include"
907+ * directive pointing to "probackup_recovery.conf".
908+ * If don`t do that, recovery will fail.
875909 */
876910 pg12_recovery_config (backup , false);
877911 return ;
@@ -901,13 +935,10 @@ create_recovery_conf(time_t backup_id,
901935#endif
902936
903937 /* construct restore_command */
904- if (need_restore_conf )
938+ if (pitr_requested )
905939 {
906- char restore_command_guc [16384 ];
907-
908- /* If restore_command is provided, use it */
909- if (instance_config .restore_command &&
910- (pg_strcasecmp (instance_config .restore_command , "none" ) != 0 ))
940+ /* If restore_command is provided, use it. Otherwise construct it from scratch. */
941+ if (restore_command_provided )
911942 sprintf (restore_command_guc , "%s" , instance_config .restore_command );
912943 else
913944 {
@@ -937,10 +968,6 @@ create_recovery_conf(time_t backup_id,
937968 }
938969 }
939970
940- elog (LOG , "Setting restore_command to '%s'" , restore_command_guc );
941- fio_fprintf (fp , "restore_command = '%s'\n" ,
942- restore_command_guc );
943-
944971 /*
945972 * We've already checked that only one of the four following mutually
946973 * exclusive options is specified, so the order of calls is insignificant.
@@ -996,13 +1023,29 @@ create_recovery_conf(time_t backup_id,
9961023 fio_fprintf (fp , "primary_conninfo = '%s'\n" , backup -> primary_conninfo );
9971024 }
9981025
1026+ if (pitr_requested )
1027+ {
1028+ elog (LOG , "Setting restore_command to '%s'" , restore_command_guc );
1029+ fio_fprintf (fp , "restore_command = '%s'\n" , restore_command_guc );
1030+ }
1031+
9991032 if (fio_fflush (fp ) != 0 ||
10001033 fio_fclose (fp ))
10011034 elog (ERROR , "cannot write file \"%s\": %s" , path ,
10021035 strerror (errno ));
10031036
10041037#if PG_VERSION_NUM >= 120000
1005- if (need_restore_conf )
1038+ /*
1039+ * Create "recovery.signal" to mark this recovery as PITR for PostgreSQL.
1040+ * In older versions presense of recovery.conf alone was enough.
1041+ * To keep behaviour consistent with older versions,
1042+ * we are forced to create "recovery.signal"
1043+ * even when only restore_command is provided.
1044+ * Presense of "recovery.signal" by itself determine only
1045+ * one thing: do PostgreSQL must switch to a new timeline
1046+ * after successfull recovery or not?
1047+ */
1048+ if (pitr_requested )
10061049 {
10071050 elog (LOG , "creating recovery.signal file" );
10081051 snprintf (path , lengthof (path ), "%s/recovery.signal" , instance_config .pgdata );
0 commit comments