mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
Rewrite the FSM. Instead of relying on a fixed-size shared memory segment, the
free space information is stored in a dedicated FSM relation fork, with each relation (except for hash indexes; they don't use FSM). This eliminates the max_fsm_relations and max_fsm_pages GUC options; remove any trace of them from the backend, initdb, and documentation. Rewrite contrib/pg_freespacemap to match the new FSM implementation. Also introduce a new variant of the get_raw_page(regclass, int4, int4) function in contrib/pageinspect that let's you to return pages from any relation fork, and a new fsm_page_contents() function to inspect the new FSM pages.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.151 2008/06/12 09:12:29 heikki Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.152 2008/09/30 10:52:10 heikki Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -19,6 +19,7 @@
|
||||
#include "catalog/index.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/indexfsm.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
const XLogRecPtr XLogRecPtrForTemp = {1, 1};
|
||||
@ -102,6 +103,9 @@ gistbuild(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "index \"%s\" already contains data",
|
||||
RelationGetRelationName(index));
|
||||
|
||||
/* Initialize FSM */
|
||||
InitIndexFreeSpaceMap(index);
|
||||
|
||||
/* no locking is needed */
|
||||
initGISTstate(&buildstate.giststate, index);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.30 2008/07/13 20:45:46 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.31 2008/09/30 10:52:10 heikki Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -16,6 +16,7 @@
|
||||
#include "access/gist_private.h"
|
||||
#include "access/reloptions.h"
|
||||
#include "storage/freespace.h"
|
||||
#include "storage/indexfsm.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "utils/rel.h"
|
||||
@ -617,7 +618,7 @@ gistNewBuffer(Relation r)
|
||||
/* First, try to get a page from FSM */
|
||||
for (;;)
|
||||
{
|
||||
BlockNumber blkno = GetFreeIndexPage(&r->rd_node);
|
||||
BlockNumber blkno = GetFreeIndexPage(r);
|
||||
|
||||
if (blkno == InvalidBlockNumber)
|
||||
break; /* nothing left in FSM */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.36 2008/06/12 09:12:30 heikki Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.37 2008/09/30 10:52:10 heikki Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -20,6 +20,7 @@
|
||||
#include "miscadmin.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/freespace.h"
|
||||
#include "storage/indexfsm.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
@ -518,10 +519,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
||||
Relation rel = info->index;
|
||||
BlockNumber npages,
|
||||
blkno;
|
||||
BlockNumber totFreePages,
|
||||
nFreePages,
|
||||
*freePages,
|
||||
maxFreePages;
|
||||
BlockNumber totFreePages;
|
||||
BlockNumber lastBlock = GIST_ROOT_BLKNO,
|
||||
lastFilledBlock = GIST_ROOT_BLKNO;
|
||||
bool needLock;
|
||||
@ -589,13 +587,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
||||
if (needLock)
|
||||
UnlockRelationForExtension(rel, ExclusiveLock);
|
||||
|
||||
maxFreePages = npages;
|
||||
if (maxFreePages > MaxFSMPages)
|
||||
maxFreePages = MaxFSMPages;
|
||||
|
||||
totFreePages = nFreePages = 0;
|
||||
freePages = (BlockNumber *) palloc(sizeof(BlockNumber) * maxFreePages);
|
||||
|
||||
totFreePages = 0;
|
||||
for (blkno = GIST_ROOT_BLKNO + 1; blkno < npages; blkno++)
|
||||
{
|
||||
Buffer buffer;
|
||||
@ -609,9 +601,8 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
||||
|
||||
if (PageIsNew(page) || GistPageIsDeleted(page))
|
||||
{
|
||||
if (nFreePages < maxFreePages)
|
||||
freePages[nFreePages++] = blkno;
|
||||
totFreePages++;
|
||||
RecordFreeIndexPage(rel, blkno);
|
||||
}
|
||||
else
|
||||
lastFilledBlock = blkno;
|
||||
@ -619,25 +610,15 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
||||
}
|
||||
lastBlock = npages - 1;
|
||||
|
||||
if (info->vacuum_full && nFreePages > 0)
|
||||
if (info->vacuum_full && lastFilledBlock < lastBlock)
|
||||
{ /* try to truncate index */
|
||||
int i;
|
||||
FreeSpaceMapTruncateRel(rel, lastFilledBlock + 1);
|
||||
RelationTruncate(rel, lastFilledBlock + 1);
|
||||
|
||||
for (i = 0; i < nFreePages; i++)
|
||||
if (freePages[i] >= lastFilledBlock)
|
||||
{
|
||||
totFreePages = nFreePages = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastBlock > lastFilledBlock)
|
||||
RelationTruncate(rel, lastFilledBlock + 1);
|
||||
stats->std.pages_removed = lastBlock - lastFilledBlock;
|
||||
totFreePages = totFreePages - stats->std.pages_removed;
|
||||
}
|
||||
|
||||
RecordIndexFreeSpace(&rel->rd_node, totFreePages, nFreePages, freePages);
|
||||
pfree(freePages);
|
||||
|
||||
/* return statistics */
|
||||
stats->std.pages_free = totFreePages;
|
||||
if (needLock)
|
||||
|
Reference in New Issue
Block a user