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 15:15:32 Functions: 100.0 % 1 1 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           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 *
      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 */
      75 UBC           0 :             pg_log_error("syntax error in history file: %s", fline);
      76               0 :             pg_log_error_detail("Expected a numeric timeline ID.");
      77               0 :             exit(1);
      78                 :         }
      79 CBC          15 :         if (nfields != 3)
      80                 :         {
      81 UBC           0 :             pg_log_error("syntax error in history file: %s", fline);
      82               0 :             pg_log_error_detail("Expected a write-ahead log switchpoint location.");
      83               0 :             exit(1);
      84                 :         }
      85 CBC          15 :         if (entries && tli <= lasttli)
      86                 :         {
      87 UBC           0 :             pg_log_error("invalid data in history file: %s", fline);
      88               0 :             pg_log_error_detail("Timeline IDs must be in increasing sequence.");
      89               0 :             exit(1);
      90                 :         }
      91                 : 
      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                 :     {
     108 UBC           0 :         pg_log_error("invalid data in history file");
     109               0 :         pg_log_error_detail("Timeline IDs must be less than child timeline's ID.");
     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                 :      */
     117 CBC          14 :     nlines++;
     118              14 :     if (entries)
     119              14 :         entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
     120                 :     else
     121 UBC           0 :         entries = pg_malloc(1 * sizeof(TimeLineHistoryEntry));
     122                 : 
     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