endptr = XLogCtl->xlblocks[idx];
if (expectedEndPtr != endptr)
{
+ XLogRecPtr initializedUpto;
+
/*
- * Let others know that we're finished inserting the record up to the
- * page boundary.
+ * Before calling AdvanceXLInsertBuffer(), which can block, let others
+ * know how far we're finished with inserting the record.
+ *
+ * NB: If 'ptr' points to just after the page header, advertise a
+ * position at the beginning of the page rather than 'ptr' itself. If
+ * there are no other insertions running, someone might try to flush
+ * up to our advertised location. If we advertised a position after
+ * the page header, someone might try to flush the page header, even
+ * though page might actually not be initialized yet. As the first
+ * inserter on the page, we are effectively responsible for making
+ * sure that it's initialized, before we let insertingAt to move past
+ * the page header.
*/
- WALInsertLockUpdateInsertingAt(expectedEndPtr - XLOG_BLCKSZ);
+ if (ptr % XLOG_BLCKSZ == SizeOfXLogShortPHD &&
+ ptr % XLOG_SEG_SIZE > XLOG_BLCKSZ)
+ initializedUpto = ptr - SizeOfXLogShortPHD;
+ else if (ptr % XLOG_BLCKSZ == SizeOfXLogLongPHD &&
+ ptr % XLOG_SEG_SIZE < XLOG_BLCKSZ)
+ initializedUpto = ptr - SizeOfXLogLongPHD;
+ else
+ initializedUpto = ptr;
+
+ WALInsertLockUpdateInsertingAt(initializedUpto);
AdvanceXLInsertBuffer(ptr, false);
endptr = XLogCtl->xlblocks[idx];