]> granicus.if.org Git - postgresql/commitdiff
Add TIMELINE to backup_label file
authorSimon Riggs <simon@2ndQuadrant.com>
Sat, 6 Jan 2018 12:24:19 +0000 (12:24 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Sat, 6 Jan 2018 12:24:19 +0000 (12:24 +0000)
Allows new test to confirm timelines match

Author: Michael Paquier
Reviewed-by: David Steele
src/backend/access/transam/xlog.c
src/test/perl/PostgresNode.pm

index 02974f0e52c86aa79c2a539206a989a7f490518d..e42b828edf05b85f279cb98658a183269fabef20 100644 (file)
@@ -10535,6 +10535,7 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
                                                 backup_started_in_recovery ? "standby" : "master");
                appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
                appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
+               appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
 
                /*
                 * 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)
                                (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
                fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
                                (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
-               /* transfer remaining lines from label to history file */
+               /*
+                * Transfer remaining lines including label and start timeline to
+                * history file.
+                */
                fprintf(fp, "%s", remaining);
                fprintf(fp, "STOP TIME: %s\n", strfbuf);
+               fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
                if (fflush(fp) || ferror(fp) || FreeFile(fp))
                        ereport(ERROR,
                                        (errcode_for_file_access(),
@@ -11228,11 +11233,13 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
                                  bool *backupFromStandby)
 {
        char            startxlogfilename[MAXFNAMELEN];
-       TimeLineID      tli;
+       TimeLineID      tli_from_walseg, tli_from_file;
        FILE       *lfp;
        char            ch;
        char            backuptype[20];
        char            backupfrom[20];
+       char            backuplabel[MAXPGPATH];
+       char            backuptime[128];
        uint32          hi,
                                lo;
 
@@ -11259,7 +11266,7 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
         * format).
         */
        if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s)%c",
-                          &hi, &lo, &tli, startxlogfilename, &ch) != 5 || ch != '\n')
+                          &hi, &lo, &tli_from_walseg, startxlogfilename, &ch) != 5 || ch != '\n')
                ereport(FATAL,
                                (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
@@ -11288,6 +11295,43 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired,
                        *backupFromStandby = true;
        }
 
+       /*
+        * Parse START TIME and LABEL. Those are not mandatory fields for
+        * recovery but checking for their presence is useful for debugging
+        * and the next sanity checks. Cope also with the fact that the
+        * result buffers have a pre-allocated size, hence if the backup_label
+        * file has been generated with strings longer than the maximum assumed
+        * here an incorrect parsing happens. That's fine as only minor
+        * consistency checks are done afterwards.
+        */
+       if (fscanf(lfp, "START TIME: %127[^\n]\n", backuptime) == 1)
+               ereport(DEBUG1,
+                               (errmsg("backup time %s in file \"%s\"",
+                                               backuptime, BACKUP_LABEL_FILE)));
+
+       if (fscanf(lfp, "LABEL: %1023[^\n]\n", backuplabel) == 1)
+               ereport(DEBUG1,
+                               (errmsg("backup label %s in file \"%s\"",
+                                               backuplabel, BACKUP_LABEL_FILE)));
+
+       /*
+        * START TIMELINE is new as of 11. Its parsing is not mandatory, still
+        * use it as a sanity check if present.
+        */
+       if (fscanf(lfp, "START TIMELINE: %u\n", &tli_from_file) == 1)
+       {
+               if (tli_from_walseg != tli_from_file)
+                       ereport(FATAL,
+                                       (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                                        errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE),
+                                        errdetail("Timeline ID parsed is %u, but expected %u",
+                                                          tli_from_file, tli_from_walseg)));
+
+               ereport(DEBUG1,
+                               (errmsg("backup timeline %u in file \"%s\"",
+                                               tli_from_file, BACKUP_LABEL_FILE)));
+       }
+
        if (ferror(lfp) || FreeFile(lfp))
                ereport(FATAL,
                                (errcode_for_file_access(),
index 93faadc20e9244599a0bd2b321707c2139e445f4..80f68df246b00e95f47b6683570326d8d5088ff6 100644 (file)
@@ -419,6 +419,7 @@ sub init
        print $conf "restart_after_crash = off\n";
        print $conf "log_line_prefix = '%m [%p] %q%a '\n";
        print $conf "log_statement = all\n";
+       print $conf "log_min_messages = debug1\n";
        print $conf "log_replication_commands = on\n";
        print $conf "wal_retrieve_retry_interval = '500ms'\n";
        print $conf "port = $port\n";