@@ -894,26 +894,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
894
894
freespace = PageGetHeapFreeSpace (page );
895
895
896
896
/* mark page all-visible, if appropriate */
897
- if (all_visible )
897
+ if (all_visible && ! all_visible_according_to_vm )
898
898
{
899
- if (!PageIsAllVisible (page ))
900
- {
901
- PageSetAllVisible (page );
902
- MarkBufferDirty (buf );
903
- visibilitymap_set (onerel , blkno , buf , InvalidXLogRecPtr ,
904
- vmbuffer , visibility_cutoff_xid );
905
- }
906
- else if (!all_visible_according_to_vm )
907
- {
908
- /*
909
- * It should never be the case that the visibility map page is
910
- * set while the page-level bit is clear, but the reverse is
911
- * allowed. Set the visibility map bit as well so that we get
912
- * back in sync.
913
- */
914
- visibilitymap_set (onerel , blkno , buf , InvalidXLogRecPtr ,
915
- vmbuffer , visibility_cutoff_xid );
916
- }
899
+ /*
900
+ * It should never be the case that the visibility map page is set
901
+ * while the page-level bit is clear, but the reverse is allowed
902
+ * (if checksums are not enabled). Regardless, set the both bits
903
+ * so that we get back in sync.
904
+ *
905
+ * NB: If the heap page is all-visible but the VM bit is not set,
906
+ * we don't need to dirty the heap page. However, if checksums are
907
+ * enabled, we do need to make sure that the heap page is dirtied
908
+ * before passing it to visibilitymap_set(), because it may be
909
+ * logged. Given that this situation should only happen in rare
910
+ * cases after a crash, it is not worth optimizing.
911
+ */
912
+ PageSetAllVisible (page );
913
+ MarkBufferDirty (buf );
914
+ visibilitymap_set (onerel , blkno , buf , InvalidXLogRecPtr ,
915
+ vmbuffer , visibility_cutoff_xid );
917
916
}
918
917
919
918
/*
@@ -1138,6 +1137,14 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
1138
1137
1139
1138
PageRepairFragmentation (page );
1140
1139
1140
+ /*
1141
+ * Mark buffer dirty before we write WAL.
1142
+ *
1143
+ * If checksums are enabled, visibilitymap_set() may log the heap page, so
1144
+ * we must mark heap buffer dirty before calling visibilitymap_set().
1145
+ */
1146
+ MarkBufferDirty (buffer );
1147
+
1141
1148
/*
1142
1149
* Now that we have removed the dead tuples from the page, once again check
1143
1150
* if the page has become all-visible.
@@ -1151,8 +1158,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
1151
1158
visibility_cutoff_xid );
1152
1159
}
1153
1160
1154
- MarkBufferDirty (buffer );
1155
-
1156
1161
/* XLOG stuff */
1157
1162
if (RelationNeedsWAL (onerel ))
1158
1163
{
0 commit comments