@@ -842,7 +842,10 @@ restore_files(void *arg)
842
842
return NULL ;
843
843
}
844
844
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
+ */
846
849
static void
847
850
create_recovery_conf (time_t backup_id ,
848
851
pgRecoveryTarget * rt ,
@@ -851,9 +854,17 @@ create_recovery_conf(time_t backup_id,
851
854
{
852
855
char path [MAXPGPATH ];
853
856
FILE * fp ;
854
- bool need_restore_conf ;
857
+ bool pitr_requested ;
855
858
bool target_latest ;
856
859
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
+ }
857
868
858
869
/* restore-target='latest' support */
859
870
target_latest = rt -> target_stop != NULL &&
@@ -862,16 +873,39 @@ create_recovery_conf(time_t backup_id,
862
873
target_immediate = rt -> target_stop != NULL &&
863
874
strcmp (rt -> target_stop , "immediate" ) == 0 ;
864
875
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 ||
866
894
rt -> xid_string || rt -> lsn_string || rt -> target_name ||
867
- target_immediate || target_latest ;
895
+ target_immediate || target_latest || restore_command_provided ;
868
896
869
897
/* 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 ))
871
899
{
872
900
/*
873
901
* Restoring STREAM backup without PITR and not as replica,
874
902
* 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.
875
909
*/
876
910
pg12_recovery_config (backup , false);
877
911
return ;
@@ -901,13 +935,10 @@ create_recovery_conf(time_t backup_id,
901
935
#endif
902
936
903
937
/* construct restore_command */
904
- if (need_restore_conf )
938
+ if (pitr_requested )
905
939
{
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 )
911
942
sprintf (restore_command_guc , "%s" , instance_config .restore_command );
912
943
else
913
944
{
@@ -937,10 +968,6 @@ create_recovery_conf(time_t backup_id,
937
968
}
938
969
}
939
970
940
- elog (LOG , "Setting restore_command to '%s'" , restore_command_guc );
941
- fio_fprintf (fp , "restore_command = '%s'\n" ,
942
- restore_command_guc );
943
-
944
971
/*
945
972
* We've already checked that only one of the four following mutually
946
973
* exclusive options is specified, so the order of calls is insignificant.
@@ -996,13 +1023,29 @@ create_recovery_conf(time_t backup_id,
996
1023
fio_fprintf (fp , "primary_conninfo = '%s'\n" , backup -> primary_conninfo );
997
1024
}
998
1025
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
+
999
1032
if (fio_fflush (fp ) != 0 ||
1000
1033
fio_fclose (fp ))
1001
1034
elog (ERROR , "cannot write file \"%s\": %s" , path ,
1002
1035
strerror (errno ));
1003
1036
1004
1037
#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 )
1006
1049
{
1007
1050
elog (LOG , "creating recovery.signal file" );
1008
1051
snprintf (path , lengthof (path ), "%s/recovery.signal" , instance_config .pgdata );
0 commit comments