]> granicus.if.org Git - postgresql/commitdiff
Fix WAL-logging of setting the visibility map bit.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 13 Dec 2013 11:52:47 +0000 (13:52 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 13 Dec 2013 12:23:02 +0000 (14:23 +0200)
The operation that removes the remaining dead tuples from the page must
be WAL-logged before the setting of the VM bit. Otherwise, if you replay
the WAL to between those two records, you end up with the VM bit set, but
the dead tuples are still there.

Backpatch to 9.3, where this bug was introduced.

src/backend/commands/vacuumlazy.c

index ff6bd8e5b06e1c2de31a6bfbdb4389b81395af5c..2433325abb28fdac1710af95a2d5afa24227f59e 100644 (file)
@@ -1185,12 +1185,21 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 
        /*
         * Mark buffer dirty before we write WAL.
-        *
-        * If checksums are enabled, visibilitymap_set() may log the heap page, so
-        * we must mark heap buffer dirty before calling visibilitymap_set().
         */
        MarkBufferDirty(buffer);
 
+       /* XLOG stuff */
+       if (RelationNeedsWAL(onerel))
+       {
+               XLogRecPtr      recptr;
+
+               recptr = log_heap_clean(onerel, buffer,
+                                                               NULL, 0, NULL, 0,
+                                                               unused, uncnt,
+                                                               vacrelstats->latestRemovedXid);
+               PageSetLSN(page, recptr);
+       }
+
        /*
         * Now that we have removed the dead tuples from the page, once again
         * check if the page has become all-visible.
@@ -1204,18 +1213,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
                                                  visibility_cutoff_xid);
        }
 
-       /* XLOG stuff */
-       if (RelationNeedsWAL(onerel))
-       {
-               XLogRecPtr      recptr;
-
-               recptr = log_heap_clean(onerel, buffer,
-                                                               NULL, 0, NULL, 0,
-                                                               unused, uncnt,
-                                                               vacrelstats->latestRemovedXid);
-               PageSetLSN(page, recptr);
-       }
-
        END_CRIT_SECTION();
 
        return tupindex;