]> granicus.if.org Git - postgresql/commitdiff
Reduce memory consumption during VACUUM of large relations, by using
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Mar 2008 02:04:10 +0000 (02:04 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Mar 2008 02:04:10 +0000 (02:04 +0000)
FSMPageData (6 bytes) instead of PageFreeSpaceInfo (8 or 16 bytes)
for the temporary array of page-free-space information.

Itagaki Takahiro

src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/backend/storage/freespace/freespace.c
src/include/storage/freespace.h

index 7e31ac452a7f42fd3cc9dcb2dab391aae3445d21..a073a1d68e5560fdac1605e487d03258786c8737 100644 (file)
@@ -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++;
                }
        }
index 7adde03f4ac6819d518a8a357e08bb8bfcf39cb8..d524e52b55522b66a5ba84e6438c3622e0723943 100644 (file)
@@ -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;
 }
index 7b66340f56c566ee0db305387de2d2acbfc00a7b..9373675b8cca6e1b3ce01ece6933c3a227076939 100644 (file)
@@ -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--;
                }
index 0ef828ed54d8ac42ce70c75cc26b038aa7215df8..86dd22647c358abc386da571edc67e79c45de8c9 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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,