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