PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
walsummary.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include "access/xlog_internal.h"
#include "backup/walsummary.h"
#include "common/int.h"
#include "utils/wait_event.h"
Include dependency graph for walsummary.c:

Go to the source code of this file.

Functions

static bool IsWalSummaryFilename (char *filename)
 
static int ListComparatorForWalSummaryFiles (const ListCell *a, const ListCell *b)
 
ListGetWalSummaries (TimeLineID tli, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
 
ListFilterWalSummaries (List *wslist, TimeLineID tli, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
 
bool WalSummariesAreComplete (List *wslist, XLogRecPtr start_lsn, XLogRecPtr end_lsn, XLogRecPtr *missing_lsn)
 
File OpenWalSummaryFile (WalSummaryFile *ws, bool missing_ok)
 
void RemoveWalSummaryIfOlderThan (WalSummaryFile *ws, time_t cutoff_time)
 
int ReadWalSummary (void *wal_summary_io, void *data, int length)
 
int WriteWalSummary (void *wal_summary_io, void *data, int length)
 
void ReportWalSummaryError (void *callback_arg, char *fmt,...)
 

Function Documentation

◆ FilterWalSummaries()

List * FilterWalSummaries ( List wslist,
TimeLineID  tli,
XLogRecPtr  start_lsn,
XLogRecPtr  end_lsn 
)

Definition at line 100 of file walsummary.c.

102{
103 List *result = NIL;
104 ListCell *lc;
105
106 /* Loop over input. */
107 foreach(lc, wslist)
108 {
109 WalSummaryFile *ws = lfirst(lc);
110
111 /* Skip if it doesn't match the filter criteria. */
112 if (tli != 0 && tli != ws->tli)
113 continue;
114 if (!XLogRecPtrIsInvalid(start_lsn) && start_lsn > ws->end_lsn)
115 continue;
116 if (!XLogRecPtrIsInvalid(end_lsn) && end_lsn < ws->start_lsn)
117 continue;
118
119 /* Add it to the result list. */
120 result = lappend(result, ws);
121 }
122
123 return result;
124}
List * lappend(List *list, void *datum)
Definition: list.c:339
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54
XLogRecPtr end_lsn
Definition: walsummary.h:30
TimeLineID tli
Definition: walsummary.h:31
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29

References WalSummaryFile::end_lsn, lappend(), lfirst, NIL, WalSummaryFile::tli, and XLogRecPtrIsInvalid.

Referenced by PrepareForIncrementalBackup().

◆ GetWalSummaries()

List * GetWalSummaries ( TimeLineID  tli,
XLogRecPtr  start_lsn,
XLogRecPtr  end_lsn 
)

Definition at line 43 of file walsummary.c.

44{
45 DIR *sdir;
46 struct dirent *dent;
47 List *result = NIL;
48
49 sdir = AllocateDir(XLOGDIR "/summaries");
50 while ((dent = ReadDir(sdir, XLOGDIR "/summaries")) != NULL)
51 {
53 uint32 tmp[5];
54 TimeLineID file_tli;
55 XLogRecPtr file_start_lsn;
56 XLogRecPtr file_end_lsn;
57
58 /* Decode filename, or skip if it's not in the expected format. */
59 if (!IsWalSummaryFilename(dent->d_name))
60 continue;
61 sscanf(dent->d_name, "%08X%08X%08X%08X%08X",
62 &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4]);
63 file_tli = tmp[0];
64 file_start_lsn = ((uint64) tmp[1]) << 32 | tmp[2];
65 file_end_lsn = ((uint64) tmp[3]) << 32 | tmp[4];
66
67 /* Skip if it doesn't match the filter criteria. */
68 if (tli != 0 && tli != file_tli)
69 continue;
70 if (!XLogRecPtrIsInvalid(start_lsn) && start_lsn >= file_end_lsn)
71 continue;
72 if (!XLogRecPtrIsInvalid(end_lsn) && end_lsn <= file_start_lsn)
73 continue;
74
75 /* Add it to the list. */
76 ws = palloc(sizeof(WalSummaryFile));
77 ws->tli = file_tli;
78 ws->start_lsn = file_start_lsn;
79 ws->end_lsn = file_end_lsn;
80 result = lappend(result, ws);
81 }
82 FreeDir(sdir);
83
84 return result;
85}
uint64_t uint64
Definition: c.h:486
uint32_t uint32
Definition: c.h:485
int FreeDir(DIR *dir)
Definition: fd.c:2983
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2865
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2931
void * palloc(Size size)
Definition: mcxt.c:1317
Definition: dirent.c:26
XLogRecPtr start_lsn
Definition: walsummary.h:29
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
static bool IsWalSummaryFilename(char *filename)
Definition: walsummary.c:263
#define XLOGDIR
uint64 XLogRecPtr
Definition: xlogdefs.h:21
uint32 TimeLineID
Definition: xlogdefs.h:59

References AllocateDir(), dirent::d_name, WalSummaryFile::end_lsn, FreeDir(), IsWalSummaryFilename(), lappend(), NIL, palloc(), ReadDir(), WalSummaryFile::start_lsn, WalSummaryFile::tli, XLOGDIR, and XLogRecPtrIsInvalid.

Referenced by GetOldestUnsummarizedLSN(), MaybeRemoveOldWalSummaries(), pg_available_wal_summaries(), and PrepareForIncrementalBackup().

◆ IsWalSummaryFilename()

static bool IsWalSummaryFilename ( char *  filename)
static

Definition at line 263 of file walsummary.c.

264{
265 return strspn(filename, "0123456789ABCDEF") == 40 &&
266 strcmp(filename + 40, ".summary") == 0;
267}
static char * filename
Definition: pg_dumpall.c:119

References filename.

Referenced by GetWalSummaries().

◆ ListComparatorForWalSummaryFiles()

static int ListComparatorForWalSummaryFiles ( const ListCell a,
const ListCell b 
)
static

Definition at line 347 of file walsummary.c.

348{
349 WalSummaryFile *ws1 = lfirst(a);
350 WalSummaryFile *ws2 = lfirst(b);
351
352 return pg_cmp_u64(ws1->start_lsn, ws2->start_lsn);
353}
static int pg_cmp_u64(uint64 a, uint64 b)
Definition: int.h:664
int b
Definition: isn.c:69
int a
Definition: isn.c:68

References a, b, lfirst, pg_cmp_u64(), and WalSummaryFile::start_lsn.

Referenced by WalSummariesAreComplete().

◆ OpenWalSummaryFile()

File OpenWalSummaryFile ( WalSummaryFile ws,
bool  missing_ok 
)

Definition at line 205 of file walsummary.c.

206{
207 char path[MAXPGPATH];
208 File file;
209
210 snprintf(path, MAXPGPATH,
211 XLOGDIR "/summaries/%08X%08X%08X%08X%08X.summary",
212 ws->tli,
215
216 file = PathNameOpenFile(path, O_RDONLY);
217 if (file < 0 && (errno != EEXIST || !missing_ok))
220 errmsg("could not open file \"%s\": %m", path)));
221
222 return file;
223}
int errcode_for_file_access(void)
Definition: elog.c:876
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1574
int File
Definition: fd.h:51
#define MAXPGPATH
#define snprintf
Definition: port.h:238
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43

References WalSummaryFile::end_lsn, ereport, errcode_for_file_access(), errmsg(), ERROR, LSN_FORMAT_ARGS, MAXPGPATH, PathNameOpenFile(), snprintf, WalSummaryFile::start_lsn, WalSummaryFile::tli, and XLOGDIR.

Referenced by pg_wal_summary_contents(), and PrepareForIncrementalBackup().

◆ ReadWalSummary()

int ReadWalSummary ( void *  wal_summary_io,
void *  data,
int  length 
)

Definition at line 273 of file walsummary.c.

274{
275 WalSummaryIO *io = wal_summary_io;
276 int nbytes;
277
278 nbytes = FileRead(io->file, data, length, io->filepos,
279 WAIT_EVENT_WAL_SUMMARY_READ);
280 if (nbytes < 0)
283 errmsg("could not read file \"%s\": %m",
284 FilePathName(io->file))));
285
286 io->filepos += nbytes;
287 return nbytes;
288}
char * FilePathName(File file)
Definition: fd.c:2483
static ssize_t FileRead(File file, void *buffer, size_t amount, off_t offset, uint32 wait_event_info)
Definition: fd.h:196
const void * data
off_t filepos
Definition: walsummary.h:24

References data, ereport, errcode_for_file_access(), errmsg(), ERROR, WalSummaryIO::file, FilePathName(), WalSummaryIO::filepos, and FileRead().

Referenced by pg_wal_summary_contents(), and PrepareForIncrementalBackup().

◆ RemoveWalSummaryIfOlderThan()

void RemoveWalSummaryIfOlderThan ( WalSummaryFile ws,
time_t  cutoff_time 
)

Definition at line 230 of file walsummary.c.

231{
232 char path[MAXPGPATH];
233 struct stat statbuf;
234
235 snprintf(path, MAXPGPATH,
236 XLOGDIR "/summaries/%08X%08X%08X%08X%08X.summary",
237 ws->tli,
240
241 if (lstat(path, &statbuf) != 0)
242 {
243 if (errno == ENOENT)
244 return;
247 errmsg("could not stat file \"%s\": %m", path)));
248 }
249 if (statbuf.st_mtime >= cutoff_time)
250 return;
251 if (unlink(path) != 0)
254 errmsg("could not stat file \"%s\": %m", path)));
256 (errmsg_internal("removing file \"%s\"", path)));
257}
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define DEBUG2
Definition: elog.h:29
#define lstat(path, sb)
Definition: win32_port.h:285

References DEBUG2, WalSummaryFile::end_lsn, ereport, errcode_for_file_access(), errmsg(), errmsg_internal(), ERROR, LSN_FORMAT_ARGS, lstat, MAXPGPATH, snprintf, stat::st_mtime, WalSummaryFile::start_lsn, WalSummaryFile::tli, and XLOGDIR.

Referenced by MaybeRemoveOldWalSummaries().

◆ ReportWalSummaryError()

void ReportWalSummaryError ( void *  callback_arg,
char *  fmt,
  ... 
)

Definition at line 322 of file walsummary.c.

323{
325 va_list ap;
326 int needed;
327
329 for (;;)
330 {
331 va_start(ap, fmt);
332 needed = appendStringInfoVA(&buf, fmt, ap);
333 va_end(ap);
334 if (needed == 0)
335 break;
336 enlargeStringInfo(&buf, needed);
337 }
340 errmsg_internal("%s", buf.data));
341}
int errcode(int sqlerrcode)
Definition: elog.c:853
static void const char * fmt
va_end(args)
va_start(args, fmt)
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
static char * buf
Definition: pg_test_fsync.c:72
int appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
Definition: stringinfo.c:136
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:286
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56

References appendStringInfoVA(), buf, enlargeStringInfo(), ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), ERROR, fmt, initStringInfo(), va_end(), and va_start().

Referenced by pg_wal_summary_contents(), and PrepareForIncrementalBackup().

◆ WalSummariesAreComplete()

bool WalSummariesAreComplete ( List wslist,
XLogRecPtr  start_lsn,
XLogRecPtr  end_lsn,
XLogRecPtr missing_lsn 
)

Definition at line 138 of file walsummary.c.

140{
141 XLogRecPtr current_lsn = start_lsn;
142 ListCell *lc;
143
144 /* Special case for empty list. */
145 if (wslist == NIL)
146 {
147 *missing_lsn = InvalidXLogRecPtr;
148 return false;
149 }
150
151 /* Make a private copy of the list and sort it by start LSN. */
152 wslist = list_copy(wslist);
154
155 /*
156 * Consider summary files in order of increasing start_lsn, advancing the
157 * known-summarized range from start_lsn toward end_lsn.
158 *
159 * Normally, the summary files should cover non-overlapping WAL ranges,
160 * but this algorithm is intended to be correct even in case of overlap.
161 */
162 foreach(lc, wslist)
163 {
164 WalSummaryFile *ws = lfirst(lc);
165
166 if (ws->start_lsn > current_lsn)
167 {
168 /* We found a gap. */
169 break;
170 }
171 if (ws->end_lsn > current_lsn)
172 {
173 /*
174 * Next summary extends beyond end of previous summary, so extend
175 * the end of the range known to be summarized.
176 */
177 current_lsn = ws->end_lsn;
178
179 /*
180 * If the range we know to be summarized has reached the required
181 * end LSN, we have proved completeness.
182 */
183 if (current_lsn >= end_lsn)
184 return true;
185 }
186 }
187
188 /*
189 * We either ran out of summary files without reaching the end LSN, or we
190 * hit a gap in the sequence that resulted in us bailing out of the loop
191 * above.
192 */
193 *missing_lsn = current_lsn;
194 return false;
195}
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1674
List * list_copy(const List *oldlist)
Definition: list.c:1573
static int ListComparatorForWalSummaryFiles(const ListCell *a, const ListCell *b)
Definition: walsummary.c:347
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28

References WalSummaryFile::end_lsn, InvalidXLogRecPtr, lfirst, list_copy(), list_sort(), ListComparatorForWalSummaryFiles(), NIL, and WalSummaryFile::start_lsn.

Referenced by PrepareForIncrementalBackup().

◆ WriteWalSummary()

int WriteWalSummary ( void *  wal_summary_io,
void *  data,
int  length 
)

Definition at line 294 of file walsummary.c.

295{
296 WalSummaryIO *io = wal_summary_io;
297 int nbytes;
298
299 nbytes = FileWrite(io->file, data, length, io->filepos,
300 WAIT_EVENT_WAL_SUMMARY_WRITE);
301 if (nbytes < 0)
304 errmsg("could not write file \"%s\": %m",
305 FilePathName(io->file))));
306 if (nbytes != length)
309 errmsg("could not write file \"%s\": wrote only %d of %d bytes at offset %u",
310 FilePathName(io->file), nbytes,
311 length, (unsigned) io->filepos),
312 errhint("Check free disk space.")));
313
314 io->filepos += nbytes;
315 return nbytes;
316}
int errhint(const char *fmt,...)
Definition: elog.c:1317
static ssize_t FileWrite(File file, const void *buffer, size_t amount, off_t offset, uint32 wait_event_info)
Definition: fd.h:208

References data, ereport, errcode_for_file_access(), errhint(), errmsg(), ERROR, WalSummaryIO::file, FilePathName(), WalSummaryIO::filepos, and FileWrite().

Referenced by SummarizeWAL().