Commit 58536626 authored by Alvaro Herrera's avatar Alvaro Herrera

Reduce the size of memory allocations by lazy vacuum when processing a small

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: ----------------------------------------------------------------------
parent 48f7e643
...@@ -11,10 +11,12 @@ ...@@ -11,10 +11,12 @@
* on the number of tuples and pages we will keep track of at once. * 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 * 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. * 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 * with an upper limit that depends on table size (this limit ensures we don't
* perform a pass of index cleanup and page compaction, then resume the heap * allocate a huge area uselessly for vacuuming small tables). If the array
* scan with an empty TID 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, * 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 * since that's the most the free space map will be willing to remember
...@@ -36,7 +38,7 @@ ...@@ -36,7 +38,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.99 2007/09/24 03:12:23 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.100 2007/09/24 03:52:55 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -68,6 +70,12 @@ ...@@ -68,6 +70,12 @@
#define REL_TRUNCATE_MINIMUM 1000 #define REL_TRUNCATE_MINIMUM 1000
#define REL_TRUNCATE_FRACTION 16 #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 typedef struct LVRelStats
{ {
...@@ -1001,6 +1009,11 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks) ...@@ -1001,6 +1009,11 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData); maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData);
maxtuples = Min(maxtuples, INT_MAX); maxtuples = Min(maxtuples, INT_MAX);
maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData)); maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));
/* curious coding here to ensure the multiplication can't overflow */
if ((BlockNumber) (maxtuples / LAZY_ALLOC_TUPLES) > relblocks)
maxtuples = relblocks * LAZY_ALLOC_TUPLES;
/* stay sane if small maintenance_work_mem */ /* stay sane if small maintenance_work_mem */
maxtuples = Max(maxtuples, MaxHeapTuplesPerPage); maxtuples = Max(maxtuples, MaxHeapTuplesPerPage);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment