mirror of
https://github.com/postgres/postgres.git
synced 2025-08-24 09:27:52 +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:
92
src/backend/storage/freespace/indexfsm.c
Normal file
92
src/backend/storage/freespace/indexfsm.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* indexfsm.c
|
||||
* POSTGRES free space map for quickly finding free pages in relations
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/freespace/indexfsm.c,v 1.1 2008/09/30 10:52:13 heikki Exp $
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* This is similar to the FSM used for heap, in freespace.c, but instead
|
||||
* of tracking the amount of free space on pages, we only track whether
|
||||
* pages are completely free or in-use. We use the same FSM implementation
|
||||
* as for heaps, using BLCKSZ - 1 to denote used pages, and 0 for unused.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/freespace.h"
|
||||
#include "storage/indexfsm.h"
|
||||
#include "storage/smgr.h"
|
||||
|
||||
/*
|
||||
* Exported routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* InitIndexFreeSpaceMap - Create or reset the FSM fork for relation.
|
||||
*/
|
||||
void
|
||||
InitIndexFreeSpaceMap(Relation rel)
|
||||
{
|
||||
/* Create FSM fork if it doesn't exist yet, or truncate it if it does */
|
||||
RelationOpenSmgr(rel);
|
||||
if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
|
||||
smgrcreate(rel->rd_smgr, FSM_FORKNUM, rel->rd_istemp, false);
|
||||
else
|
||||
smgrtruncate(rel->rd_smgr, FSM_FORKNUM, 0, rel->rd_istemp);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetFreeIndexPage - return a free page from the FSM
|
||||
*
|
||||
* As a side effect, the page is marked as used in the FSM.
|
||||
*/
|
||||
BlockNumber
|
||||
GetFreeIndexPage(Relation rel)
|
||||
{
|
||||
BlockNumber blkno = GetPageWithFreeSpace(rel, BLCKSZ/2);
|
||||
|
||||
if (blkno != InvalidBlockNumber)
|
||||
RecordUsedIndexPage(rel, blkno);
|
||||
|
||||
return blkno;
|
||||
}
|
||||
|
||||
/*
|
||||
* RecordFreeIndexPage - mark a page as free in the FSM
|
||||
*/
|
||||
void
|
||||
RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
|
||||
{
|
||||
RecordPageWithFreeSpace(rel, freeBlock, BLCKSZ - 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RecordUsedIndexPage - mark a page as used in the FSM
|
||||
*/
|
||||
void
|
||||
RecordUsedIndexPage(Relation rel, BlockNumber usedBlock)
|
||||
{
|
||||
RecordPageWithFreeSpace(rel, usedBlock, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* IndexFreeSpaceMapTruncate - adjust for truncation of a relation.
|
||||
*
|
||||
* We need to delete any stored data past the new relation length, so that
|
||||
* we don't bogusly return removed block numbers.
|
||||
*/
|
||||
void
|
||||
IndexFreeSpaceMapTruncate(Relation rel, BlockNumber nblocks)
|
||||
{
|
||||
FreeSpaceMapTruncateRel(rel, nblocks);
|
||||
}
|
Reference in New Issue
Block a user