summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-03-10 02:04:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-03-10 02:04:10 +0000
commit3fcc7e8e1884c966e1a292a3caeb39cce06f61aa (patch)
tree7728e9e3dabc64793e2450beb3b5e40f9a190a9c
parent9537739f7fcd3bafa2471b199297ec7ad7c935e7 (diff)
Reduce memory consumption during VACUUM of large relations, by using
FSMPageData (6 bytes) instead of PageFreeSpaceInfo (8 or 16 bytes) for the temporary array of page-free-space information. Itagaki Takahiro
-rw-r--r--src/backend/commands/vacuum.c11
-rw-r--r--src/backend/commands/vacuumlazy.c56
-rw-r--r--src/backend/storage/freespace/freespace.c27
-rw-r--r--src/include/storage/freespace.h14
4 files changed, 48 insertions, 60 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7e31ac452a7..a073a1d68e5 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.365 2008/02/20 14:31:35 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.366 2008/03/10 02:04:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3461,7 +3461,7 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages,
int nPages = fraged_pages->num_pages;
VacPage *pagedesc = fraged_pages->pagedesc;
Size threshold;
- PageFreeSpaceInfo *pageSpaces;
+ FSMPageData *pageSpaces;
int outPages;
int i;
@@ -3477,8 +3477,7 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages,
*/
threshold = GetAvgFSMRequestSize(&onerel->rd_node);
- pageSpaces = (PageFreeSpaceInfo *)
- palloc(nPages * sizeof(PageFreeSpaceInfo));
+ pageSpaces = (FSMPageData *) palloc(nPages * sizeof(FSMPageData));
outPages = 0;
for (i = 0; i < nPages; i++)
@@ -3493,8 +3492,8 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages,
if (pagedesc[i]->free >= threshold)
{
- pageSpaces[outPages].blkno = pagedesc[i]->blkno;
- pageSpaces[outPages].avail = pagedesc[i]->free;
+ FSMPageSetPageNum(&pageSpaces[outPages], pagedesc[i]->blkno);
+ FSMPageSetSpace(&pageSpaces[outPages], pagedesc[i]->free);
outPages++;
}
}
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 7adde03f4ac..d524e52b555 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -38,7 +38,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.103 2008/01/01 19:45:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.104 2008/03/10 02:04:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -98,7 +98,7 @@ typedef struct LVRelStats
bool fs_is_heap; /* are we using heap organization? */
int num_free_pages; /* current # of entries */
int max_free_pages; /* # slots allocated in array */
- PageFreeSpaceInfo *free_pages; /* array or heap of blkno/avail */
+ FSMPageData *free_pages; /* array or heap of blkno/avail */
BlockNumber tot_free_pages; /* total pages with >= threshold space */
int num_index_scans;
} LVRelStats;
@@ -813,7 +813,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
{
BlockNumber old_rel_pages = vacrelstats->rel_pages;
BlockNumber new_rel_pages;
- PageFreeSpaceInfo *pageSpaces;
+ FSMPageData *pageSpaces;
int n;
int i,
j;
@@ -881,7 +881,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
j = 0;
for (i = 0; i < n; i++)
{
- if (pageSpaces[i].blkno < new_rel_pages)
+ if (FSMPageGetPageNum(&pageSpaces[i]) < new_rel_pages)
{
pageSpaces[j] = pageSpaces[i];
j++;
@@ -1028,7 +1028,7 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
palloc(maxtuples * sizeof(ItemPointerData));
maxpages = MaxFSMPages;
- maxpages = Min(maxpages, MaxAllocSize / sizeof(PageFreeSpaceInfo));
+ maxpages = Min(maxpages, MaxAllocSize / sizeof(FSMPageData));
/* No need to allocate more pages than the relation has blocks */
if (relblocks < (BlockNumber) maxpages)
maxpages = (int) relblocks;
@@ -1036,8 +1036,8 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
vacrelstats->fs_is_heap = false;
vacrelstats->num_free_pages = 0;
vacrelstats->max_free_pages = maxpages;
- vacrelstats->free_pages = (PageFreeSpaceInfo *)
- palloc(maxpages * sizeof(PageFreeSpaceInfo));
+ vacrelstats->free_pages = (FSMPageData *)
+ palloc(maxpages * sizeof(FSMPageData));
vacrelstats->tot_free_pages = 0;
}
@@ -1068,7 +1068,7 @@ lazy_record_free_space(LVRelStats *vacrelstats,
BlockNumber page,
Size avail)
{
- PageFreeSpaceInfo *pageSpaces;
+ FSMPageData *pageSpaces;
int n;
/*
@@ -1098,8 +1098,8 @@ lazy_record_free_space(LVRelStats *vacrelstats,
/* If we haven't filled the array yet, just keep adding entries */
if (vacrelstats->num_free_pages < n)
{
- pageSpaces[vacrelstats->num_free_pages].blkno = page;
- pageSpaces[vacrelstats->num_free_pages].avail = avail;
+ FSMPageSetPageNum(&pageSpaces[vacrelstats->num_free_pages], page);
+ FSMPageSetSpace(&pageSpaces[vacrelstats->num_free_pages], avail);
vacrelstats->num_free_pages++;
return;
}
@@ -1127,8 +1127,8 @@ lazy_record_free_space(LVRelStats *vacrelstats,
while (--l >= 0)
{
- BlockNumber R = pageSpaces[l].blkno;
- Size K = pageSpaces[l].avail;
+ BlockNumber R = FSMPageGetPageNum(&pageSpaces[l]);
+ Size K = FSMPageGetSpace(&pageSpaces[l]);
int i; /* i is where the "hole" is */
i = l;
@@ -1138,22 +1138,22 @@ lazy_record_free_space(LVRelStats *vacrelstats,
if (j >= n)
break;
- if (j + 1 < n && pageSpaces[j].avail > pageSpaces[j + 1].avail)
+ if (j + 1 < n && FSMPageGetSpace(&pageSpaces[j]) > FSMPageGetSpace(&pageSpaces[j + 1]))
j++;
- if (K <= pageSpaces[j].avail)
+ if (K <= FSMPageGetSpace(&pageSpaces[j]))
break;
pageSpaces[i] = pageSpaces[j];
i = j;
}
- pageSpaces[i].blkno = R;
- pageSpaces[i].avail = K;
+ FSMPageSetPageNum(&pageSpaces[i], R);
+ FSMPageSetSpace(&pageSpaces[i], K);
}
vacrelstats->fs_is_heap = true;
}
/* If new page has more than zero'th entry, insert it into heap */
- if (avail > pageSpaces[0].avail)
+ if (avail > FSMPageGetSpace(&pageSpaces[0]))
{
/*
* Notionally, we replace the zero'th entry with the new data, and
@@ -1169,15 +1169,15 @@ lazy_record_free_space(LVRelStats *vacrelstats,
if (j >= n)
break;
- if (j + 1 < n && pageSpaces[j].avail > pageSpaces[j + 1].avail)
+ if (j + 1 < n && FSMPageGetSpace(&pageSpaces[j]) > FSMPageGetSpace(&pageSpaces[j + 1]))
j++;
- if (avail <= pageSpaces[j].avail)
+ if (avail <= FSMPageGetSpace(&pageSpaces[j]))
break;
pageSpaces[i] = pageSpaces[j];
i = j;
}
- pageSpaces[i].blkno = page;
- pageSpaces[i].avail = avail;
+ FSMPageSetPageNum(&pageSpaces[i], page);
+ FSMPageSetSpace(&pageSpaces[i], avail);
}
}
@@ -1210,14 +1210,14 @@ lazy_tid_reaped(ItemPointer itemptr, void *state)
static void
lazy_update_fsm(Relation onerel, LVRelStats *vacrelstats)
{
- PageFreeSpaceInfo *pageSpaces = vacrelstats->free_pages;
+ FSMPageData *pageSpaces = vacrelstats->free_pages;
int nPages = vacrelstats->num_free_pages;
/*
* Sort data into order, as required by RecordRelationFreeSpace.
*/
if (nPages > 1)
- qsort(pageSpaces, nPages, sizeof(PageFreeSpaceInfo),
+ qsort(pageSpaces, nPages, sizeof(FSMPageData),
vac_cmp_page_spaces);
RecordRelationFreeSpace(&onerel->rd_node, vacrelstats->tot_free_pages,
@@ -1257,12 +1257,14 @@ vac_cmp_itemptr(const void *left, const void *right)
static int
vac_cmp_page_spaces(const void *left, const void *right)
{
- PageFreeSpaceInfo *linfo = (PageFreeSpaceInfo *) left;
- PageFreeSpaceInfo *rinfo = (PageFreeSpaceInfo *) right;
+ FSMPageData *linfo = (FSMPageData *) left;
+ FSMPageData *rinfo = (FSMPageData *) right;
+ BlockNumber lblkno = FSMPageGetPageNum(linfo);
+ BlockNumber rblkno = FSMPageGetPageNum(rinfo);
- if (linfo->blkno < rinfo->blkno)
+ if (lblkno < rblkno)
return -1;
- else if (linfo->blkno > rinfo->blkno)
+ else if (lblkno > rblkno)
return 1;
return 0;
}
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 7b66340f56c..9373675b8cc 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.59 2008/01/01 19:45:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.60 2008/03/10 02:04:09 tgl Exp $
*
*
* NOTES:
@@ -143,7 +143,7 @@ static bool lookup_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page,
static void compact_fsm_storage(void);
static void push_fsm_rels_after(FSMRelation *afterRel);
static void pack_incoming_pages(FSMPageData *newLocation, int newPages,
- PageFreeSpaceInfo *pageSpaces, int nPages);
+ FSMPageData *pageSpaces, int nPages);
static void pack_existing_pages(FSMPageData *newLocation, int newPages,
FSMPageData *oldLocation, int oldPages);
static int fsm_calc_request(FSMRelation *fsmrel);
@@ -375,7 +375,7 @@ void
RecordRelationFreeSpace(RelFileNode *rel,
BlockNumber interestingPages,
int nPages,
- PageFreeSpaceInfo *pageSpaces)
+ FSMPageData *pageSpaces)
{
FSMRelation *fsmrel;
@@ -415,14 +415,12 @@ RecordRelationFreeSpace(RelFileNode *rel,
for (i = 0; i < nPages; i++)
{
- BlockNumber page = pageSpaces[i].blkno;
- Size avail = pageSpaces[i].avail;
+ BlockNumber page = FSMPageGetPageNum(&pageSpaces[i]);
/* Check caller provides sorted data */
- if (i > 0 && page <= pageSpaces[i - 1].blkno)
+ if (i > 0 && page <= FSMPageGetPageNum(&pageSpaces[i - 1]))
elog(ERROR, "free-space data is not in page order");
- FSMPageSetPageNum(newLocation, page);
- FSMPageSetSpace(newLocation, avail);
+ *newLocation = pageSpaces[i];
newLocation++;
}
fsmrel->storedPages = nPages;
@@ -1534,7 +1532,7 @@ push_fsm_rels_after(FSMRelation *afterRel)
static void
pack_incoming_pages(FSMPageData *newLocation, int newPages,
- PageFreeSpaceInfo *pageSpaces, int nPages)
+ FSMPageData *pageSpaces, int nPages)
{
int histogram[HISTOGRAM_BINS];
int above,
@@ -1548,7 +1546,7 @@ pack_incoming_pages(FSMPageData *newLocation, int newPages,
MemSet(histogram, 0, sizeof(histogram));
for (i = 0; i < nPages; i++)
{
- Size avail = pageSpaces[i].avail;
+ Size avail = FSMPageGetSpace(&pageSpaces[i]);
if (avail >= BLCKSZ)
elog(ERROR, "bogus freespace amount");
@@ -1572,18 +1570,17 @@ pack_incoming_pages(FSMPageData *newLocation, int newPages,
/* And copy the appropriate data */
for (i = 0; i < nPages; i++)
{
- BlockNumber page = pageSpaces[i].blkno;
- Size avail = pageSpaces[i].avail;
+ BlockNumber page = FSMPageGetPageNum(&pageSpaces[i]);
+ Size avail = FSMPageGetSpace(&pageSpaces[i]);
/* Check caller provides sorted data */
- if (i > 0 && page <= pageSpaces[i - 1].blkno)
+ if (i > 0 && page <= FSMPageGetPageNum(&pageSpaces[i - 1]))
elog(ERROR, "free-space data is not in page order");
/* Save this page? */
if (avail >= thresholdU ||
(avail >= thresholdL && (--binct >= 0)))
{
- FSMPageSetPageNum(newLocation, page);
- FSMPageSetSpace(newLocation, avail);
+ *newLocation = pageSpaces[i];
newLocation++;
newPages--;
}
diff --git a/src/include/storage/freespace.h b/src/include/storage/freespace.h
index 0ef828ed54d..86dd22647c3 100644
--- a/src/include/storage/freespace.h
+++ b/src/include/storage/freespace.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/freespace.h,v 1.27 2008/01/01 19:45:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/freespace.h,v 1.28 2008/03/10 02:04:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,16 +18,6 @@
#include "storage/itemptr.h"
-/*
- * exported types
- */
-typedef struct PageFreeSpaceInfo
-{
- BlockNumber blkno; /* which page in relation */
- Size avail; /* space available on this page */
-} PageFreeSpaceInfo;
-
-
/* Initial value for average-request moving average */
#define INITIAL_AVERAGE ((Size) (BLCKSZ / 32))
@@ -144,7 +134,7 @@ extern Size GetAvgFSMRequestSize(RelFileNode *rel);
extern void RecordRelationFreeSpace(RelFileNode *rel,
BlockNumber interestingPages,
int nPages,
- PageFreeSpaceInfo *pageSpaces);
+ FSMPageData *pageSpaces);
extern BlockNumber GetFreeIndexPage(RelFileNode *rel);
extern void RecordIndexFreeSpace(RelFileNode *rel,