mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 00:02:04 -04:00
Reimplement free-space-map management as per recent discussions.
Adjustable threshold is gone in favor of keeping track of total requested page storage and doling out proportional fractions to each relation (with a minimum amount per relation, and some quantization of the results to avoid thrashing with small changes in page counts). Provide special- case code for indexes so as not to waste space storing useless page free space counts. Restructure internal data storage to be a flat array instead of list-of-chunks; this may cost a little more work in data copying when reorganizing, but allows binary search to be used during lookup_fsm_page_entry().
This commit is contained in:
parent
a455c94257
commit
391eb5e5b6
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.169 2003/02/19 04:06:28 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.170 2003/03/04 21:51:19 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Chapter Id="runtime">
|
<Chapter Id="runtime">
|
||||||
@ -1725,7 +1725,9 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Sets the maximum number of disk pages for which free space will
|
Sets the maximum number of disk pages for which free space will
|
||||||
be tracked in the shared free-space map. The default is 10000.
|
be tracked in the shared free-space map. Six bytes of shared memory
|
||||||
|
are consumed for each page slot. This setting must be more than
|
||||||
|
16 * <varname>max_fsm_relations</varname>. The default is 20000.
|
||||||
This option can only be set at server start.
|
This option can only be set at server start.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -1735,9 +1737,11 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
|
|||||||
<term><varname>MAX_FSM_RELATIONS</varname> (<type>integer</type>)</term>
|
<term><varname>MAX_FSM_RELATIONS</varname> (<type>integer</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Sets the maximum number of relations (tables) for which free
|
Sets the maximum number of relations (tables and indexes) for which
|
||||||
space will be tracked in the shared free-space map. The default
|
free space will be tracked in the shared free-space map. Roughly
|
||||||
is 1000. This option can only be set at server start.
|
fifty bytes of shared memory are consumed for each slot.
|
||||||
|
The default is 1000.
|
||||||
|
This option can only be set at server start.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.63 2003/02/23 23:20:52 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.64 2003/03/04 21:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Postgres btree pages look like ordinary relation pages. The opaque
|
* Postgres btree pages look like ordinary relation pages. The opaque
|
||||||
@ -401,15 +401,10 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
|
|||||||
* that the page is still free. (For example, an already-free page
|
* that the page is still free. (For example, an already-free page
|
||||||
* could have been re-used between the time the last VACUUM scanned
|
* could have been re-used between the time the last VACUUM scanned
|
||||||
* it and the time the VACUUM made its FSM updates.)
|
* it and the time the VACUUM made its FSM updates.)
|
||||||
*
|
|
||||||
* The request size should be more than half of what btvacuumcleanup
|
|
||||||
* logs as the per-page free space. We use BLCKSZ/2 and BLCKSZ-1
|
|
||||||
* to try to get some use out of FSM's space management algorithm.
|
|
||||||
* XXX this needs some more thought...
|
|
||||||
*/
|
*/
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
blkno = GetPageWithFreeSpace(&rel->rd_node, BLCKSZ/2);
|
blkno = GetFreeIndexPage(&rel->rd_node);
|
||||||
if (blkno == InvalidBlockNumber)
|
if (blkno == InvalidBlockNumber)
|
||||||
break;
|
break;
|
||||||
buf = ReadBuffer(rel, blkno);
|
buf = ReadBuffer(rel, blkno);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.100 2003/02/24 00:57:17 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.101 2003/03/04 21:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -697,7 +697,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(2);
|
IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(2);
|
||||||
BlockNumber num_pages;
|
BlockNumber num_pages;
|
||||||
BlockNumber blkno;
|
BlockNumber blkno;
|
||||||
PageFreeSpaceInfo *pageSpaces;
|
BlockNumber *freePages;
|
||||||
int nFreePages,
|
int nFreePages,
|
||||||
maxFreePages;
|
maxFreePages;
|
||||||
BlockNumber pages_deleted = 0;
|
BlockNumber pages_deleted = 0;
|
||||||
@ -712,7 +712,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
maxFreePages = MaxFSMPages;
|
maxFreePages = MaxFSMPages;
|
||||||
if ((BlockNumber) maxFreePages > num_pages)
|
if ((BlockNumber) maxFreePages > num_pages)
|
||||||
maxFreePages = (int) num_pages + 1; /* +1 to avoid palloc(0) */
|
maxFreePages = (int) num_pages + 1; /* +1 to avoid palloc(0) */
|
||||||
pageSpaces = (PageFreeSpaceInfo *) palloc(maxFreePages * sizeof(PageFreeSpaceInfo));
|
freePages = (BlockNumber *) palloc(maxFreePages * sizeof(BlockNumber));
|
||||||
nFreePages = 0;
|
nFreePages = 0;
|
||||||
|
|
||||||
/* Create a temporary memory context to run _bt_pagedel in */
|
/* Create a temporary memory context to run _bt_pagedel in */
|
||||||
@ -740,12 +740,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
/* Okay to recycle this page */
|
/* Okay to recycle this page */
|
||||||
if (nFreePages < maxFreePages)
|
if (nFreePages < maxFreePages)
|
||||||
{
|
freePages[nFreePages++] = blkno;
|
||||||
pageSpaces[nFreePages].blkno = blkno;
|
|
||||||
/* claimed avail-space must be < BLCKSZ */
|
|
||||||
pageSpaces[nFreePages].avail = BLCKSZ-1;
|
|
||||||
nFreePages++;
|
|
||||||
}
|
|
||||||
pages_deleted++;
|
pages_deleted++;
|
||||||
}
|
}
|
||||||
else if (P_ISDELETED(opaque))
|
else if (P_ISDELETED(opaque))
|
||||||
@ -781,12 +776,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
if (ndel && info->vacuum_full)
|
if (ndel && info->vacuum_full)
|
||||||
{
|
{
|
||||||
if (nFreePages < maxFreePages)
|
if (nFreePages < maxFreePages)
|
||||||
{
|
freePages[nFreePages++] = blkno;
|
||||||
pageSpaces[nFreePages].blkno = blkno;
|
|
||||||
/* claimed avail-space must be < BLCKSZ */
|
|
||||||
pageSpaces[nFreePages].avail = BLCKSZ-1;
|
|
||||||
nFreePages++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
@ -805,8 +795,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
BlockNumber new_pages = num_pages;
|
BlockNumber new_pages = num_pages;
|
||||||
|
|
||||||
while (nFreePages > 0 &&
|
while (nFreePages > 0 && freePages[nFreePages-1] == new_pages-1)
|
||||||
pageSpaces[nFreePages-1].blkno == new_pages-1)
|
|
||||||
{
|
{
|
||||||
new_pages--;
|
new_pages--;
|
||||||
pages_deleted--;
|
pages_deleted--;
|
||||||
@ -841,12 +830,12 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the shared Free Space Map with the info we now have about
|
* Update the shared Free Space Map with the info we now have about
|
||||||
* free space in the index, discarding any old info the map may have.
|
* free pages in the index, discarding any old info the map may have.
|
||||||
* We do not need to sort the page numbers; they're in order already.
|
* We do not need to sort the page numbers; they're in order already.
|
||||||
*/
|
*/
|
||||||
MultiRecordFreeSpace(&rel->rd_node, 0, nFreePages, pageSpaces);
|
RecordIndexFreeSpace(&rel->rd_node, nFreePages, freePages);
|
||||||
|
|
||||||
pfree(pageSpaces);
|
pfree(freePages);
|
||||||
|
|
||||||
MemoryContextDelete(mycontext);
|
MemoryContextDelete(mycontext);
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.250 2003/02/24 00:57:17 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.251 2003/03/04 21:51:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -336,6 +336,13 @@ vacuum(VacuumStmt *vacstmt)
|
|||||||
*/
|
*/
|
||||||
StartTransactionCommand(true);
|
StartTransactionCommand(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it was a database-wide VACUUM, print FSM usage statistics
|
||||||
|
* (we don't make you be superuser to see these).
|
||||||
|
*/
|
||||||
|
if (vacstmt->relation == NULL)
|
||||||
|
PrintFreeSpaceMapStatistics(elevel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we completed a database-wide VACUUM without skipping any
|
* If we completed a database-wide VACUUM without skipping any
|
||||||
* relations, update the database's pg_database row with info
|
* relations, update the database's pg_database row with info
|
||||||
@ -2781,31 +2788,48 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages,
|
|||||||
BlockNumber rel_pages)
|
BlockNumber rel_pages)
|
||||||
{
|
{
|
||||||
int nPages = fraged_pages->num_pages;
|
int nPages = fraged_pages->num_pages;
|
||||||
int i;
|
VacPage *pagedesc = fraged_pages->pagedesc;
|
||||||
|
Size threshold;
|
||||||
PageFreeSpaceInfo *pageSpaces;
|
PageFreeSpaceInfo *pageSpaces;
|
||||||
|
int outPages;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only report pages with free space at least equal to the average
|
||||||
|
* request size --- this avoids cluttering FSM with uselessly-small bits
|
||||||
|
* of space. Although FSM would discard pages with little free space
|
||||||
|
* anyway, it's important to do this prefiltering because (a) it reduces
|
||||||
|
* the time spent holding the FSM lock in RecordRelationFreeSpace, and
|
||||||
|
* (b) FSM uses the number of pages reported as a statistic for guiding
|
||||||
|
* space management. If we didn't threshold our reports the same way
|
||||||
|
* vacuumlazy.c does, we'd be skewing that statistic.
|
||||||
|
*/
|
||||||
|
threshold = GetAvgFSMRequestSize(&onerel->rd_node);
|
||||||
|
|
||||||
/* +1 to avoid palloc(0) */
|
/* +1 to avoid palloc(0) */
|
||||||
pageSpaces = (PageFreeSpaceInfo *)
|
pageSpaces = (PageFreeSpaceInfo *)
|
||||||
palloc((nPages + 1) * sizeof(PageFreeSpaceInfo));
|
palloc((nPages + 1) * sizeof(PageFreeSpaceInfo));
|
||||||
|
outPages = 0;
|
||||||
|
|
||||||
for (i = 0; i < nPages; i++)
|
for (i = 0; i < nPages; i++)
|
||||||
{
|
{
|
||||||
pageSpaces[i].blkno = fraged_pages->pagedesc[i]->blkno;
|
|
||||||
pageSpaces[i].avail = fraged_pages->pagedesc[i]->free;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fraged_pages may contain entries for pages that we later
|
* fraged_pages may contain entries for pages that we later
|
||||||
* decided to truncate from the relation; don't enter them into
|
* decided to truncate from the relation; don't enter them into
|
||||||
* the free space map!
|
* the free space map!
|
||||||
*/
|
*/
|
||||||
if (pageSpaces[i].blkno >= rel_pages)
|
if (pagedesc[i]->blkno >= rel_pages)
|
||||||
{
|
|
||||||
nPages = i;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (pagedesc[i]->free >= threshold)
|
||||||
|
{
|
||||||
|
pageSpaces[outPages].blkno = pagedesc[i]->blkno;
|
||||||
|
pageSpaces[outPages].avail = pagedesc[i]->free;
|
||||||
|
outPages++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiRecordFreeSpace(&onerel->rd_node, 0, nPages, pageSpaces);
|
RecordRelationFreeSpace(&onerel->rd_node, outPages, pageSpaces);
|
||||||
|
|
||||||
pfree(pageSpaces);
|
pfree(pageSpaces);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.26 2003/02/24 00:57:17 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.27 2003/03/04 21:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -51,21 +51,11 @@
|
|||||||
/*
|
/*
|
||||||
* Space/time tradeoff parameters: do these need to be user-tunable?
|
* Space/time tradeoff parameters: do these need to be user-tunable?
|
||||||
*
|
*
|
||||||
* A page with less than PAGE_SPACE_THRESHOLD free space will be forgotten
|
|
||||||
* immediately, and not even passed to the free space map. Removing the
|
|
||||||
* uselessly small entries early saves cycles, and in particular reduces
|
|
||||||
* the amount of time we spend holding the FSM lock when we finally call
|
|
||||||
* MultiRecordFreeSpace. Since the FSM will ignore pages below its own
|
|
||||||
* runtime threshold anyway, there's no point in making this really small.
|
|
||||||
* XXX Is it worth trying to measure average tuple size, and using that to
|
|
||||||
* set the threshold? Problem is we don't know average tuple size very
|
|
||||||
* accurately for the first few pages...
|
|
||||||
*
|
|
||||||
* To consider truncating the relation, we want there to be at least
|
* To consider truncating the relation, we want there to be at least
|
||||||
* relsize / REL_TRUNCATE_FRACTION potentially-freeable pages.
|
* REL_TRUNCATE_MINIMUM or (relsize / REL_TRUNCATE_FRACTION) (whichever
|
||||||
|
* is less) potentially-freeable pages.
|
||||||
*/
|
*/
|
||||||
#define PAGE_SPACE_THRESHOLD ((Size) (BLCKSZ / 32))
|
#define REL_TRUNCATE_MINIMUM 1000
|
||||||
|
|
||||||
#define REL_TRUNCATE_FRACTION 16
|
#define REL_TRUNCATE_FRACTION 16
|
||||||
|
|
||||||
/* MAX_TUPLES_PER_PAGE can be a conservative upper limit */
|
/* MAX_TUPLES_PER_PAGE can be a conservative upper limit */
|
||||||
@ -78,6 +68,7 @@ typedef struct LVRelStats
|
|||||||
BlockNumber rel_pages;
|
BlockNumber rel_pages;
|
||||||
double rel_tuples;
|
double rel_tuples;
|
||||||
BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */
|
BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */
|
||||||
|
Size threshold; /* minimum interesting free space */
|
||||||
/* List of TIDs of tuples we intend to delete */
|
/* List of TIDs of tuples we intend to delete */
|
||||||
/* NB: this list is ordered by TID address */
|
/* NB: this list is ordered by TID address */
|
||||||
int num_dead_tuples; /* current # of entries */
|
int num_dead_tuples; /* current # of entries */
|
||||||
@ -149,6 +140,10 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
|
|||||||
|
|
||||||
vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
|
vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
|
||||||
|
|
||||||
|
/* Set threshold for interesting free space = average request size */
|
||||||
|
/* XXX should we scale it up or down? Adjust vacuum.c too, if so */
|
||||||
|
vacrelstats->threshold = GetAvgFSMRequestSize(&onerel->rd_node);
|
||||||
|
|
||||||
/* Open all indexes of the relation */
|
/* Open all indexes of the relation */
|
||||||
vac_open_indexes(onerel, &nindexes, &Irel);
|
vac_open_indexes(onerel, &nindexes, &Irel);
|
||||||
hasindex = (nindexes > 0);
|
hasindex = (nindexes > 0);
|
||||||
@ -166,7 +161,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
|
|||||||
* number of pages. Otherwise, the time taken isn't worth it.
|
* number of pages. Otherwise, the time taken isn't worth it.
|
||||||
*/
|
*/
|
||||||
possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages;
|
possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages;
|
||||||
if (possibly_freeable > vacrelstats->rel_pages / REL_TRUNCATE_FRACTION)
|
if (possibly_freeable >= REL_TRUNCATE_MINIMUM ||
|
||||||
|
possibly_freeable >= vacrelstats->rel_pages / REL_TRUNCATE_FRACTION)
|
||||||
lazy_truncate_heap(onerel, vacrelstats);
|
lazy_truncate_heap(onerel, vacrelstats);
|
||||||
|
|
||||||
/* Update shared free space map with final free space info */
|
/* Update shared free space map with final free space info */
|
||||||
@ -943,8 +939,21 @@ lazy_record_free_space(LVRelStats *vacrelstats,
|
|||||||
PageFreeSpaceInfo *pageSpaces;
|
PageFreeSpaceInfo *pageSpaces;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* Ignore pages with little free space */
|
/*
|
||||||
if (avail < PAGE_SPACE_THRESHOLD)
|
* A page with less than stats->threshold free space will be forgotten
|
||||||
|
* immediately, and never passed to the free space map. Removing the
|
||||||
|
* uselessly small entries early saves cycles, and in particular reduces
|
||||||
|
* the amount of time we spend holding the FSM lock when we finally call
|
||||||
|
* RecordRelationFreeSpace. Since the FSM will probably drop pages with
|
||||||
|
* little free space anyway, there's no point in making this really small.
|
||||||
|
*
|
||||||
|
* XXX Is it worth trying to measure average tuple size, and using that to
|
||||||
|
* adjust the threshold? Would be worthwhile if FSM has no stats yet
|
||||||
|
* for this relation. But changing the threshold as we scan the rel
|
||||||
|
* might lead to bizarre behavior, too. Also, it's probably better if
|
||||||
|
* vacuum.c has the same thresholding behavior as we do here.
|
||||||
|
*/
|
||||||
|
if (avail < vacrelstats->threshold)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Copy pointers to local variables for notational simplicity */
|
/* Copy pointers to local variables for notational simplicity */
|
||||||
@ -1079,13 +1088,13 @@ lazy_update_fsm(Relation onerel, LVRelStats *vacrelstats)
|
|||||||
int nPages = vacrelstats->num_free_pages;
|
int nPages = vacrelstats->num_free_pages;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort data into order, as required by MultiRecordFreeSpace.
|
* Sort data into order, as required by RecordRelationFreeSpace.
|
||||||
*/
|
*/
|
||||||
if (nPages > 1)
|
if (nPages > 1)
|
||||||
qsort(pageSpaces, nPages, sizeof(PageFreeSpaceInfo),
|
qsort(pageSpaces, nPages, sizeof(PageFreeSpaceInfo),
|
||||||
vac_cmp_page_spaces);
|
vac_cmp_page_spaces);
|
||||||
|
|
||||||
MultiRecordFreeSpace(&onerel->rd_node, 0, nPages, pageSpaces);
|
RecordRelationFreeSpace(&onerel->rd_node, nPages, pageSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.61 2002/09/20 19:56:01 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.62 2003/03/04 21:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -410,7 +410,7 @@ smgrtruncate(int16 which, Relation reln, BlockNumber nblocks)
|
|||||||
* for the about-to-be-deleted blocks. We want to be sure it
|
* for the about-to-be-deleted blocks. We want to be sure it
|
||||||
* won't return bogus block numbers later on.
|
* won't return bogus block numbers later on.
|
||||||
*/
|
*/
|
||||||
MultiRecordFreeSpace(&reln->rd_node, nblocks, 0, NULL);
|
FreeSpaceMapTruncateRel(&reln->rd_node, nblocks);
|
||||||
|
|
||||||
newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks);
|
newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks);
|
||||||
if (newblks == InvalidBlockNumber)
|
if (newblks == InvalidBlockNumber)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* command, configuration file, and command line options.
|
* command, configuration file, and command line options.
|
||||||
* See src/backend/utils/misc/README for more information.
|
* See src/backend/utils/misc/README for more information.
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.115 2003/02/23 23:27:21 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.116 2003/03/04 21:51:21 tgl Exp $
|
||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
@ -644,11 +644,11 @@ static struct config_int
|
|||||||
|
|
||||||
{
|
{
|
||||||
{"max_fsm_relations", PGC_POSTMASTER}, &MaxFSMRelations,
|
{"max_fsm_relations", PGC_POSTMASTER}, &MaxFSMRelations,
|
||||||
1000, 10, INT_MAX, NULL, NULL
|
1000, 100, INT_MAX, NULL, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"max_fsm_pages", PGC_POSTMASTER}, &MaxFSMPages,
|
{"max_fsm_pages", PGC_POSTMASTER}, &MaxFSMPages,
|
||||||
10000, 1000, INT_MAX, NULL, NULL
|
20000, 1000, INT_MAX, NULL, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -48,10 +48,11 @@
|
|||||||
# Shared Memory Size
|
# Shared Memory Size
|
||||||
#
|
#
|
||||||
#shared_buffers = 64 # min max_connections*2 or 16, 8KB each
|
#shared_buffers = 64 # min max_connections*2 or 16, 8KB each
|
||||||
#max_fsm_relations = 1000 # min 10, fsm is free space map, ~40 bytes
|
|
||||||
#max_fsm_pages = 10000 # min 1000, fsm is free space map, ~6 bytes
|
|
||||||
#max_locks_per_transaction = 64 # min 10
|
#max_locks_per_transaction = 64 # min 10
|
||||||
#wal_buffers = 8 # min 4, typically 8KB each
|
#wal_buffers = 8 # min 4, typically 8KB each
|
||||||
|
# fsm = free space map
|
||||||
|
#max_fsm_relations = 1000 # min 100, ~50 bytes each
|
||||||
|
#max_fsm_pages = 20000 # min max_fsm_relations*16, 6 bytes each
|
||||||
|
|
||||||
#
|
#
|
||||||
# Non-shared Memory Sizes
|
# Non-shared Memory Sizes
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: freespace.h,v 1.8 2002/09/20 19:56:01 tgl Exp $
|
* $Id: freespace.h,v 1.9 2003/03/04 21:51:22 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -28,6 +28,7 @@ typedef struct PageFreeSpaceInfo
|
|||||||
} PageFreeSpaceInfo;
|
} PageFreeSpaceInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/* GUC variables */
|
||||||
extern int MaxFSMRelations;
|
extern int MaxFSMRelations;
|
||||||
extern int MaxFSMPages;
|
extern int MaxFSMPages;
|
||||||
|
|
||||||
@ -39,19 +40,26 @@ extern void InitFreeSpaceMap(void);
|
|||||||
extern int FreeSpaceShmemSize(void);
|
extern int FreeSpaceShmemSize(void);
|
||||||
|
|
||||||
extern BlockNumber GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded);
|
extern BlockNumber GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded);
|
||||||
extern void RecordFreeSpace(RelFileNode *rel, BlockNumber page,
|
|
||||||
Size spaceAvail);
|
|
||||||
extern BlockNumber RecordAndGetPageWithFreeSpace(RelFileNode *rel,
|
extern BlockNumber RecordAndGetPageWithFreeSpace(RelFileNode *rel,
|
||||||
BlockNumber oldPage,
|
BlockNumber oldPage,
|
||||||
Size oldSpaceAvail,
|
Size oldSpaceAvail,
|
||||||
Size spaceNeeded);
|
Size spaceNeeded);
|
||||||
extern void MultiRecordFreeSpace(RelFileNode *rel,
|
extern Size GetAvgFSMRequestSize(RelFileNode *rel);
|
||||||
BlockNumber minPage,
|
extern void RecordRelationFreeSpace(RelFileNode *rel,
|
||||||
int nPages,
|
int nPages,
|
||||||
PageFreeSpaceInfo *pageSpaces);
|
PageFreeSpaceInfo *pageSpaces);
|
||||||
|
|
||||||
|
extern BlockNumber GetFreeIndexPage(RelFileNode *rel);
|
||||||
|
extern void RecordIndexFreeSpace(RelFileNode *rel,
|
||||||
|
int nPages,
|
||||||
|
BlockNumber *pages);
|
||||||
|
|
||||||
|
extern void FreeSpaceMapTruncateRel(RelFileNode *rel, BlockNumber nblocks);
|
||||||
extern void FreeSpaceMapForgetRel(RelFileNode *rel);
|
extern void FreeSpaceMapForgetRel(RelFileNode *rel);
|
||||||
extern void FreeSpaceMapForgetDatabase(Oid dbid);
|
extern void FreeSpaceMapForgetDatabase(Oid dbid);
|
||||||
|
|
||||||
|
extern void PrintFreeSpaceMapStatistics(int elevel);
|
||||||
|
|
||||||
#ifdef FREESPACE_DEBUG
|
#ifdef FREESPACE_DEBUG
|
||||||
extern void DumpFreeSpace(void);
|
extern void DumpFreeSpace(void);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user