PostgreSQL Source Code git master
Loading...
Searching...
No Matches
timeline.h File Reference
#include "access/xlogdefs.h"
#include "nodes/pg_list.h"
Include dependency graph for timeline.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  TimeLineHistoryEntry
 

Functions

ListreadTimeLineHistory (TimeLineID targetTLI)
 
bool existsTimeLineHistory (TimeLineID probeTLI)
 
TimeLineID findNewestTimeLine (TimeLineID startTLI)
 
void writeTimeLineHistory (TimeLineID newTLI, TimeLineID parentTLI, XLogRecPtr switchpoint, char *reason)
 
void writeTimeLineHistoryFile (TimeLineID tli, char *content, int size)
 
void restoreTimeLineHistoryFiles (TimeLineID begin, TimeLineID end)
 
bool tliInHistory (TimeLineID tli, List *expectedTLEs)
 
TimeLineID tliOfPointInHistory (XLogRecPtr ptr, List *history)
 
XLogRecPtr tliSwitchPoint (TimeLineID tli, List *history, TimeLineID *nextTLI)
 

Function Documentation

◆ existsTimeLineHistory()

bool existsTimeLineHistory ( TimeLineID  probeTLI)
extern

Definition at line 223 of file timeline.c.

224{
225 char path[MAXPGPATH];
227 FILE *fd;
228
229 /* Timeline 1 does not have a history file, so no need to check */
230 if (probeTLI == 1)
231 return false;
232
234 {
236 RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
237 }
238 else
240
241 fd = AllocateFile(path, "r");
242 if (fd != NULL)
243 {
244 FreeFile(fd);
245 return true;
246 }
247 else
248 {
249 if (errno != ENOENT)
252 errmsg("could not open file \"%s\": %m", path)));
253 return false;
254 }
255}
int errcode_for_file_access(void)
Definition elog.c:897
#define FATAL
Definition elog.h:41
#define ereport(elevel,...)
Definition elog.h:150
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
static char * errmsg
#define MAXPGPATH
static int fd(const char *x, int i)
static int fb(int x)
#define MAXFNAMELEN
static void TLHistoryFilePath(char *path, TimeLineID tli)
static void TLHistoryFileName(char *fname, TimeLineID tli)
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition xlogarchive.c:55
bool ArchiveRecoveryRequested

References AllocateFile(), ArchiveRecoveryRequested, ereport, errcode_for_file_access(), errmsg, FATAL, fb(), fd(), FreeFile(), MAXFNAMELEN, MAXPGPATH, RestoreArchivedFile(), TLHistoryFileName(), and TLHistoryFilePath().

Referenced by findNewestTimeLine(), validateRecoveryParameters(), and WalRcvFetchTimeLineHistoryFiles().

◆ findNewestTimeLine()

TimeLineID findNewestTimeLine ( TimeLineID  startTLI)
extern

Definition at line 265 of file timeline.c.

266{
269
270 /*
271 * The algorithm is just to probe for the existence of timeline history
272 * files. XXX is it useful to allow gaps in the sequence?
273 */
275
276 for (probeTLI = startTLI + 1;; probeTLI++)
277 {
279 {
280 newestTLI = probeTLI; /* probeTLI exists */
281 }
282 else
283 {
284 /* doesn't exist, assume we're done */
285 break;
286 }
287 }
288
289 return newestTLI;
290}
bool existsTimeLineHistory(TimeLineID probeTLI)
Definition timeline.c:223
uint32 TimeLineID
Definition xlogdefs.h:63

References existsTimeLineHistory(), and fb().

Referenced by rescanLatestTimeLine(), StartupXLOG(), and validateRecoveryParameters().

◆ readTimeLineHistory()

List * readTimeLineHistory ( TimeLineID  targetTLI)
extern

Definition at line 77 of file timeline.c.

78{
79 List *result;
80 char path[MAXPGPATH];
82 FILE *fd;
86 bool fromArchive = false;
87
88 /* Timeline 1 does not have a history file, so no need to check */
89 if (targetTLI == 1)
90 {
92 entry->tli = targetTLI;
93 entry->begin = entry->end = InvalidXLogRecPtr;
94 return list_make1(entry);
95 }
96
98 {
101 RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
102 }
103 else
105
106 fd = AllocateFile(path, "r");
107 if (fd == NULL)
108 {
109 if (errno != ENOENT)
112 errmsg("could not open file \"%s\": %m", path)));
113 /* Not there, so assume no parents */
115 entry->tli = targetTLI;
116 entry->begin = entry->end = InvalidXLogRecPtr;
117 return list_make1(entry);
118 }
119
120 result = NIL;
121
122 /*
123 * Parse the file...
124 */
126 for (;;)
127 {
128 char fline[MAXPGPATH];
129 char *res;
130 char *ptr;
131 TimeLineID tli;
134 int nfields;
135
137 res = fgets(fline, sizeof(fline), fd);
139 if (res == NULL)
140 {
141 if (ferror(fd))
144 errmsg("could not read file \"%s\": %m", path)));
145
146 break;
147 }
148
149 /* skip leading whitespace and check for # comment */
150 for (ptr = fline; *ptr; ptr++)
151 {
152 if (!isspace((unsigned char) *ptr))
153 break;
154 }
155 if (*ptr == '\0' || *ptr == '#')
156 continue;
157
158 nfields = sscanf(fline, "%u\t%X/%08X", &tli, &switchpoint_hi, &switchpoint_lo);
159
160 if (nfields < 1)
161 {
162 /* expect a numeric timeline ID as first field of line */
164 (errmsg("syntax error in history file: %s", fline),
165 errhint("Expected a numeric timeline ID.")));
166 }
167 if (nfields != 3)
169 (errmsg("syntax error in history file: %s", fline),
170 errhint("Expected a write-ahead log switchpoint location.")));
171
172 if (result && tli <= lasttli)
174 (errmsg("invalid data in history file: %s", fline),
175 errhint("Timeline IDs must be in increasing sequence.")));
176
177 lasttli = tli;
178
180 entry->tli = tli;
181 entry->begin = prevend;
182 entry->end = ((uint64) (switchpoint_hi)) << 32 | (uint64) switchpoint_lo;
183 prevend = entry->end;
184
185 /* Build list with newest item first */
186 result = lcons(entry, result);
187
188 /* we ignore the remainder of each line */
189 }
190
191 FreeFile(fd);
192
193 if (result && targetTLI <= lasttli)
195 (errmsg("invalid data in history file \"%s\"", path),
196 errhint("Timeline IDs must be less than child timeline's ID.")));
197
198 /*
199 * Create one more entry for the "tip" of the timeline, which has no entry
200 * in the history file.
201 */
203 entry->tli = targetTLI;
204 entry->begin = prevend;
205 entry->end = InvalidXLogRecPtr;
206
207 result = lcons(entry, result);
208
209 /*
210 * If the history file was fetched from archive, save it in pg_wal for
211 * future reference.
212 */
213 if (fromArchive)
215
216 return result;
217}
uint64_t uint64
Definition c.h:589
uint32_t uint32
Definition c.h:588
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define palloc_object(type)
Definition fe_memutils.h:74
List * lcons(void *datum, List *list)
Definition list.c:495
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:212
Definition pg_list.h:54
XLogRecPtr begin
Definition timeline.h:28
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:69
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
void KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
uint64 XLogRecPtr
Definition xlogdefs.h:21
#define InvalidXLogRecPtr
Definition xlogdefs.h:28

References AllocateFile(), ArchiveRecoveryRequested, TimeLineHistoryEntry::begin, TimeLineHistoryEntry::end, ereport, errcode_for_file_access(), errhint(), errmsg, ERROR, FATAL, fb(), fd(), FreeFile(), InvalidXLogRecPtr, KeepFileRestoredFromArchive(), lcons(), list_make1, MAXFNAMELEN, MAXPGPATH, NIL, palloc_object, pgstat_report_wait_end(), pgstat_report_wait_start(), RestoreArchivedFile(), TLHistoryFileName(), TLHistoryFilePath(), and TimeLineHistoryEntry::tli.

Referenced by AddWALInfoToBackupManifest(), GetOldestUnsummarizedLSN(), PrepareForIncrementalBackup(), ReadReplicationSlot(), rescanLatestTimeLine(), StartReplication(), summarizer_read_local_xlog_page(), WaitForWALToBecomeAvailable(), WalSummarizerMain(), XLogFileReadAnyTLI(), XLogReadDetermineTimeline(), and XLogSendPhysical().

◆ restoreTimeLineHistoryFiles()

void restoreTimeLineHistoryFiles ( TimeLineID  begin,
TimeLineID  end 
)
extern

Definition at line 51 of file timeline.c.

52{
53 char path[MAXPGPATH];
55 TimeLineID tli;
56
57 for (tli = begin; tli < end; tli++)
58 {
59 if (tli == 1)
60 continue;
61
63 if (RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false))
65 }
66}

References fb(), KeepFileRestoredFromArchive(), MAXFNAMELEN, MAXPGPATH, RestoreArchivedFile(), and TLHistoryFileName().

Referenced by rescanLatestTimeLine(), and StartupXLOG().

◆ tliInHistory()

bool tliInHistory ( TimeLineID  tli,
List expectedTLEs 
)
extern

Definition at line 527 of file timeline.c.

528{
529 ListCell *cell;
530
531 foreach(cell, expectedTLEs)
532 {
533 if (((TimeLineHistoryEntry *) lfirst(cell))->tli == tli)
534 return true;
535 }
536
537 return false;
538}
#define lfirst(lc)
Definition pg_list.h:172
static List * expectedTLEs

References expectedTLEs, and lfirst.

Referenced by checkTimeLineSwitch(), and ReadRecord().

◆ tliOfPointInHistory()

TimeLineID tliOfPointInHistory ( XLogRecPtr  ptr,
List history 
)
extern

Definition at line 545 of file timeline.c.

546{
547 ListCell *cell;
548
549 foreach(cell, history)
550 {
552
553 if ((!XLogRecPtrIsValid(tle->begin) || tle->begin <= ptr) &&
554 (!XLogRecPtrIsValid(tle->end) || ptr < tle->end))
555 {
556 /* found it */
557 return tle->tli;
558 }
559 }
560
561 /* shouldn't happen. */
562 elog(ERROR, "timeline history was not contiguous");
563 return 0; /* keep compiler quiet */
564}
#define elog(elevel,...)
Definition elog.h:226
#define XLogRecPtrIsValid(r)
Definition xlogdefs.h:29

References elog, ERROR, fb(), lfirst, TimeLineHistoryEntry::tli, and XLogRecPtrIsValid.

Referenced by InitWalRecovery(), ReadReplicationSlot(), WaitForWALToBecomeAvailable(), and XLogReadDetermineTimeline().

◆ tliSwitchPoint()

XLogRecPtr tliSwitchPoint ( TimeLineID  tli,
List history,
TimeLineID nextTLI 
)
extern

Definition at line 573 of file timeline.c.

574{
575 ListCell *cell;
576
577 if (nextTLI)
578 *nextTLI = 0;
579 foreach(cell, history)
580 {
582
583 if (tle->tli == tli)
584 return tle->end;
585 if (nextTLI)
586 *nextTLI = tle->tli;
587 }
588
590 (errmsg("requested timeline %u is not in this server's history",
591 tli)));
592 return InvalidXLogRecPtr; /* keep compiler quiet */
593}

References TimeLineHistoryEntry::end, ereport, errmsg, ERROR, fb(), InvalidXLogRecPtr, and lfirst.

Referenced by InitWalRecovery(), StartReplication(), summarizer_read_local_xlog_page(), WalSummarizerMain(), XLogReadDetermineTimeline(), and XLogSendPhysical().

◆ writeTimeLineHistory()

void writeTimeLineHistory ( TimeLineID  newTLI,
TimeLineID  parentTLI,
XLogRecPtr  switchpoint,
char reason 
)
extern

Definition at line 305 of file timeline.c.

307{
308 char path[MAXPGPATH];
309 char tmppath[MAXPGPATH];
311 char buffer[BLCKSZ];
312 int srcfd;
313 int fd;
314 int nbytes;
315
316 Assert(newTLI > parentTLI); /* else bad selection of newTLI */
317
318 /*
319 * Write into a temp file name.
320 */
321 snprintf(tmppath, MAXPGPATH, XLOGDIR "/xlogtemp.%d", (int) getpid());
322
324
325 /* do not use get_sync_bit() here --- want to fsync only at end of fill */
327 if (fd < 0)
330 errmsg("could not create file \"%s\": %m", tmppath)));
331
332 /*
333 * If a history file exists for the parent, copy it verbatim
334 */
336 {
338 RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
339 }
340 else
342
344 if (srcfd < 0)
345 {
346 if (errno != ENOENT)
349 errmsg("could not open file \"%s\": %m", path)));
350 /* Not there, so assume parent has no parents */
351 }
352 else
353 {
354 for (;;)
355 {
356 errno = 0;
358 nbytes = (int) read(srcfd, buffer, sizeof(buffer));
360 if (nbytes < 0 || errno != 0)
363 errmsg("could not read file \"%s\": %m", path)));
364 if (nbytes == 0)
365 break;
366 errno = 0;
368 if ((int) write(fd, buffer, nbytes) != nbytes)
369 {
370 int save_errno = errno;
371
372 /*
373 * If we fail to make the file, delete it to release disk
374 * space
375 */
377
378 /*
379 * if write didn't set errno, assume problem is no disk space
380 */
382
385 errmsg("could not write to file \"%s\": %m", tmppath)));
386 }
388 }
389
390 if (CloseTransientFile(srcfd) != 0)
393 errmsg("could not close file \"%s\": %m", path)));
394 }
395
396 /*
397 * Append one line with the details of this timeline split.
398 *
399 * If we did have a parent file, insert an extra newline just in case the
400 * parent file failed to end with one.
401 */
402 snprintf(buffer, sizeof(buffer),
403 "%s%u\t%X/%08X\t%s\n",
404 (srcfd < 0) ? "" : "\n",
405 parentTLI,
407 reason);
408
409 nbytes = strlen(buffer);
410 errno = 0;
412 if ((int) write(fd, buffer, nbytes) != nbytes)
413 {
414 int save_errno = errno;
415
416 /*
417 * If we fail to make the file, delete it to release disk space
418 */
420 /* if write didn't set errno, assume problem is no disk space */
422
425 errmsg("could not write to file \"%s\": %m", tmppath)));
426 }
428
430 if (pg_fsync(fd) != 0)
433 errmsg("could not fsync file \"%s\": %m", tmppath)));
435
436 if (CloseTransientFile(fd) != 0)
439 errmsg("could not close file \"%s\": %m", tmppath)));
440
441 /*
442 * Now move the completed history file into place with its final name.
443 */
445 Assert(access(path, F_OK) != 0 && errno == ENOENT);
447
448 /* The history file can be archived immediately. */
450 {
453 }
454}
#define Assert(condition)
Definition c.h:915
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition fd.c:783
int CloseTransientFile(int fd)
Definition fd.c:2855
int data_sync_elevel(int elevel)
Definition fd.c:3986
int pg_fsync(int fd)
Definition fd.c:390
int OpenTransientFile(const char *fileName, int fileFlags)
Definition fd.c:2678
#define write(a, b, c)
Definition win32.h:14
#define read(a, b, c)
Definition win32.h:13
#define snprintf
Definition port.h:260
short access
#define XLogArchivingActive()
Definition xlog.h:101
#define XLOGDIR
void XLogArchiveNotify(const char *xlog)
#define LSN_FORMAT_ARGS(lsn)
Definition xlogdefs.h:47

References ArchiveRecoveryRequested, Assert, CloseTransientFile(), data_sync_elevel(), durable_rename(), ereport, errcode_for_file_access(), errmsg, ERROR, fb(), fd(), LSN_FORMAT_ARGS, MAXFNAMELEN, MAXPGPATH, OpenTransientFile(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), read, RestoreArchivedFile(), snprintf, TLHistoryFileName(), TLHistoryFilePath(), write, XLogArchiveNotify(), XLogArchivingActive, and XLOGDIR.

Referenced by StartupXLOG().

◆ writeTimeLineHistoryFile()

void writeTimeLineHistoryFile ( TimeLineID  tli,
char content,
int  size 
)
extern

Definition at line 464 of file timeline.c.

465{
466 char path[MAXPGPATH];
467 char tmppath[MAXPGPATH];
468 int fd;
469
470 /*
471 * Write into a temp file name.
472 */
473 snprintf(tmppath, MAXPGPATH, XLOGDIR "/xlogtemp.%d", (int) getpid());
474
476
477 /* do not use get_sync_bit() here --- want to fsync only at end of fill */
479 if (fd < 0)
482 errmsg("could not create file \"%s\": %m", tmppath)));
483
484 errno = 0;
486 if ((int) write(fd, content, size) != size)
487 {
488 int save_errno = errno;
489
490 /*
491 * If we fail to make the file, delete it to release disk space
492 */
494 /* if write didn't set errno, assume problem is no disk space */
496
499 errmsg("could not write to file \"%s\": %m", tmppath)));
500 }
502
504 if (pg_fsync(fd) != 0)
507 errmsg("could not fsync file \"%s\": %m", tmppath)));
509
510 if (CloseTransientFile(fd) != 0)
513 errmsg("could not close file \"%s\": %m", tmppath)));
514
515 /*
516 * Now move the completed history file into place with its final name,
517 * replacing any existing file with the same name.
518 */
519 TLHistoryFilePath(path, tli);
521}

References CloseTransientFile(), data_sync_elevel(), durable_rename(), ereport, errcode_for_file_access(), errmsg, ERROR, fb(), fd(), MAXPGPATH, OpenTransientFile(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), snprintf, TLHistoryFilePath(), write, and XLOGDIR.

Referenced by WalRcvFetchTimeLineHistoryFiles().