Reduce the size of memory allocations by lazy vacuum when processing a small
authorAlvaro Herrera <[email protected]>
Mon, 24 Sep 2007 03:53:06 +0000 (03:53 +0000)
committerAlvaro Herrera <[email protected]>
Mon, 24 Sep 2007 03:53:06 +0000 (03:53 +0000)
table, by allocating just enough for a hardcoded number of dead tuples per
page.  The current estimate is 200 dead tuples per page.

Per reports from Jeff Amiel, Erik Jones and Marko Kreen, and subsequent
discussion.
CVS: ----------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS:  commands/vacuumlazy.c
CVS: ----------------------------------------------------------------------

src/backend/commands/vacuumlazy.c

index 9d67a842f6d9edaebd18e4b1fb20fe50c8ebc5b3..9c56945b2fe527603448b605ae4d0bfa702feb1b 100644 (file)
  * on the number of tuples and pages we will keep track of at once.
  *
  * We are willing to use at most maintenance_work_mem memory space to keep
- * track of dead tuples.  We initially allocate an array of TIDs of that size.
- * If the array threatens to overflow, we suspend the heap scan phase and
- * perform a pass of index cleanup and page compaction, then resume the heap
- * scan with an empty TID array.
+ * track of dead tuples.  We initially allocate an array of TIDs of that size,
+ * with an upper limit that depends on table size (this limit ensures we don't
+ * allocate a huge area uselessly for vacuuming small tables).  If the array
+ * threatens to overflow, we suspend the heap scan phase and perform a pass of
+ * index cleanup and page compaction, then resume the heap scan with an empty
+ * TID array.
  *
  * We can limit the storage for page free space to MaxFSMPages entries,
  * since that's the most the free space map will be willing to remember
 #define REL_TRUNCATE_MINIMUM   1000
 #define REL_TRUNCATE_FRACTION  16
 
+/*
+ * Guesstimation of number of dead tuples per page.  This is used to
+ * provide an upper limit to memory allocated when vacuuming small
+ * tables.
+ */
+#define LAZY_ALLOC_TUPLES              200
 
 typedef struct LVRelStats
 {
@@ -934,6 +942,10 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
        /* stay sane if small maintenance_work_mem */
        maxtuples = Max(maxtuples, MaxHeapTuplesPerPage);
 
+       /* curious coding here to ensure the multiplication can't overflow */
+       if ((BlockNumber) (maxtuples / LAZY_ALLOC_TUPLES) > relblocks)
+               maxtuples = relblocks * LAZY_ALLOC_TUPLES;
+
        vacrelstats->num_dead_tuples = 0;
        vacrelstats->max_dead_tuples = (int) maxtuples;
        vacrelstats->dead_tuples = (ItemPointer)