PostgreSQL Source Code  git master
timeline.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include "access/timeline.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "access/xlogdefs.h"
#include "pgstat.h"
#include "storage/fd.h"
Include dependency graph for timeline.c:

Go to the source code of this file.

Functions

void restoreTimeLineHistoryFiles (TimeLineID begin, TimeLineID end)
 
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)
 
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)

Definition at line 222 of file timeline.c.

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

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

223 {
224  char path[MAXPGPATH];
225  char histfname[MAXFNAMELEN];
226  FILE *fd;
227 
228  /* Timeline 1 does not have a history file, so no need to check */
229  if (probeTLI == 1)
230  return false;
231 
233  {
234  TLHistoryFileName(histfname, probeTLI);
235  RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
236  }
237  else
238  TLHistoryFilePath(path, probeTLI);
239 
240  fd = AllocateFile(path, "r");
241  if (fd != NULL)
242  {
243  FreeFile(fd);
244  return true;
245  }
246  else
247  {
248  if (errno != ENOENT)
249  ereport(FATAL,
251  errmsg("could not open file \"%s\": %m", path)));
252  return false;
253  }
254 }
bool ArchiveRecoveryRequested
Definition: xlog.c:266
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition: xlogarchive.c:53
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
#define TLHistoryFileName(fname, tli)
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2322
#define MAXFNAMELEN
#define ereport(elevel,...)
Definition: elog.h:144
int FreeFile(FILE *file)
Definition: fd.c:2521
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define TLHistoryFilePath(path, tli)

◆ findNewestTimeLine()

TimeLineID findNewestTimeLine ( TimeLineID  startTLI)

Definition at line 264 of file timeline.c.

References existsTimeLineHistory().

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

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

◆ readTimeLineHistory()

List* readTimeLineHistory ( TimeLineID  targetTLI)

Definition at line 76 of file timeline.c.

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

Referenced by AddWALInfoToBackupManifest(), rescanLatestTimeLine(), StartReplication(), WaitForWALToBecomeAvailable(), XLogFileReadAnyTLI(), XLogReadDetermineTimeline(), and XLogSendPhysical().

77 {
78  List *result;
79  char path[MAXPGPATH];
80  char histfname[MAXFNAMELEN];
81  FILE *fd;
82  TimeLineHistoryEntry *entry;
83  TimeLineID lasttli = 0;
84  XLogRecPtr prevend;
85  bool fromArchive = false;
86 
87  /* Timeline 1 does not have a history file, so no need to check */
88  if (targetTLI == 1)
89  {
91  entry->tli = targetTLI;
92  entry->begin = entry->end = InvalidXLogRecPtr;
93  return list_make1(entry);
94  }
95 
97  {
98  TLHistoryFileName(histfname, targetTLI);
99  fromArchive =
100  RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
101  }
102  else
103  TLHistoryFilePath(path, targetTLI);
104 
105  fd = AllocateFile(path, "r");
106  if (fd == NULL)
107  {
108  if (errno != ENOENT)
109  ereport(FATAL,
111  errmsg("could not open file \"%s\": %m", path)));
112  /* Not there, so assume no parents */
113  entry = (TimeLineHistoryEntry *) palloc(sizeof(TimeLineHistoryEntry));
114  entry->tli = targetTLI;
115  entry->begin = entry->end = InvalidXLogRecPtr;
116  return list_make1(entry);
117  }
118 
119  result = NIL;
120 
121  /*
122  * Parse the file...
123  */
124  prevend = InvalidXLogRecPtr;
125  for (;;)
126  {
127  char fline[MAXPGPATH];
128  char *res;
129  char *ptr;
130  TimeLineID tli;
131  uint32 switchpoint_hi;
132  uint32 switchpoint_lo;
133  int nfields;
134 
136  res = fgets(fline, sizeof(fline), fd);
138  if (res == NULL)
139  {
140  if (ferror(fd))
141  ereport(ERROR,
143  errmsg("could not read file \"%s\": %m", path)));
144 
145  break;
146  }
147 
148  /* skip leading whitespace and check for # comment */
149  for (ptr = fline; *ptr; ptr++)
150  {
151  if (!isspace((unsigned char) *ptr))
152  break;
153  }
154  if (*ptr == '\0' || *ptr == '#')
155  continue;
156 
157  nfields = sscanf(fline, "%u\t%X/%X", &tli, &switchpoint_hi, &switchpoint_lo);
158 
159  if (nfields < 1)
160  {
161  /* expect a numeric timeline ID as first field of line */
162  ereport(FATAL,
163  (errmsg("syntax error in history file: %s", fline),
164  errhint("Expected a numeric timeline ID.")));
165  }
166  if (nfields != 3)
167  ereport(FATAL,
168  (errmsg("syntax error in history file: %s", fline),
169  errhint("Expected a write-ahead log switchpoint location.")));
170 
171  if (result && tli <= lasttli)
172  ereport(FATAL,
173  (errmsg("invalid data in history file: %s", fline),
174  errhint("Timeline IDs must be in increasing sequence.")));
175 
176  lasttli = tli;
177 
178  entry = (TimeLineHistoryEntry *) palloc(sizeof(TimeLineHistoryEntry));
179  entry->tli = tli;
180  entry->begin = prevend;
181  entry->end = ((uint64) (switchpoint_hi)) << 32 | (uint64) switchpoint_lo;
182  prevend = entry->end;
183 
184  /* Build list with newest item first */
185  result = lcons(entry, result);
186 
187  /* we ignore the remainder of each line */
188  }
189 
190  FreeFile(fd);
191 
192  if (result && targetTLI <= lasttli)
193  ereport(FATAL,
194  (errmsg("invalid data in history file \"%s\"", path),
195  errhint("Timeline IDs must be less than child timeline's ID.")));
196 
197  /*
198  * Create one more entry for the "tip" of the timeline, which has no entry
199  * in the history file.
200  */
201  entry = (TimeLineHistoryEntry *) palloc(sizeof(TimeLineHistoryEntry));
202  entry->tli = targetTLI;
203  entry->begin = prevend;
204  entry->end = InvalidXLogRecPtr;
205 
206  result = lcons(entry, result);
207 
208  /*
209  * If the history file was fetched from archive, save it in pg_wal for
210  * future reference.
211  */
212  if (fromArchive)
213  KeepFileRestoredFromArchive(path, histfname);
214 
215  return result;
216 }
bool ArchiveRecoveryRequested
Definition: xlog.c:266
#define NIL
Definition: pg_list.h:65
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
int errhint(const char *fmt,...)
Definition: elog.c:1068
uint32 TimeLineID
Definition: xlogdefs.h:52
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition: xlogarchive.c:53
void KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
Definition: xlogarchive.c:380
TimeLineID tli
Definition: timeline.h:27
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define list_make1(x1)
Definition: pg_list.h:206
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
#define TLHistoryFileName(fname, tli)
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2322
unsigned int uint32
Definition: c.h:375
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1466
#define MAXFNAMELEN
#define ereport(elevel,...)
Definition: elog.h:144
List * lcons(void *datum, List *list)
Definition: list.c:453
XLogRecPtr end
Definition: timeline.h:29
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1442
int FreeFile(FILE *file)
Definition: fd.c:2521
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:821
XLogRecPtr begin
Definition: timeline.h:28
Definition: pg_list.h:50
#define TLHistoryFilePath(path, tli)

◆ restoreTimeLineHistoryFiles()

void restoreTimeLineHistoryFiles ( TimeLineID  begin,
TimeLineID  end 
)

Definition at line 50 of file timeline.c.

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

Referenced by rescanLatestTimeLine(), and StartupXLOG().

51 {
52  char path[MAXPGPATH];
53  char histfname[MAXFNAMELEN];
54  TimeLineID tli;
55 
56  for (tli = begin; tli < end; tli++)
57  {
58  if (tli == 1)
59  continue;
60 
61  TLHistoryFileName(histfname, tli);
62  if (RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false))
63  KeepFileRestoredFromArchive(path, histfname);
64  }
65 }
uint32 TimeLineID
Definition: xlogdefs.h:52
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition: xlogarchive.c:53
void KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
Definition: xlogarchive.c:380
#define MAXPGPATH
#define TLHistoryFileName(fname, tli)
#define MAXFNAMELEN

◆ tliInHistory()

bool tliInHistory ( TimeLineID  tli,
List expectedTLEs 
)

Definition at line 534 of file timeline.c.

References lfirst.

Referenced by checkTimeLineSwitch(), and ReadRecord().

535 {
536  ListCell *cell;
537 
538  foreach(cell, expectedTLEs)
539  {
540  if (((TimeLineHistoryEntry *) lfirst(cell))->tli == tli)
541  return true;
542  }
543 
544  return false;
545 }
#define lfirst(lc)
Definition: pg_list.h:169

◆ tliOfPointInHistory()

TimeLineID tliOfPointInHistory ( XLogRecPtr  ptr,
List history 
)

Definition at line 552 of file timeline.c.

References TimeLineHistoryEntry::begin, elog, TimeLineHistoryEntry::end, ERROR, lfirst, TimeLineHistoryEntry::tli, and XLogRecPtrIsInvalid.

Referenced by StartupXLOG(), WaitForWALToBecomeAvailable(), and XLogReadDetermineTimeline().

553 {
554  ListCell *cell;
555 
556  foreach(cell, history)
557  {
559 
560  if ((XLogRecPtrIsInvalid(tle->begin) || tle->begin <= ptr) &&
561  (XLogRecPtrIsInvalid(tle->end) || ptr < tle->end))
562  {
563  /* found it */
564  return tle->tli;
565  }
566  }
567 
568  /* shouldn't happen. */
569  elog(ERROR, "timeline history was not contiguous");
570  return 0; /* keep compiler quiet */
571 }
TimeLineID tli
Definition: timeline.h:27
#define ERROR
Definition: elog.h:43
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
XLogRecPtr end
Definition: timeline.h:29
#define lfirst(lc)
Definition: pg_list.h:169
XLogRecPtr begin
Definition: timeline.h:28
#define elog(elevel,...)
Definition: elog.h:214

◆ tliSwitchPoint()

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

Definition at line 580 of file timeline.c.

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

Referenced by StartReplication(), StartupXLOG(), XLogReadDetermineTimeline(), and XLogSendPhysical().

581 {
582  ListCell *cell;
583 
584  if (nextTLI)
585  *nextTLI = 0;
586  foreach(cell, history)
587  {
589 
590  if (tle->tli == tli)
591  return tle->end;
592  if (nextTLI)
593  *nextTLI = tle->tli;
594  }
595 
596  ereport(ERROR,
597  (errmsg("requested timeline %u is not in this server's history",
598  tli)));
599  return InvalidXLogRecPtr; /* keep compiler quiet */
600 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
TimeLineID tli
Definition: timeline.h:27
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
XLogRecPtr end
Definition: timeline.h:29
#define lfirst(lc)
Definition: pg_list.h:169
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ writeTimeLineHistory()

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

Definition at line 304 of file timeline.c.

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

Referenced by StartupXLOG().

306 {
307  char path[MAXPGPATH];
308  char tmppath[MAXPGPATH];
309  char histfname[MAXFNAMELEN];
310  char buffer[BLCKSZ];
311  int srcfd;
312  int fd;
313  int nbytes;
314 
315  Assert(newTLI > parentTLI); /* else bad selection of newTLI */
316 
317  /*
318  * Write into a temp file name.
319  */
320  snprintf(tmppath, MAXPGPATH, XLOGDIR "/xlogtemp.%d", (int) getpid());
321 
322  unlink(tmppath);
323 
324  /* do not use get_sync_bit() here --- want to fsync only at end of fill */
325  fd = OpenTransientFile(tmppath, O_RDWR | O_CREAT | O_EXCL);
326  if (fd < 0)
327  ereport(ERROR,
329  errmsg("could not create file \"%s\": %m", tmppath)));
330 
331  /*
332  * If a history file exists for the parent, copy it verbatim
333  */
335  {
336  TLHistoryFileName(histfname, parentTLI);
337  RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
338  }
339  else
340  TLHistoryFilePath(path, parentTLI);
341 
342  srcfd = OpenTransientFile(path, O_RDONLY);
343  if (srcfd < 0)
344  {
345  if (errno != ENOENT)
346  ereport(ERROR,
348  errmsg("could not open file \"%s\": %m", path)));
349  /* Not there, so assume parent has no parents */
350  }
351  else
352  {
353  for (;;)
354  {
355  errno = 0;
357  nbytes = (int) read(srcfd, buffer, sizeof(buffer));
359  if (nbytes < 0 || errno != 0)
360  ereport(ERROR,
362  errmsg("could not read file \"%s\": %m", path)));
363  if (nbytes == 0)
364  break;
365  errno = 0;
367  if ((int) write(fd, buffer, nbytes) != nbytes)
368  {
369  int save_errno = errno;
370 
371  /*
372  * If we fail to make the file, delete it to release disk
373  * space
374  */
375  unlink(tmppath);
376 
377  /*
378  * if write didn't set errno, assume problem is no disk space
379  */
380  errno = save_errno ? save_errno : ENOSPC;
381 
382  ereport(ERROR,
384  errmsg("could not write to file \"%s\": %m", tmppath)));
385  }
387  }
388 
389  if (CloseTransientFile(srcfd) != 0)
390  ereport(ERROR,
392  errmsg("could not close file \"%s\": %m", path)));
393  }
394 
395  /*
396  * Append one line with the details of this timeline split.
397  *
398  * If we did have a parent file, insert an extra newline just in case the
399  * parent file failed to end with one.
400  */
401  snprintf(buffer, sizeof(buffer),
402  "%s%u\t%X/%X\t%s\n",
403  (srcfd < 0) ? "" : "\n",
404  parentTLI,
405  (uint32) (switchpoint >> 32), (uint32) (switchpoint),
406  reason);
407 
408  nbytes = strlen(buffer);
409  errno = 0;
411  if ((int) write(fd, buffer, nbytes) != nbytes)
412  {
413  int save_errno = errno;
414 
415  /*
416  * If we fail to make the file, delete it to release disk space
417  */
418  unlink(tmppath);
419  /* if write didn't set errno, assume problem is no disk space */
420  errno = save_errno ? save_errno : ENOSPC;
421 
422  ereport(ERROR,
424  errmsg("could not write to file \"%s\": %m", tmppath)));
425  }
427 
429  if (pg_fsync(fd) != 0)
432  errmsg("could not fsync file \"%s\": %m", tmppath)));
434 
435  if (CloseTransientFile(fd) != 0)
436  ereport(ERROR,
438  errmsg("could not close file \"%s\": %m", tmppath)));
439 
440  /*
441  * Now move the completed history file into place with its final name.
442  */
443  TLHistoryFilePath(path, newTLI);
444 
445  /*
446  * Perform the rename using link if available, paranoidly trying to avoid
447  * overwriting an existing file (there shouldn't be one).
448  */
449  durable_rename_excl(tmppath, path, ERROR);
450 
451  /* The history file can be archived immediately. */
452  if (XLogArchivingActive())
453  {
454  TLHistoryFileName(histfname, newTLI);
455  XLogArchiveNotify(histfname);
456  }
457 }
bool ArchiveRecoveryRequested
Definition: xlog.c:266
#define write(a, b, c)
Definition: win32.h:14
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition: xlogarchive.c:53
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:466
int durable_rename_excl(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:786
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2372
#define MAXPGPATH
#define TLHistoryFileName(fname, tli)
int errcode_for_file_access(void)
Definition: elog.c:633
unsigned int uint32
Definition: c.h:375
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1466
int CloseTransientFile(int fd)
Definition: fd.c:2549
#define MAXFNAMELEN
#define XLOGDIR
int data_sync_elevel(int elevel)
Definition: fd.c:3603
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
#define XLogArchivingActive()
Definition: xlog.h:180
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1442
int errmsg(const char *fmt,...)
Definition: elog.c:821
int pg_fsync(int fd)
Definition: fd.c:346
#define snprintf
Definition: port.h:215
#define read(a, b, c)
Definition: win32.h:13
#define TLHistoryFilePath(path, tli)

◆ writeTimeLineHistoryFile()

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

Definition at line 467 of file timeline.c.

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

Referenced by WalRcvFetchTimeLineHistoryFiles().

468 {
469  char path[MAXPGPATH];
470  char tmppath[MAXPGPATH];
471  int fd;
472 
473  /*
474  * Write into a temp file name.
475  */
476  snprintf(tmppath, MAXPGPATH, XLOGDIR "/xlogtemp.%d", (int) getpid());
477 
478  unlink(tmppath);
479 
480  /* do not use get_sync_bit() here --- want to fsync only at end of fill */
481  fd = OpenTransientFile(tmppath, O_RDWR | O_CREAT | O_EXCL);
482  if (fd < 0)
483  ereport(ERROR,
485  errmsg("could not create file \"%s\": %m", tmppath)));
486 
487  errno = 0;
489  if ((int) write(fd, content, size) != size)
490  {
491  int save_errno = errno;
492 
493  /*
494  * If we fail to make the file, delete it to release disk space
495  */
496  unlink(tmppath);
497  /* if write didn't set errno, assume problem is no disk space */
498  errno = save_errno ? save_errno : ENOSPC;
499 
500  ereport(ERROR,
502  errmsg("could not write to file \"%s\": %m", tmppath)));
503  }
505 
507  if (pg_fsync(fd) != 0)
510  errmsg("could not fsync file \"%s\": %m", tmppath)));
512 
513  if (CloseTransientFile(fd) != 0)
514  ereport(ERROR,
516  errmsg("could not close file \"%s\": %m", tmppath)));
517 
518  /*
519  * Now move the completed history file into place with its final name.
520  */
521  TLHistoryFilePath(path, tli);
522 
523  /*
524  * Perform the rename using link if available, paranoidly trying to avoid
525  * overwriting an existing file (there shouldn't be one).
526  */
527  durable_rename_excl(tmppath, path, ERROR);
528 }
#define write(a, b, c)
Definition: win32.h:14
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int durable_rename_excl(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:786
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2372
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:633
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1466
int CloseTransientFile(int fd)
Definition: fd.c:2549
#define XLOGDIR
int data_sync_elevel(int elevel)
Definition: fd.c:3603
#define ereport(elevel,...)
Definition: elog.h:144
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1442
int errmsg(const char *fmt,...)
Definition: elog.c:821
int pg_fsync(int fd)
Definition: fd.c:346
#define snprintf
Definition: port.h:215
#define TLHistoryFilePath(path, tli)