diff options
author | Heikki Linnakangas | 2013-10-23 11:03:54 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2013-10-23 11:24:37 +0000 |
commit | 83eb54001cb69d6ee8f0813c4e280be876823068 (patch) | |
tree | 14fb288e289dcb9c2edb95b2a7272e89913cf22a /src | |
parent | 5f1ab4610102a73c124000788585c1af2a36284b (diff) |
Fix two bugs in setting the vm bit of empty pages.
Use a critical section when setting the all-visible flag on an empty page,
and WAL-logging it. log_newpage_buffer() contains an assertion that it
must be called inside a critical section, and it's the right thing to do
when modifying a buffer anyway.
Also, the page should be marked dirty before calling log_newpage_buffer(),
per the comment in log_newpage_buffer() and src/backend/access/transam/README.
Patch by Andres Freund, in response to my report. Backpatch to 9.2, like
the patch that introduced these bugs (a6370fd9).
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/vacuumlazy.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index a6d5fc5932e..e1d6d1c9e61 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(); + + /* mark buffer dirty before writing a WAL record */ + 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); |