|
11 | 11 | * on the number of tuples and pages we will keep track of at once. |
12 | 12 | * |
13 | 13 | * We are willing to use at most maintenance_work_mem memory space to keep |
14 | | - * track of dead tuples. We initially allocate an array of TIDs of that size. |
15 | | - * If the array threatens to overflow, we suspend the heap scan phase and |
16 | | - * perform a pass of index cleanup and page compaction, then resume the heap |
17 | | - * scan with an empty TID array. |
| 14 | + * track of dead tuples. We initially allocate an array of TIDs of that size, |
| 15 | + * with an upper limit that depends on table size (this limit ensures we don't |
| 16 | + * allocate a huge area uselessly for vacuuming small tables). If the array |
| 17 | + * threatens to overflow, we suspend the heap scan phase and perform a pass of |
| 18 | + * index cleanup and page compaction, then resume the heap scan with an empty |
| 19 | + * TID array. |
18 | 20 | * |
19 | 21 | * We can limit the storage for page free space to MaxFSMPages entries, |
20 | 22 | * since that's the most the free space map will be willing to remember |
|
36 | 38 | * |
37 | 39 | * |
38 | 40 | * IDENTIFICATION |
39 | | - * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.99 2007/09/24 03:12:23 tgl Exp $ |
| 41 | + * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.100 2007/09/24 03:52:55 alvherre Exp $ |
40 | 42 | * |
41 | 43 | *------------------------------------------------------------------------- |
42 | 44 | */ |
|
68 | 70 | #define REL_TRUNCATE_MINIMUM 1000 |
69 | 71 | #define REL_TRUNCATE_FRACTION 16 |
70 | 72 |
|
| 73 | +/* |
| 74 | + * Guesstimation of number of dead tuples per page. This is used to |
| 75 | + * provide an upper limit to memory allocated when vacuuming small |
| 76 | + * tables. |
| 77 | + */ |
| 78 | +#define LAZY_ALLOC_TUPLES 200 |
71 | 79 |
|
72 | 80 | typedef struct LVRelStats |
73 | 81 | { |
@@ -1001,6 +1009,11 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks) |
1001 | 1009 | maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData); |
1002 | 1010 | maxtuples = Min(maxtuples, INT_MAX); |
1003 | 1011 | maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData)); |
| 1012 | + |
| 1013 | + /* curious coding here to ensure the multiplication can't overflow */ |
| 1014 | + if ((BlockNumber) (maxtuples / LAZY_ALLOC_TUPLES) > relblocks) |
| 1015 | + maxtuples = relblocks * LAZY_ALLOC_TUPLES; |
| 1016 | + |
1004 | 1017 | /* stay sane if small maintenance_work_mem */ |
1005 | 1018 | maxtuples = Max(maxtuples, MaxHeapTuplesPerPage); |
1006 | 1019 | } |
|
0 commit comments