diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-09-21 21:25:42 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-09-21 21:25:42 +0000 |
commit | cc59049daf78c3d351c1ec78fb319b5fdeb20d53 (patch) | |
tree | 74c6471e902926264b639164859c2ae69a3420ed /src/backend/access/heap/pruneheap.c | |
parent | 386a5d4268c7ae13510f0a40243b2277eccb6189 (diff) |
Improve handling of prune/no-prune decisions by storing a page's oldest
unpruned XMAX in its header. At the cost of 4 bytes per page, this keeps us
from performing heap_page_prune when there's no chance of pruning anything.
Seems to be necessary per Heikki's preliminary performance testing.
Diffstat (limited to 'src/backend/access/heap/pruneheap.c')
-rw-r--r-- | src/backend/access/heap/pruneheap.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index d5496689003..5a1e82216bd 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/pruneheap.c,v 1.1 2007/09/20 17:56:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/pruneheap.c,v 1.2 2007/09/21 21:25:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -63,9 +63,10 @@ heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin) /* * Let's see if we really need pruning. * - * Forget it if page is not hinted to contain something prunable + * Forget it if page is not hinted to contain something prunable that's + * older than OldestXmin. */ - if (!PageIsPrunable(dp)) + if (!PageIsPrunable(dp, OldestXmin)) return; /* @@ -93,6 +94,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin) /* * Now that we have buffer lock, get accurate information about the * page's free space, and recheck the heuristic about whether to prune. + * (We needn't recheck PageIsPrunable, since no one else could have + * pruned while we hold pin.) */ if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree) { @@ -147,7 +150,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, START_CRIT_SECTION(); /* - * Mark the page as clear of prunable tuples. If we find a tuple which + * 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. @@ -203,6 +206,14 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, PageSetLSN(BufferGetPage(buffer), recptr); } } + else + { + /* + * If we didn't prune anything, we have nonetheless updated the + * pd_prune_xid field; treat this as a non-WAL-logged hint. + */ + SetBufferCommitInfoNeedsSave(buffer); + } END_CRIT_SECTION(); @@ -392,18 +403,18 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum, case HEAPTUPLE_RECENTLY_DEAD: recent_dead = true; /* - * This tuple may soon become DEAD. Re-set the hint bit so + * This tuple may soon become DEAD. Update the hint field so * that the page is reconsidered for pruning in future. */ - PageSetPrunable(dp); + PageSetPrunable(dp, HeapTupleHeaderGetXmax(htup)); break; case HEAPTUPLE_DELETE_IN_PROGRESS: /* - * This tuple may soon become DEAD. Re-set the hint bit so + * This tuple may soon become DEAD. Update the hint field so * that the page is reconsidered for pruning in future. */ - PageSetPrunable(dp); + PageSetPrunable(dp, HeapTupleHeaderGetXmax(htup)); break; case HEAPTUPLE_LIVE: |