LCOV - code coverage report
Current view: top level - src/bin/pg_rewind - timeline.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 41 54 75.9 %
Date: 2019-06-19 14:06:47 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13