@@ -10535,6 +10535,7 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
1053510535backup_started_in_recovery ?"standby" :"master" );
1053610536appendStringInfo (labelfile ,"START TIME: %s\n" ,strfbuf );
1053710537appendStringInfo (labelfile ,"LABEL: %s\n" ,backupidstr );
10538+ appendStringInfo (labelfile ,"START TIMELINE: %u\n" ,starttli );
1053810539
1053910540/*
1054010541 * Okay, write the file, or return its contents to caller.
@@ -11015,9 +11016,13 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1101511016(uint32 ) (startpoint >>32 ), (uint32 )startpoint ,startxlogfilename );
1101611017fprintf (fp ,"STOP WAL LOCATION: %X/%X (file %s)\n" ,
1101711018(uint32 ) (stoppoint >>32 ), (uint32 )stoppoint ,stopxlogfilename );
11018- /* transfer remaining lines from label to history file */
11019+ /*
11020+ * Transfer remaining lines including label and start timeline to
11021+ * history file.
11022+ */
1101911023fprintf (fp ,"%s" ,remaining );
1102011024fprintf (fp ,"STOP TIME: %s\n" ,strfbuf );
11025+ fprintf (fp ,"STOP TIMELINE: %u\n" ,stoptli );
1102111026if (fflush (fp )|| ferror (fp )|| FreeFile (fp ))
1102211027ereport (ERROR ,
1102311028(errcode_for_file_access (),
@@ -11228,11 +11233,13 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
1122811233bool * backupFromStandby )
1122911234{
1123011235char startxlogfilename [MAXFNAMELEN ];
11231- TimeLineID tli ;
11236+ TimeLineID tli_from_walseg , tli_from_file ;
1123211237FILE * lfp ;
1123311238char ch ;
1123411239char backuptype [20 ];
1123511240char backupfrom [20 ];
11241+ char backuplabel [MAXPGPATH ];
11242+ char backuptime [128 ];
1123611243uint32 hi ,
1123711244lo ;
1123811245
@@ -11259,7 +11266,7 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
1125911266 * format).
1126011267 */
1126111268if (fscanf (lfp ,"START WAL LOCATION: %X/%X (file %08X%16s)%c" ,
11262- & hi ,& lo ,& tli ,startxlogfilename ,& ch )!= 5 || ch != '\n' )
11269+ & hi ,& lo ,& tli_from_walseg ,startxlogfilename ,& ch )!= 5 || ch != '\n' )
1126311270ereport (FATAL ,
1126411271(errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
1126511272errmsg ("invalid data in file \"%s\"" ,BACKUP_LABEL_FILE )));
@@ -11288,6 +11295,43 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
1128811295* backupFromStandby = true;
1128911296}
1129011297
11298+ /*
11299+ * Parse START TIME and LABEL. Those are not mandatory fields for
11300+ * recovery but checking for their presence is useful for debugging
11301+ * and the next sanity checks. Cope also with the fact that the
11302+ * result buffers have a pre-allocated size, hence if the backup_label
11303+ * file has been generated with strings longer than the maximum assumed
11304+ * here an incorrect parsing happens. That's fine as only minor
11305+ * consistency checks are done afterwards.
11306+ */
11307+ if (fscanf (lfp ,"START TIME: %127[^\n]\n" ,backuptime )== 1 )
11308+ ereport (DEBUG1 ,
11309+ (errmsg ("backup time %s in file \"%s\"" ,
11310+ backuptime ,BACKUP_LABEL_FILE )));
11311+
11312+ if (fscanf (lfp ,"LABEL: %1023[^\n]\n" ,backuplabel )== 1 )
11313+ ereport (DEBUG1 ,
11314+ (errmsg ("backup label %s in file \"%s\"" ,
11315+ backuplabel ,BACKUP_LABEL_FILE )));
11316+
11317+ /*
11318+ * START TIMELINE is new as of 11. Its parsing is not mandatory, still
11319+ * use it as a sanity check if present.
11320+ */
11321+ if (fscanf (lfp ,"START TIMELINE: %u\n" ,& tli_from_file )== 1 )
11322+ {
11323+ if (tli_from_walseg != tli_from_file )
11324+ ereport (FATAL ,
11325+ (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
11326+ errmsg ("invalid data in file \"%s\"" ,BACKUP_LABEL_FILE ),
11327+ errdetail ("Timeline ID parsed is %u, but expected %u" ,
11328+ tli_from_file ,tli_from_walseg )));
11329+
11330+ ereport (DEBUG1 ,
11331+ (errmsg ("backup timeline %u in file \"%s\"" ,
11332+ tli_from_file ,BACKUP_LABEL_FILE )));
11333+ }
11334+
1129111335if (ferror (lfp )|| FreeFile (lfp ))
1129211336ereport (FATAL ,
1129311337(errcode_for_file_access (),