mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
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
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user