diff options
Diffstat (limited to 'src/backend/access/transam')
-rw-r--r-- | src/backend/access/transam/README | 2 | ||||
-rw-r--r-- | src/backend/access/transam/xlog.c | 60 |
2 files changed, 35 insertions, 27 deletions
diff --git a/src/backend/access/transam/README b/src/backend/access/transam/README index c0c9aeaa318..57b4b9d08b3 100644 --- a/src/backend/access/transam/README +++ b/src/backend/access/transam/README @@ -473,7 +473,7 @@ the same page, only BKP(1) would have been set. For this reason as well as the risk of deadlocking on buffer locks, it's best to design WAL records so that they reflect small atomic actions involving just one or a few pages. The current XLOG infrastructure cannot handle WAL records -involving references to more than three shared buffers, anyway. +involving references to more than four shared buffers, anyway. In the case where the WAL record contains enough information to re-generate the entire contents of a page, do *not* show that page's buffer ID in the diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9d96044cbdc..41800a46040 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -971,19 +971,6 @@ begin:; } /* - * If we backed up any full blocks and online backup is not in progress, - * mark the backup blocks as removable. This allows the WAL archiver to - * know whether it is safe to compress archived WAL data by transforming - * full-block records into the non-full-block format. - * - * Note: we could just set the flag whenever !forcePageWrites, but - * defining it like this leaves the info bit free for some potential other - * use in records without any backup blocks. - */ - if ((info & XLR_BKP_BLOCK_MASK) && !Insert->forcePageWrites) - info |= XLR_BKP_REMOVABLE; - - /* * If there isn't enough space on the current XLOG page for a record * header, advance to the next page (leaving the unused space as zeroes). */ @@ -1602,6 +1589,21 @@ AdvanceXLInsertBuffer(bool new_segment) NewPage ->xlp_pageaddr.xrecoff = NewPageEndPtr.xrecoff - XLOG_BLCKSZ; /* + * If online backup is not in progress, mark the header to indicate that + * WAL records beginning in this page have removable backup blocks. This + * allows the WAL archiver to know whether it is safe to compress archived + * WAL data by transforming full-block records into the non-full-block + * format. It is sufficient to record this at the page level because we + * force a page switch (in fact a segment switch) when starting a backup, + * so the flag will be off before any records can be written during the + * backup. At the end of a backup, the last page will be marked as all + * unsafe when perhaps only part is unsafe, but at worst the archiver + * would miss the opportunity to compress a few records. + */ + if (!Insert->forcePageWrites) + NewPage->xlp_info |= XLP_BKP_REMOVABLE; + + /* * If first page of an XLOG segment file, make it a long header. */ if ((NewPage->xlp_pageaddr.xrecoff % XLogSegSize) == 0) @@ -8850,19 +8852,6 @@ do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile) MAXPGPATH))); /* - * Force an XLOG file switch before the checkpoint, to ensure that the WAL - * segment the checkpoint is written to doesn't contain pages with old - * timeline IDs. That would otherwise happen if you called - * pg_start_backup() right after restoring from a PITR archive: the first - * WAL segment containing the startup checkpoint has pages in the - * beginning with the old timeline ID. That can cause trouble at recovery: - * we won't have a history file covering the old timeline if pg_xlog - * directory was not included in the base backup and the WAL archive was - * cleared too before starting the backup. - */ - RequestXLogSwitch(); - - /* * Mark backup active in shared memory. We must do full-page WAL writes * during an on-line backup even if not doing so at other times, because * it's quite possible for the backup dump to obtain a "torn" (partially @@ -8902,6 +8891,25 @@ do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile) { bool gotUniqueStartpoint = false; + /* + * Force an XLOG file switch before the checkpoint, to ensure that the + * WAL segment the checkpoint is written to doesn't contain pages with + * old timeline IDs. That would otherwise happen if you called + * pg_start_backup() right after restoring from a PITR archive: the + * first WAL segment containing the startup checkpoint has pages in + * the beginning with the old timeline ID. That can cause trouble at + * recovery: we won't have a history file covering the old timeline if + * pg_xlog directory was not included in the base backup and the WAL + * archive was cleared too before starting the backup. + * + * This also ensures that we have emitted a WAL page header that has + * XLP_BKP_REMOVABLE off before we emit the checkpoint record. + * Therefore, if a WAL archiver (such as pglesslog) is trying to + * compress out removable backup blocks, it won't remove any that + * occur after this point. + */ + RequestXLogSwitch(); + do { /* |