]> granicus.if.org Git - postgresql/commitdiff
Keep heap_page_prune from marking the buffer dirty when it didn't
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Oct 2007 13:05:57 +0000 (13:05 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Oct 2007 13:05:57 +0000 (13:05 +0000)
really change anything.  Per report from Itagaki Takahiro.  Fix by
Pavan Deolasee.

src/backend/access/heap/pruneheap.c

index 5a1e82216bdfe2490d08b39941b7de90e947ea64..9723241547ff2ea1947d6c5999c6d4d6b75cbc7e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/heap/pruneheap.c,v 1.2 2007/09/21 21:25:42 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/heap/pruneheap.c,v 1.3 2007/10/24 13:05:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -146,17 +146,29 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin,
        int                             nredirected = 0;
        int                             ndead = 0;
        int                             nunused = 0;
+       bool                    page_was_full = false;
+       TransactionId   save_prune_xid;
 
        START_CRIT_SECTION();
 
        /*
-        * Mark the page as clear of prunable tuples.  If we find a tuple which
-        * may soon become prunable, we shall set the hint again.  Also clear
-        * the "page is full" flag, since there's no point in repeating the
-        * prune/defrag process until something else happens to the page.
+        * Save the current pd_prune_xid and mark the page as clear of prunable
+        * tuples. If we find a tuple which may soon become prunable, we shall set
+        * the hint again.
         */
+       save_prune_xid = ((PageHeader) page)->pd_prune_xid;
        PageClearPrunable(page);
-       PageClearFull(page);
+
+       /* 
+        * Also clear the "page is full" flag if it is set, since there's no point
+        * in repeating the prune/defrag process until something else happens to
+        * the page.
+        */
+       if (PageIsFull(page))
+       {
+               PageClearFull(page);
+               page_was_full = true;
+       }
 
        /* Scan the page */
        maxoff = PageGetMaxOffsetNumber(page);
@@ -209,10 +221,13 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin,
        else
        {
                /*
-                * If we didn't prune anything, we have nonetheless updated the
-                * pd_prune_xid field; treat this as a non-WAL-logged hint.
+                * If we didn't prune anything, but have updated either the
+                * pd_prune_xid field or the "page is full" flag, mark the buffer
+                * dirty.  This is treated as a non-WAL-logged hint.
                 */
-               SetBufferCommitInfoNeedsSave(buffer);
+               if (((PageHeader) page)->pd_prune_xid != save_prune_xid ||
+                       page_was_full)
+                       SetBufferCommitInfoNeedsSave(buffer);
        }
 
        END_CRIT_SECTION();