diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 0bca449eacf..b4fd8395b72 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1533,30 +1533,50 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata, /* * If this was an xlog-switch, it's not enough to write the switch record, - * we also have to consume all the remaining space in the WAL segment. We - * have already reserved it for us, but we still need to make sure it's - * allocated and zeroed in the WAL buffers so that when the caller (or - * someone else) does XLogWrite(), it can really write out all the zeros. + * we also have to consume all the remaining space in the WAL segment. We + * have already reserved that space, but we need to actually fill it. */ if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0) { /* An xlog-switch record doesn't contain any data besides the header */ Assert(write_len == SizeOfXLogRecord); - /* - * We do this one page at a time, to make sure we don't deadlock - * against ourselves if wal_buffers < wal_segment_size. - */ + /* Assert that we did reserve the right amount of space */ Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0); - /* Use up all the remaining space on the first page */ + /* Use up all the remaining space on the current page */ CurrPos += freespace; + /* + * Cause all remaining pages in the segment to be flushed, leaving the + * XLog position where it should be, at the start of the next segment. + * We do this one page at a time, to make sure we don't deadlock + * against ourselves if wal_buffers < wal_segment_size. + */ while (CurrPos < EndPos) { - /* initialize the next page (if not initialized already) */ - WALInsertLockUpdateInsertingAt(CurrPos); - AdvanceXLInsertBuffer(CurrPos, false); + /* + * The minimal action to flush the page would be to call + * WALInsertLockUpdateInsertingAt(CurrPos) followed by + * AdvanceXLInsertBuffer(...). The page would be left initialized + * mostly to zeros, except for the page header (always the short + * variant, as this is never a segment's first page). + * + * The large vistas of zeros are good for compressibility, but the + * headers interrupting them every XLOG_BLCKSZ (with values that + * differ from page to page) are not. The effect varies with + * compression tool, but bzip2 for instance compresses about an + * order of magnitude worse if those headers are left in place. + * + * Rather than complicating AdvanceXLInsertBuffer itself (which is + * called in heavily-loaded circumstances as well as this lightly- + * loaded one) with variant behavior, we just use GetXLogBuffer + * (which itself calls the two methods we need) to get the pointer + * and zero most of the page. Then we just zero the page header. + */ + currpos = GetXLogBuffer(CurrPos); + MemSet(currpos, 0, SizeOfXLogShortPHD); + CurrPos += XLOG_BLCKSZ; } } |