/*
* 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;
}
}