>From 4fe13d241062c3aa47ddfe3cfb967d80809aa826 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 24 Sep 2013 11:58:34 +0200
Subject: [PATCH] Use critical section when ensuring empty pages are
 initialized during vacuum.

a6370fd9 tried to fix the problem that replay of XLOG_HEAP2_VISIBLE
records can fail when unitialized page are referenced during
replay. Unfortunately the patch/I missed the fact that log_newpage()
should be used inside a critical section leading to assertion failure
during WAL replay when those are enabled while working otherwise.

Also fix the issue that pages should be marked dirty before calling
log_newpage_buffer() (check src/backend/access/transam/README for
reasons).

Both issues noticed Heikki
---
 src/backend/commands/vacuumlazy.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index bb4e03e..af7cd59 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -663,6 +663,11 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
 			/* empty pages are always all-visible */
 			if (!PageIsAllVisible(page))
 			{
+				START_CRIT_SECTION();
+
+				/* dirty page before any possible XLogInsert()s */
+				MarkBufferDirty(buf);
+
 				/*
 				 * It's possible that another backend has extended the heap,
 				 * initialized the page, and then failed to WAL-log the page
@@ -682,9 +687,9 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
 					log_newpage_buffer(buf);
 
 				PageSetAllVisible(page);
-				MarkBufferDirty(buf);
 				visibilitymap_set(onerel, blkno, buf, InvalidXLogRecPtr,
 								  vmbuffer, InvalidTransactionId);
+				END_CRIT_SECTION();
 			}
 
 			UnlockReleaseBuffer(buf);
-- 
1.8.4.21.g992c386.dirty

