mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Rely on relcache invalidation to update the cached size of the FSM.
This commit is contained in:
parent
df559de9c1
commit
9858a8c81c
@ -11,7 +11,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.63 2008/11/19 10:34:50 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.64 2008/11/26 17:08:57 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -376,7 +376,7 @@ CreateFakeRelcacheEntry(RelFileNode rnode)
|
|||||||
rel->rd_lockInfo.lockRelId.relId = rnode.relNode;
|
rel->rd_lockInfo.lockRelId.relId = rnode.relNode;
|
||||||
|
|
||||||
rel->rd_targblock = InvalidBlockNumber;
|
rel->rd_targblock = InvalidBlockNumber;
|
||||||
rel->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
rel->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
rel->rd_smgr = NULL;
|
rel->rd_smgr = NULL;
|
||||||
|
|
||||||
return rel;
|
return rel;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.67 2008/11/19 10:34:52 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.68 2008/11/26 17:08:57 heikki Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
@ -101,7 +101,7 @@ static BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot);
|
|||||||
static BlockNumber fsm_logical_to_physical(FSMAddress addr);
|
static BlockNumber fsm_logical_to_physical(FSMAddress addr);
|
||||||
|
|
||||||
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend);
|
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend);
|
||||||
static void fsm_extend(Relation rel, BlockNumber nfsmblocks, bool createstorage);
|
static void fsm_extend(Relation rel, BlockNumber fsm_nblocks);
|
||||||
|
|
||||||
/* functions to convert amount of free space to a FSM category */
|
/* functions to convert amount of free space to a FSM category */
|
||||||
static uint8 fsm_space_avail_to_cat(Size avail);
|
static uint8 fsm_space_avail_to_cat(Size avail);
|
||||||
@ -303,13 +303,13 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
|
|||||||
smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks, rel->rd_istemp);
|
smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks, rel->rd_istemp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need to invalidate the relcache entry, because rd_fsm_nblocks_cache
|
* Need to invalidate the relcache entry, because rd_fsm_nblocks
|
||||||
* seen by other backends is no longer valid.
|
* seen by other backends is no longer valid.
|
||||||
*/
|
*/
|
||||||
if (!InRecovery)
|
if (!InRecovery)
|
||||||
CacheInvalidateRelcache(rel);
|
CacheInvalidateRelcache(rel);
|
||||||
|
|
||||||
rel->rd_fsm_nblocks_cache = new_nfsmblocks;
|
rel->rd_fsm_nblocks = new_nfsmblocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -503,19 +503,20 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
|
|||||||
|
|
||||||
RelationOpenSmgr(rel);
|
RelationOpenSmgr(rel);
|
||||||
|
|
||||||
if (rel->rd_fsm_nblocks_cache == InvalidBlockNumber ||
|
/* If we haven't cached the size of the FSM yet, check it first */
|
||||||
rel->rd_fsm_nblocks_cache <= blkno)
|
if (rel->rd_fsm_nblocks == InvalidBlockNumber)
|
||||||
{
|
{
|
||||||
if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
|
if (smgrexists(rel->rd_smgr, FSM_FORKNUM))
|
||||||
fsm_extend(rel, blkno + 1, true);
|
rel->rd_fsm_nblocks = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
|
||||||
else
|
else
|
||||||
rel->rd_fsm_nblocks_cache = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
|
rel->rd_fsm_nblocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blkno >= rel->rd_fsm_nblocks_cache)
|
/* Handle requests beyond EOF */
|
||||||
|
if (blkno >= rel->rd_fsm_nblocks)
|
||||||
{
|
{
|
||||||
if (extend)
|
if (extend)
|
||||||
fsm_extend(rel, blkno + 1, false);
|
fsm_extend(rel, blkno + 1);
|
||||||
else
|
else
|
||||||
return InvalidBuffer;
|
return InvalidBuffer;
|
||||||
}
|
}
|
||||||
@ -536,13 +537,12 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
|
|||||||
/*
|
/*
|
||||||
* Ensure that the FSM fork is at least n_fsmblocks long, extending
|
* Ensure that the FSM fork is at least n_fsmblocks long, extending
|
||||||
* it if necessary with empty pages. And by empty, I mean pages filled
|
* it if necessary with empty pages. And by empty, I mean pages filled
|
||||||
* with zeros, meaning there's no free space. If createstorage is true,
|
* with zeros, meaning there's no free space.
|
||||||
* the FSM file might need to be created first.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fsm_extend(Relation rel, BlockNumber n_fsmblocks, bool createstorage)
|
fsm_extend(Relation rel, BlockNumber fsm_nblocks)
|
||||||
{
|
{
|
||||||
BlockNumber n_fsmblocks_now;
|
BlockNumber fsm_nblocks_now;
|
||||||
Page pg;
|
Page pg;
|
||||||
|
|
||||||
pg = (Page) palloc(BLCKSZ);
|
pg = (Page) palloc(BLCKSZ);
|
||||||
@ -561,27 +561,30 @@ fsm_extend(Relation rel, BlockNumber n_fsmblocks, bool createstorage)
|
|||||||
LockRelationForExtension(rel, ExclusiveLock);
|
LockRelationForExtension(rel, ExclusiveLock);
|
||||||
|
|
||||||
/* Create the FSM file first if it doesn't exist */
|
/* Create the FSM file first if it doesn't exist */
|
||||||
if (createstorage && !smgrexists(rel->rd_smgr, FSM_FORKNUM))
|
if ((rel->rd_fsm_nblocks == 0 || rel->rd_fsm_nblocks == InvalidBlockNumber)
|
||||||
|
&& !smgrexists(rel->rd_smgr, FSM_FORKNUM))
|
||||||
{
|
{
|
||||||
smgrcreate(rel->rd_smgr, FSM_FORKNUM, false);
|
smgrcreate(rel->rd_smgr, FSM_FORKNUM, false);
|
||||||
n_fsmblocks_now = 0;
|
fsm_nblocks_now = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
n_fsmblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
|
fsm_nblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
|
||||||
|
|
||||||
while (n_fsmblocks_now < n_fsmblocks)
|
while (fsm_nblocks_now < fsm_nblocks)
|
||||||
{
|
{
|
||||||
smgrextend(rel->rd_smgr, FSM_FORKNUM, n_fsmblocks_now,
|
smgrextend(rel->rd_smgr, FSM_FORKNUM, fsm_nblocks_now,
|
||||||
(char *) pg, rel->rd_istemp);
|
(char *) pg, rel->rd_istemp);
|
||||||
n_fsmblocks_now++;
|
fsm_nblocks_now++;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockRelationForExtension(rel, ExclusiveLock);
|
UnlockRelationForExtension(rel, ExclusiveLock);
|
||||||
|
|
||||||
pfree(pg);
|
pfree(pg);
|
||||||
|
|
||||||
/* update the cache with the up-to-date size */
|
/* Update the relcache with the up-to-date size */
|
||||||
rel->rd_fsm_nblocks_cache = n_fsmblocks_now;
|
if (!InRecovery)
|
||||||
|
CacheInvalidateRelcache(rel);
|
||||||
|
rel->rd_fsm_nblocks = fsm_nblocks_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
16
src/backend/utils/cache/relcache.c
vendored
16
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.276 2008/11/10 00:49:37 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.277 2008/11/26 17:08:57 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -304,7 +304,7 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
|||||||
*/
|
*/
|
||||||
MemSet(relation, 0, sizeof(RelationData));
|
MemSet(relation, 0, sizeof(RelationData));
|
||||||
relation->rd_targblock = InvalidBlockNumber;
|
relation->rd_targblock = InvalidBlockNumber;
|
||||||
relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
relation->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
|
|
||||||
/* make sure relation is marked as having no open file yet */
|
/* make sure relation is marked as having no open file yet */
|
||||||
relation->rd_smgr = NULL;
|
relation->rd_smgr = NULL;
|
||||||
@ -1376,7 +1376,7 @@ formrdesc(const char *relationName, Oid relationReltype,
|
|||||||
*/
|
*/
|
||||||
relation = (Relation) palloc0(sizeof(RelationData));
|
relation = (Relation) palloc0(sizeof(RelationData));
|
||||||
relation->rd_targblock = InvalidBlockNumber;
|
relation->rd_targblock = InvalidBlockNumber;
|
||||||
relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
relation->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
|
|
||||||
/* make sure relation is marked as having no open file yet */
|
/* make sure relation is marked as having no open file yet */
|
||||||
relation->rd_smgr = NULL;
|
relation->rd_smgr = NULL;
|
||||||
@ -1665,9 +1665,9 @@ RelationReloadIndexInfo(Relation relation)
|
|||||||
heap_freetuple(pg_class_tuple);
|
heap_freetuple(pg_class_tuple);
|
||||||
/* We must recalculate physical address in case it changed */
|
/* We must recalculate physical address in case it changed */
|
||||||
RelationInitPhysicalAddr(relation);
|
RelationInitPhysicalAddr(relation);
|
||||||
/* Must reset targblock and fsm_nblocks_cache in case rel was truncated */
|
/* Must reset targblock and fsm_nblocks in case rel was truncated */
|
||||||
relation->rd_targblock = InvalidBlockNumber;
|
relation->rd_targblock = InvalidBlockNumber;
|
||||||
relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
relation->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
/* Must free any AM cached data, too */
|
/* Must free any AM cached data, too */
|
||||||
if (relation->rd_amcache)
|
if (relation->rd_amcache)
|
||||||
pfree(relation->rd_amcache);
|
pfree(relation->rd_amcache);
|
||||||
@ -1750,7 +1750,7 @@ RelationClearRelation(Relation relation, bool rebuild)
|
|||||||
if (relation->rd_isnailed)
|
if (relation->rd_isnailed)
|
||||||
{
|
{
|
||||||
relation->rd_targblock = InvalidBlockNumber;
|
relation->rd_targblock = InvalidBlockNumber;
|
||||||
relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
relation->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
if (relation->rd_rel->relkind == RELKIND_INDEX)
|
if (relation->rd_rel->relkind == RELKIND_INDEX)
|
||||||
{
|
{
|
||||||
relation->rd_isvalid = false; /* needs to be revalidated */
|
relation->rd_isvalid = false; /* needs to be revalidated */
|
||||||
@ -2345,7 +2345,7 @@ RelationBuildLocalRelation(const char *relname,
|
|||||||
rel = (Relation) palloc0(sizeof(RelationData));
|
rel = (Relation) palloc0(sizeof(RelationData));
|
||||||
|
|
||||||
rel->rd_targblock = InvalidBlockNumber;
|
rel->rd_targblock = InvalidBlockNumber;
|
||||||
rel->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
rel->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
|
|
||||||
/* make sure relation is marked as having no open file yet */
|
/* make sure relation is marked as having no open file yet */
|
||||||
rel->rd_smgr = NULL;
|
rel->rd_smgr = NULL;
|
||||||
@ -3602,7 +3602,7 @@ load_relcache_init_file(void)
|
|||||||
*/
|
*/
|
||||||
rel->rd_smgr = NULL;
|
rel->rd_smgr = NULL;
|
||||||
rel->rd_targblock = InvalidBlockNumber;
|
rel->rd_targblock = InvalidBlockNumber;
|
||||||
rel->rd_fsm_nblocks_cache = InvalidBlockNumber;
|
rel->rd_fsm_nblocks = InvalidBlockNumber;
|
||||||
if (rel->rd_isnailed)
|
if (rel->rd_isnailed)
|
||||||
rel->rd_refcnt = 1;
|
rel->rd_refcnt = 1;
|
||||||
else
|
else
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.108 2008/09/30 10:52:14 heikki Exp $
|
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.109 2008/11/26 17:08:58 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -195,8 +195,8 @@ typedef struct RelationData
|
|||||||
List *rd_indpred; /* index predicate tree, if any */
|
List *rd_indpred; /* index predicate tree, if any */
|
||||||
void *rd_amcache; /* available for use by index AM */
|
void *rd_amcache; /* available for use by index AM */
|
||||||
|
|
||||||
/* Cached last-seen size of the FSM */
|
/* size of the FSM, or InvalidBlockNumber if not known yet */
|
||||||
BlockNumber rd_fsm_nblocks_cache;
|
BlockNumber rd_fsm_nblocks;
|
||||||
|
|
||||||
/* use "struct" here to avoid needing to include pgstat.h: */
|
/* use "struct" here to avoid needing to include pgstat.h: */
|
||||||
struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
|
struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user