LCOV - differential code coverage report
Current view: top level - src/bin/pg_rewind - timeline.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 75.9 % 54 41 13 41
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 1 1 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 75.9 % 54 41 13 41
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 1 1 1

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * timeline.c
                                  4                 :  *    timeline-related functions.
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  *-------------------------------------------------------------------------
                                  9                 :  */
                                 10                 : #include "postgres_fe.h"
                                 11                 : 
                                 12                 : #include "access/timeline.h"
                                 13                 : #include "access/xlog_internal.h"
                                 14                 : #include "pg_rewind.h"
                                 15                 : 
                                 16                 : /*
                                 17                 :  * This is copy-pasted from the backend readTimeLineHistory, modified to
                                 18                 :  * return a malloc'd array and to work without backend functions.
                                 19                 :  */
                                 20                 : /*
                                 21                 :  * Try to read a timeline's history file.
                                 22                 :  *
                                 23                 :  * If successful, return the list of component TLIs (the given TLI followed by
                                 24                 :  * its ancestor TLIs).  If we can't find the history file, assume that the
                                 25                 :  * timeline has no parents, and return a list of just the specified timeline
                                 26                 :  * ID.
                                 27                 :  */
                                 28                 : TimeLineHistoryEntry *
 2939 heikki.linnakangas         29 CBC          14 : rewind_parseTimeLineHistory(char *buffer, TimeLineID targetTLI, int *nentries)
                                 30                 : {
                                 31                 :     char       *fline;
                                 32                 :     TimeLineHistoryEntry *entry;
                                 33              14 :     TimeLineHistoryEntry *entries = NULL;
                                 34              14 :     int         nlines = 0;
                                 35              14 :     TimeLineID  lasttli = 0;
                                 36                 :     XLogRecPtr  prevend;
                                 37                 :     char       *bufptr;
                                 38              14 :     bool        lastline = false;
                                 39                 : 
                                 40                 :     /*
                                 41                 :      * Parse the file...
                                 42                 :      */
                                 43              14 :     prevend = InvalidXLogRecPtr;
                                 44              14 :     bufptr = buffer;
                                 45              44 :     while (!lastline)
                                 46                 :     {
                                 47                 :         char       *ptr;
                                 48                 :         TimeLineID  tli;
                                 49                 :         uint32      switchpoint_hi;
                                 50                 :         uint32      switchpoint_lo;
                                 51                 :         int         nfields;
                                 52                 : 
                                 53              30 :         fline = bufptr;
                                 54             630 :         while (*bufptr && *bufptr != '\n')
                                 55             600 :             bufptr++;
                                 56              30 :         if (!(*bufptr))
                                 57              14 :             lastline = true;
                                 58                 :         else
                                 59              16 :             *bufptr++ = '\0';
                                 60                 : 
                                 61                 :         /* skip leading whitespace and check for # comment */
                                 62              30 :         for (ptr = fline; *ptr; ptr++)
                                 63                 :         {
                                 64              15 :             if (!isspace((unsigned char) *ptr))
                                 65              15 :                 break;
                                 66                 :         }
                                 67              30 :         if (*ptr == '\0' || *ptr == '#')
                                 68              15 :             continue;
                                 69                 : 
                                 70              15 :         nfields = sscanf(fline, "%u\t%X/%X", &tli, &switchpoint_hi, &switchpoint_lo);
                                 71                 : 
                                 72              15 :         if (nfields < 1)
                                 73                 :         {
                                 74                 :             /* expect a numeric timeline ID as first field of line */
 1469 peter                      75 UBC           0 :             pg_log_error("syntax error in history file: %s", fline);
  366 tgl                        76               0 :             pg_log_error_detail("Expected a numeric timeline ID.");
 2939 heikki.linnakangas         77               0 :             exit(1);
                                 78                 :         }
 2939 heikki.linnakangas         79 CBC          15 :         if (nfields != 3)
                                 80                 :         {
 1469 peter                      81 UBC           0 :             pg_log_error("syntax error in history file: %s", fline);
  366 tgl                        82               0 :             pg_log_error_detail("Expected a write-ahead log switchpoint location.");
 2939 heikki.linnakangas         83               0 :             exit(1);
                                 84                 :         }
 2939 heikki.linnakangas         85 CBC          15 :         if (entries && tli <= lasttli)
                                 86                 :         {
 1469 peter                      87 UBC           0 :             pg_log_error("invalid data in history file: %s", fline);
  366 tgl                        88               0 :             pg_log_error_detail("Timeline IDs must be in increasing sequence.");
 2939 heikki.linnakangas         89               0 :             exit(1);
                                 90                 :         }
                                 91                 : 
 2939 heikki.linnakangas         92 CBC          15 :         lasttli = tli;
                                 93                 : 
                                 94              15 :         nlines++;
                                 95              15 :         entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
                                 96                 : 
                                 97              15 :         entry = &entries[nlines - 1];
                                 98              15 :         entry->tli = tli;
                                 99              15 :         entry->begin = prevend;
                                100              15 :         entry->end = ((uint64) (switchpoint_hi)) << 32 | (uint64) switchpoint_lo;
                                101              15 :         prevend = entry->end;
                                102                 : 
                                103                 :         /* we ignore the remainder of each line */
                                104                 :     }
                                105                 : 
                                106              14 :     if (entries && targetTLI <= lasttli)
                                107                 :     {
 1469 peter                     108 UBC           0 :         pg_log_error("invalid data in history file");
  366 tgl                       109               0 :         pg_log_error_detail("Timeline IDs must be less than child timeline's ID.");
 2939 heikki.linnakangas        110               0 :         exit(1);
                                111                 :     }
                                112                 : 
                                113                 :     /*
                                114                 :      * Create one more entry for the "tip" of the timeline, which has no entry
                                115                 :      * in the history file.
                                116                 :      */
 2939 heikki.linnakangas        117 CBC          14 :     nlines++;
                                118              14 :     if (entries)
                                119              14 :         entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
                                120                 :     else
 2939 heikki.linnakangas        121 UBC           0 :         entries = pg_malloc(1 * sizeof(TimeLineHistoryEntry));
                                122                 : 
 2939 heikki.linnakangas        123 CBC          14 :     entry = &entries[nlines - 1];
                                124              14 :     entry->tli = targetTLI;
                                125              14 :     entry->begin = prevend;
                                126              14 :     entry->end = InvalidXLogRecPtr;
                                127                 : 
                                128              14 :     *nentries = nlines;
                                129              14 :     return entries;
                                130                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a