summaryrefslogtreecommitdiff
path: root/src/backend/commands/vacuumlazy.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-09-21 20:31:22 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-09-21 20:31:22 +0000
commit9e936693a9fc464511b52b14fb681cdea014bf59 (patch)
tree2781b3043a8b46dcf3d40d6410d2b7b970fa0b5e /src/backend/commands/vacuumlazy.c
parentb0d64a090b14217c9bcf620a32c60eab1354470f (diff)
Fix free space map to correctly track the total amount of FSM space needed
even when a single relation requires more than max_fsm_pages pages. Also, make VACUUM emit a warning in this case, since it likely means that VACUUM FULL or other drastic corrective measure is needed. Per reports from Jeff Frost and others of unexpected changes in the claimed max_fsm_pages need.
Diffstat (limited to 'src/backend/commands/vacuumlazy.c')
-rw-r--r--src/backend/commands/vacuumlazy.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index d3b91807795..c839b951d98 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -36,7 +36,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.78 2006/09/13 17:47:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.79 2006/09/21 20:31:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -90,6 +90,7 @@ typedef struct LVRelStats
int num_free_pages; /* current # of entries */
int max_free_pages; /* # slots allocated in array */
PageFreeSpaceInfo *free_pages; /* array or heap of blkno/avail */
+ BlockNumber tot_free_pages; /* total pages with >= threshold space */
} LVRelStats;
@@ -523,12 +524,21 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
tups_vacuumed, num_tuples, nblocks),
errdetail("%.0f dead row versions cannot be removed yet.\n"
"There were %.0f unused item pointers.\n"
+ "%u pages contain useful free space.\n"
"%u pages are entirely empty.\n"
"%s.",
nkeep,
nunused,
+ vacrelstats->tot_free_pages,
empty_pages,
pg_rusage_show(&ru0))));
+
+ if (vacrelstats->tot_free_pages > MaxFSMPages)
+ ereport(WARNING,
+ (errmsg("relation \"%s.%s\" contains more than \"max_fsm_pages\" pages with useful free space",
+ get_namespace_name(RelationGetNamespace(onerel)),
+ relname),
+ errhint("Consider compacting this relation or increasing the configuration parameter \"max_fsm_pages\".")));
}
@@ -793,6 +803,14 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats,
}
}
vacrelstats->num_free_pages = j;
+ /*
+ * If tot_free_pages was more than num_free_pages, we can't tell for sure
+ * what its correct value is now, because we don't know which of the
+ * forgotten pages are getting truncated. Conservatively set it equal
+ * to num_free_pages.
+ */
+ vacrelstats->tot_free_pages = j;
+
/* We destroyed the heap ordering, so mark array unordered */
vacrelstats->fs_is_heap = false;
@@ -960,6 +978,7 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
vacrelstats->max_free_pages = maxpages;
vacrelstats->free_pages = (PageFreeSpaceInfo *)
palloc(maxpages * sizeof(PageFreeSpaceInfo));
+ vacrelstats->tot_free_pages = 0;
}
/*
@@ -1009,6 +1028,9 @@ lazy_record_free_space(LVRelStats *vacrelstats,
if (avail < vacrelstats->threshold)
return;
+ /* Count all pages over threshold, even if not enough space in array */
+ vacrelstats->tot_free_pages++;
+
/* Copy pointers to local variables for notational simplicity */
pageSpaces = vacrelstats->free_pages;
n = vacrelstats->max_free_pages;
@@ -1138,7 +1160,8 @@ lazy_update_fsm(Relation onerel, LVRelStats *vacrelstats)
qsort(pageSpaces, nPages, sizeof(PageFreeSpaceInfo),
vac_cmp_page_spaces);
- RecordRelationFreeSpace(&onerel->rd_node, nPages, pageSpaces);
+ RecordRelationFreeSpace(&onerel->rd_node, vacrelstats->tot_free_pages,
+ nPages, pageSpaces);
}
/*