Commit e0c9301c authored by Tom Lane's avatar Tom Lane

Install infrastructure for shared-memory free space map. Doesn't actually

do anything yet, but it has the necessary connections to initialization
and so forth.  Make some gestures towards allowing number of blocks in
a relation to be BlockNumber, ie, unsigned int, rather than signed int.
(I doubt I got all the places that are sloppy about it, yet.)  On the
way, replace the hardwired NLOCKS_PER_XACT fudge factor with a GUC
variable.
parent b5593821
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.69 2001/06/23 00:03:10 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.70 2001/06/27 23:31:37 tgl Exp $
-->
<Chapter Id="runtime">
......@@ -1131,6 +1131,42 @@ dynamic_library_path = '/usr/local/lib:/home/my_project/lib:$libdir:$libdir/cont
</listitem>
</varlistentry>
<varlistentry>
<term>MAX_FSM_RELATIONS (<type>integer</type>)</term>
<listitem>
<para>
Sets the maximum number of relations (tables) for which free space
will be tracked in the shared free-space map.
The default is 100. This option can only be set at server start.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MAX_FSM_PAGES (<type>integer</type>)</term>
<listitem>
<para>
Sets the maximum number of disk pages for which free space
will be tracked in the shared free-space map.
The default is 10000. This option can only be set at server start.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MAX_LOCKS_PER_XACT (<type>integer</type>)</term>
<listitem>
<para>
The shared lock table is sized on the assumption that at most
max_locks_per_xact * max_connections distinct objects will need
to be locked at any one time. The default, 64, has historically
proven sufficient, but you might need to raise this value if you
have clients that touch many different tables in a single transaction.
This option can only be set at server start.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>PORT (<type>integer</type>)</term>
<listitem>
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.30 2001/03/07 21:20:26 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.31 2001/06/27 23:31:37 tgl Exp $
*
* NOTES
* Postgres hash pages look like ordinary relation pages. The opaque
......@@ -70,18 +70,15 @@ _hash_metapinit(Relation rel)
int nbuckets;
uint32 nelem; /* number elements */
uint32 lg2nelem; /* _hash_log2(nelem) */
uint32 nblocks;
uint16 i;
/* can't be sharing this with anyone, now... */
if (USELOCKING)
LockRelation(rel, AccessExclusiveLock);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{
if (RelationGetNumberOfBlocks(rel) != 0)
elog(ERROR, "Cannot initialize non-empty hash table %s",
RelationGetRelationName(rel));
}
metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
pg = BufferGetPage(metabuf);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.119 2001/06/22 19:16:20 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.120 2001/06/27 23:31:38 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -121,8 +121,8 @@ heapgettup(Relation relation,
{
ItemId lpp;
Page dp;
int page;
int pages;
BlockNumber page;
BlockNumber pages;
int lines;
OffsetNumber lineoff;
int linesleft;
......@@ -172,7 +172,7 @@ heapgettup(Relation relation,
/*
* return null immediately if relation is empty
*/
if (!(pages = relation->rd_nblocks))
if ((pages = relation->rd_nblocks) == 0)
{
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
......@@ -233,15 +233,8 @@ heapgettup(Relation relation,
{
page = ItemPointerGetBlockNumber(tid); /* current page */
}
if (page < 0)
{
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
}
Assert(page < pages);
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
......@@ -283,15 +276,7 @@ heapgettup(Relation relation,
OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
}
if (page >= pages)
{
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
}
Assert(page < pages);
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
......@@ -369,12 +354,11 @@ heapgettup(Relation relation,
* and it's time to move to the next.
*/
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
page = (dir < 0) ? (page - 1) : (page + 1);
/*
* return NULL if we've exhausted all the pages
*/
if (page < 0 || page >= pages)
if ((dir < 0) ? (page == 0) : (page+1 >= pages))
{
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
......@@ -384,6 +368,10 @@ heapgettup(Relation relation,
return;
}
page = (dir < 0) ? (page - 1) : (page + 1);
Assert(page < pages);
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Id: hio.c,v 1.39 2001/05/16 22:35:12 tgl Exp $
* $Id: hio.c,v 1.40 2001/06/27 23:31:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -147,7 +147,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
*/
relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
if ((BlockNumber) relation->rd_nblocks > oldnblocks)
if (relation->rd_nblocks > oldnblocks)
{
/*
* Someone else has indeed extended the relation recently.
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.51 2001/03/22 03:59:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.52 2001/06/27 23:31:38 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
......@@ -55,7 +55,6 @@ _bt_metapinit(Relation rel)
{
Buffer buf;
Page pg;
int nblocks;
BTMetaPageData metad;
BTPageOpaque op;
......@@ -63,11 +62,9 @@ _bt_metapinit(Relation rel)
if (USELOCKING)
LockRelation(rel, AccessExclusiveLock);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{
if (RelationGetNumberOfBlocks(rel) != 0)
elog(ERROR, "Cannot initialize non-empty btree %s",
RelationGetRelationName(rel));
}
buf = ReadBuffer(rel, P_NEW);
pg = BufferGetPage(buf);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.168 2001/06/18 16:13:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.169 2001/06/27 23:31:38 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -1089,6 +1089,7 @@ RelationTruncateIndexes(Oid heapId)
/* Now truncate the actual data and set blocks to zero */
smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
currentIndex->rd_nblocks = 0;
currentIndex->rd_targblock = InvalidBlockNumber;
/* Initialize the index and rebuild */
InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
......@@ -1143,9 +1144,9 @@ heap_truncate(char *relname)
DropRelationBuffers(rel);
/* Now truncate the actual data and set blocks to zero */
smgrtruncate(DEFAULT_SMGR, rel, 0);
rel->rd_nblocks = 0;
rel->rd_targblock = InvalidBlockNumber;
/* If this relation has indexes, truncate the indexes too */
RelationTruncateIndexes(rid);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.154 2001/06/12 05:55:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.155 2001/06/27 23:31:38 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -1456,7 +1456,7 @@ UpdateStats(Oid relid, double reltuples)
Relation pg_class;
HeapTuple tuple;
HeapTuple newtup;
long relpages;
BlockNumber relpages;
int i;
Form_pg_class rd_rel;
Relation idescs[Num_pg_class_indices];
......@@ -1558,7 +1558,7 @@ UpdateStats(Oid relid, double reltuples)
reltuples = 1000;
}
else
reltuples = relpages * NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
reltuples = (double) relpages * NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
}
/*
......@@ -1566,7 +1566,7 @@ UpdateStats(Oid relid, double reltuples)
* place with the new values so that the cache contains the latest
* copy.
*/
whichRel->rd_rel->relpages = relpages;
whichRel->rd_rel->relpages = (int32) relpages;
whichRel->rd_rel->reltuples = reltuples;
/*
......@@ -1581,7 +1581,7 @@ UpdateStats(Oid relid, double reltuples)
*/
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
rd_rel->relpages = relpages;
rd_rel->relpages = (int32) relpages;
rd_rel->reltuples = reltuples;
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
......@@ -1600,7 +1600,7 @@ UpdateStats(Oid relid, double reltuples)
}
replace[Anum_pg_class_relpages - 1] = 'r';
values[Anum_pg_class_relpages - 1] = Int32GetDatum(relpages);
values[Anum_pg_class_relpages - 1] = Int32GetDatum((int32) relpages);
replace[Anum_pg_class_reltuples - 1] = 'r';
values[Anum_pg_class_reltuples - 1] = Float4GetDatum((float4) reltuples);
newtup = heap_modifytuple(tuple, pg_class, values, nulls, replace);
......@@ -1962,6 +1962,7 @@ reindex_index(Oid indexId, bool force, bool inplace)
/* Now truncate the actual data and set blocks to zero */
smgrtruncate(DEFAULT_SMGR, iRel, 0);
iRel->rd_nblocks = 0;
iRel->rd_targblock = InvalidBlockNumber;
}
/* Initialize the index and rebuild */
......
This diff is collapsed.
#
# Makefile for the storage manager subsystem
#
# $Header: /cvsroot/pgsql/src/backend/storage/Makefile,v 1.8 2000/08/31 16:10:30 petere Exp $
# $Header: /cvsroot/pgsql/src/backend/storage/Makefile,v 1.9 2001/06/27 23:31:39 tgl Exp $
#
subdir = src/backend/storage
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
SUBDIRS := buffer file ipc large_object lmgr page smgr
SUBDIRS := buffer file freespace ipc large_object lmgr page smgr
SUBDIROBJS := $(SUBDIRS:%=%/SUBSYS.o)
all: SUBSYS.o
......
#-------------------------------------------------------------------------
#
# Makefile--
# Makefile for storage/freespace
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/storage/freespace/Makefile,v 1.1 2001/06/27 23:31:39 tgl Exp $
#
#-------------------------------------------------------------------------
subdir = src/backend/storage/freespace
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = freespace.o
all: SUBSYS.o
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
clean:
rm -f SUBSYS.o $(OBJS)
ifeq (depend,$(wildcard depend))
include depend
endif
/*-------------------------------------------------------------------------
*
* freespace.c
* POSTGRES free space map for quickly finding free space in relations
*
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.1 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "storage/freespace.h"
#include "storage/itemid.h"
#include "storage/shmem.h"
/*
* Shared free-space-map objects
*
* Note: we handle pointers to these items as pointers, not as SHMEM_OFFSETs.
* This assumes that all processes accessing the map will have the shared
* memory segment mapped at the same place in their address space.
*/
typedef struct FSMHeader FSMHeader;
typedef struct FSMRelation FSMRelation;
typedef struct FSMChunk FSMChunk;
/* Header for whole map */
struct FSMHeader
{
HTAB *relationHash; /* hashtable of FSMRelation entries */
FSMRelation *relationList; /* FSMRelations in order by recency of use */
int numRelations; /* number of FSMRelations now in use */
FSMChunk *freeChunks; /* linked list of currently-free chunks */
};
/*
* Per-relation struct --- this is an entry in the shared hash table.
* The hash key is the RelFileNode value (hence, we look at the physical
* relation ID, not the logical ID, which is appropriate).
*/
struct FSMRelation
{
RelFileNode key; /* hash key (must be first) */
FSMRelation *nextRel; /* next rel in order by recency of use */
FSMRelation *priorRel; /* prior rel in order by recency of use */
FSMChunk *relChunks; /* linked list of page info chunks */
};
#define SHMEM_FSMHASH_KEYSIZE sizeof(RelFileNode)
#define SHMEM_FSMHASH_DATASIZE (sizeof(FSMRelation) - SHMEM_FSMHASH_KEYSIZE)
#define CHUNKPAGES 32 /* each chunk can store this many pages */
struct FSMChunk
{
FSMChunk *next; /* linked-list link */
int numPages; /* number of pages described here */
BlockNumber pages[CHUNKPAGES]; /* page numbers within relation */
ItemLength bytes[CHUNKPAGES]; /* free space available on each page */
};
SPINLOCK FreeSpaceLock; /* in Shmem or created in
* CreateSpinlocks() */
int MaxFSMRelations; /* these are set by guc.c */
int MaxFSMPages;
static FSMHeader *FreeSpaceMap; /* points to FSMHeader in shared memory */
/*
* InitFreeSpaceMap -- Initialize the freespace module.
*
* This must be called once during shared memory initialization.
* It builds the empty free space map table. FreeSpaceLock must also be
* initialized at some point, but is not touched here --- we assume there is
* no need for locking, since only the calling process can be accessing shared
* memory as yet. FreeSpaceShmemSize() was called previously while computing
* the space needed for shared memory.
*/
void
InitFreeSpaceMap(void)
{
HASHCTL info;
FSMChunk *chunks,
*prevchunk;
int nchunks;
/* Create table header */
FreeSpaceMap = (FSMHeader *) ShmemAlloc(sizeof(FSMHeader));
if (FreeSpaceMap == NULL)
elog(FATAL, "Insufficient shared memory for free space map");
MemSet(FreeSpaceMap, 0, sizeof(FSMHeader));
/* Create hashtable for FSMRelations */
info.keysize = SHMEM_FSMHASH_KEYSIZE;
info.datasize = SHMEM_FSMHASH_DATASIZE;
info.hash = tag_hash;
FreeSpaceMap->relationHash = ShmemInitHash("Free Space Map Hash",
MaxFSMRelations / 10,
MaxFSMRelations,
&info,
(HASH_ELEM | HASH_FUNCTION));
if (!FreeSpaceMap->relationHash)
elog(FATAL, "Insufficient shared memory for free space map");
/* Allocate FSMChunks and fill up the free-chunks list */
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
chunks = (FSMChunk *) ShmemAlloc(nchunks * sizeof(FSMChunk));
if (chunks == NULL)
elog(FATAL, "Insufficient shared memory for free space map");
prevchunk = NULL;
while (nchunks-- > 0)
{
chunks->next = prevchunk;
prevchunk = chunks;
chunks++;
}
FreeSpaceMap->freeChunks = prevchunk;
}
int
FreeSpaceShmemSize(void)
{
int size;
int nchunks;
/*
* There is no point in allowing less than one "chunk" per relation,
* so force MaxFSMPages to be at least CHUNKPAGES * MaxFSMRelations.
*/
Assert(MaxFSMRelations > 0);
if (MaxFSMPages < CHUNKPAGES * MaxFSMRelations)
MaxFSMPages = CHUNKPAGES * MaxFSMRelations;
/* table header */
size = MAXALIGN(sizeof(FSMHeader));
/* hash table, including the FSMRelation objects */
size += hash_estimate_size(MaxFSMRelations,
SHMEM_FSMHASH_KEYSIZE,
SHMEM_FSMHASH_DATASIZE);
/* FSMChunk objects */
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
size += MAXALIGN(nchunks * sizeof(FSMChunk));
return size;
}
void
FreeSpaceMapForgetRel(RelFileNode *rel)
{
}
#ifdef FREESPACE_DEBUG
/*
* Dump contents of freespace map for debugging.
*
* We assume caller holds the FreeSpaceLock, or is otherwise unconcerned
* about other processes.
*/
void
DumpFreeSpace(void)
{
}
#endif /* FREESPACE_DEBUG */
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.40 2001/03/22 03:59:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.41 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -19,6 +19,7 @@
#include "miscadmin.h"
#include "access/xlog.h"
#include "storage/bufmgr.h"
#include "storage/freespace.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/sinval.h"
......@@ -47,8 +48,12 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int maxBackends)
* moderately-accurate estimates for the big hogs, plus 100K for the
* stuff that's too small to bother with estimating.
*/
size = BufferShmemSize() + LockShmemSize(maxBackends) +
XLOGShmemSize() + SLockShmemSize() + SInvalShmemSize(maxBackends);
size = BufferShmemSize();
size += LockShmemSize(maxBackends);
size += XLOGShmemSize();
size += SLockShmemSize();
size += SInvalShmemSize(maxBackends);
size += FreeSpaceShmemSize();
#ifdef STABLE_MEMORY_STORAGE
size += MMShmemSize();
#endif
......@@ -96,4 +101,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int maxBackends)
* Set up shared-inval messaging
*/
CreateSharedInvalidationState(maxBackends);
/*
* Set up free-space map
*/
InitFreeSpaceMap();
}
......@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.32 2001/03/22 03:59:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.33 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -31,19 +31,18 @@
/* Probably should move these to an appropriate header file */
extern SPINLOCK ShmemLock;
extern SPINLOCK ShmemIndexLock;
extern SPINLOCK BufMgrLock;
extern SPINLOCK LockMgrLock;
extern SPINLOCK ProcStructLock;
extern SPINLOCK SInvalLock;
extern SPINLOCK OidGenLockId;
extern SPINLOCK XidGenLockId;
extern SPINLOCK ControlFileLockId;
extern SPINLOCK ShmemLock;
extern SPINLOCK ShmemIndexLock;
extern SPINLOCK LockMgrLock;
extern SPINLOCK SInvalLock;
extern SPINLOCK ProcStructLock;
extern SPINLOCK FreeSpaceLock;
#ifdef STABLE_MEMORY_STORAGE
extern SPINLOCK MMCacheLock;
#endif
......@@ -57,16 +56,16 @@ extern SPINLOCK MMCacheLock;
static void
InitSpinLockIDs(void)
{
ShmemLock = (SPINLOCK) SHMEMLOCKID;
ShmemIndexLock = (SPINLOCK) SHMEMINDEXLOCKID;
BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
SInvalLock = (SPINLOCK) SINVALLOCKID;
OidGenLockId = (SPINLOCK) OIDGENLOCKID;
XidGenLockId = (SPINLOCK) XIDGENLOCKID;
ControlFileLockId = (SPINLOCK) CNTLFILELOCKID;
ShmemLock = (SPINLOCK) SHMEMLOCKID;
ShmemIndexLock = (SPINLOCK) SHMEMINDEXLOCKID;
LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
SInvalLock = (SPINLOCK) SINVALLOCKID;
ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
FreeSpaceLock = (SPINLOCK) FREESPACELOCKID;
#ifdef STABLE_MEMORY_STORAGE
MMCacheLock = (SPINLOCK) MMCACHELOCKID;
#endif
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.89 2001/06/22 00:04:59 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.90 2001/06/27 23:31:39 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
......@@ -40,6 +40,13 @@
#include "utils/memutils.h"
#include "utils/ps_status.h"
/* This configuration variable is used to set the lock table size */
int max_locks_per_xact; /* set by guc.c */
#define NLOCKENTS(maxBackends) (max_locks_per_xact * (maxBackends))
static int WaitOnLock(LOCKMETHOD lockmethod, LOCKMODE lockmode,
LOCK *lock, HOLDER *holder);
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PROC *proc,
......@@ -1388,6 +1395,7 @@ int
LockShmemSize(int maxBackends)
{
int size = 0;
long max_table_size = NLOCKENTS(maxBackends);
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
size += maxBackends * MAXALIGN(sizeof(PROC)); /* each MyProc */
......@@ -1395,12 +1403,12 @@ LockShmemSize(int maxBackends)
* lockMethodTable->ctl */
/* lockHash table */
size += hash_estimate_size(NLOCKENTS(maxBackends),
size += hash_estimate_size(max_table_size,
SHMEM_LOCKTAB_KEYSIZE,
SHMEM_LOCKTAB_DATASIZE);
/* holderHash table */
size += hash_estimate_size(NLOCKENTS(maxBackends),
size += hash_estimate_size(max_table_size,
SHMEM_HOLDERTAB_KEYSIZE,
SHMEM_HOLDERTAB_DATASIZE);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.85 2001/06/06 17:07:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.86 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -72,10 +72,10 @@ static MemoryContext MdCxt; /* context for all my allocations */
/* routines declared here */
static void mdclose_fd(int fd);
static int _mdfd_getrelnfd(Relation reln);
static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags);
static MdfdVec *_mdfd_getseg(Relation reln, int blkno);
static MdfdVec *_mdfd_openseg(Relation reln, BlockNumber segno, int oflags);
static MdfdVec *_mdfd_getseg(Relation reln, BlockNumber blkno);
static int _mdfd_blind_getseg(RelFileNode rnode, int blkno);
static int _mdfd_blind_getseg(RelFileNode rnode, BlockNumber blkno);
static int _fdvec_alloc(void);
static void _fdvec_free(int);
......@@ -93,7 +93,7 @@ static BlockNumber _mdnblocks(File file, Size blcksz);
* Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mdinit()
mdinit(void)
{
int i;
......@@ -194,11 +194,11 @@ mdunlink(RelFileNode rnode)
if (status == SM_SUCCESS)
{
char *segpath = (char *) palloc(strlen(path) + 12);
int segno;
BlockNumber segno;
for (segno = 1;; segno++)
{
sprintf(segpath, "%s.%d", path, segno);
sprintf(segpath, "%s.%u", path, segno);
if (unlink(segpath) < 0)
{
/* ENOENT is expected after the last segment... */
......@@ -246,7 +246,7 @@ mdextend(Relation reln, BlockNumber blocknum, char *buffer)
v = _mdfd_getseg(reln, blocknum);
#ifndef LET_OS_MANAGE_FILESIZE
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
#ifdef DIAGNOSTIC
if (seekpos >= BLCKSZ * RELSEG_SIZE)
elog(FATAL, "seekpos too big!");
......@@ -283,7 +283,7 @@ mdextend(Relation reln, BlockNumber blocknum, char *buffer)
#ifndef LET_OS_MANAGE_FILESIZE
#ifdef DIAGNOSTIC
if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE)
if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
elog(FATAL, "segment too big!");
#endif
#endif
......@@ -338,7 +338,7 @@ mdopen(Relation reln)
Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
#ifdef DIAGNOSTIC
if (_mdnblocks(fd, BLCKSZ) > RELSEG_SIZE)
if (_mdnblocks(fd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
elog(FATAL, "segment too big on relopen!");
#endif
#endif
......@@ -438,7 +438,7 @@ mdread(Relation reln, BlockNumber blocknum, char *buffer)
v = _mdfd_getseg(reln, blocknum);
#ifndef LET_OS_MANAGE_FILESIZE
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
#ifdef DIAGNOSTIC
if (seekpos >= BLCKSZ * RELSEG_SIZE)
......@@ -482,7 +482,7 @@ mdwrite(Relation reln, BlockNumber blocknum, char *buffer)
v = _mdfd_getseg(reln, blocknum);
#ifndef LET_OS_MANAGE_FILESIZE
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
#ifdef DIAGNOSTIC
if (seekpos >= BLCKSZ * RELSEG_SIZE)
elog(FATAL, "seekpos too big!");
......@@ -516,7 +516,7 @@ mdflush(Relation reln, BlockNumber blocknum, char *buffer)
v = _mdfd_getseg(reln, blocknum);
#ifndef LET_OS_MANAGE_FILESIZE
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
#ifdef DIAGNOSTIC
if (seekpos >= BLCKSZ * RELSEG_SIZE)
elog(FATAL, "seekpos too big!");
......@@ -561,7 +561,7 @@ mdblindwrt(RelFileNode rnode,
return SM_FAIL;
#ifndef LET_OS_MANAGE_FILESIZE
seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE));
seekpos = (long) (BLCKSZ * (blkno % ((BlockNumber) RELSEG_SIZE)));
#ifdef DIAGNOSTIC
if (seekpos >= BLCKSZ * RELSEG_SIZE)
elog(FATAL, "seekpos too big!");
......@@ -659,16 +659,14 @@ mdblindmarkdirty(RelFileNode rnode,
*
* Returns # of blocks, elog's on error.
*/
int
BlockNumber
mdnblocks(Relation reln)
{
int fd;
MdfdVec *v;
#ifndef LET_OS_MANAGE_FILESIZE
int nblocks;
int segno;
BlockNumber nblocks;
BlockNumber segno;
#endif
fd = _mdfd_getrelnfd(reln);
......@@ -679,10 +677,10 @@ mdnblocks(Relation reln)
for (;;)
{
nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ);
if (nblocks > RELSEG_SIZE)
if (nblocks > ((BlockNumber) RELSEG_SIZE))
elog(FATAL, "segment too big in mdnblocks!");
if (nblocks < RELSEG_SIZE)
return (segno * RELSEG_SIZE) + nblocks;
if (nblocks < ((BlockNumber) RELSEG_SIZE))
return (segno * ((BlockNumber) RELSEG_SIZE)) + nblocks;
/*
* If segment is exactly RELSEG_SIZE, advance to next one.
*/
......@@ -713,18 +711,16 @@ mdnblocks(Relation reln)
/*
* mdtruncate() -- Truncate relation to specified number of blocks.
*
* Returns # of blocks or -1 on error.
* Returns # of blocks or InvalidBlockNumber on error.
*/
int
mdtruncate(Relation reln, int nblocks)
BlockNumber
mdtruncate(Relation reln, BlockNumber nblocks)
{
int curnblk;
int fd;
MdfdVec *v;
BlockNumber curnblk;
#ifndef LET_OS_MANAGE_FILESIZE
int priorblocks;
BlockNumber priorblocks;
#endif
/*
......@@ -732,8 +728,8 @@ mdtruncate(Relation reln, int nblocks)
* that truncate/delete loop will get them all!
*/
curnblk = mdnblocks(reln);
if (nblocks < 0 || nblocks > curnblk)
return -1; /* bogus request */
if (nblocks > curnblk)
return InvalidBlockNumber; /* bogus request */
if (nblocks == curnblk)
return nblocks; /* no work */
......@@ -748,7 +744,6 @@ mdtruncate(Relation reln, int nblocks)
if (priorblocks > nblocks)
{
/*
* This segment is no longer wanted at all (and has already
* been unlinked from the mdfd_chain). We truncate the file
......@@ -763,27 +758,25 @@ mdtruncate(Relation reln, int nblocks)
* segment */
pfree(ov);
}
else if (priorblocks + RELSEG_SIZE > nblocks)
else if (priorblocks + ((BlockNumber) RELSEG_SIZE) > nblocks)
{
/*
* This is the last segment we want to keep. Truncate the file
* to the right length, and clear chain link that points to
* any remaining segments (which we shall zap). NOTE: if
* nblocks is exactly a multiple K of RELSEG_SIZE, we will
* truncate the K+1st segment to 0 length but keep it. This is
* mainly so that the right thing happens if nblocks=0.
* mainly so that the right thing happens if nblocks==0.
*/
int lastsegblocks = nblocks - priorblocks;
BlockNumber lastsegblocks = nblocks - priorblocks;
if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0)
return -1;
return InvalidBlockNumber;
v = v->mdfd_chain;
ov->mdfd_chain = (MdfdVec *) NULL;
}
else
{
/*
* We still need this segment and 0 or more blocks beyond it,
* so nothing to do here.
......@@ -794,7 +787,7 @@ mdtruncate(Relation reln, int nblocks)
}
#else
if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
return -1;
return InvalidBlockNumber;
#endif
return nblocks;
......@@ -940,7 +933,7 @@ _fdvec_free(int fdvec)
}
static MdfdVec *
_mdfd_openseg(Relation reln, int segno, int oflags)
_mdfd_openseg(Relation reln, BlockNumber segno, int oflags)
{
MdfdVec *v;
int fd;
......@@ -953,7 +946,7 @@ _mdfd_openseg(Relation reln, int segno, int oflags)
if (segno > 0)
{
fullpath = (char *) palloc(strlen(path) + 12);
sprintf(fullpath, "%s.%d", path, segno);
sprintf(fullpath, "%s.%u", path, segno);
pfree(path);
}
else
......@@ -977,7 +970,7 @@ _mdfd_openseg(Relation reln, int segno, int oflags)
v->mdfd_chain = (MdfdVec *) NULL;
#ifdef DIAGNOSTIC
if (_mdnblocks(fd, BLCKSZ) > RELSEG_SIZE)
if (_mdnblocks(fd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
elog(FATAL, "segment too big on openseg!");
#endif
#endif
......@@ -1007,17 +1000,19 @@ _mdfd_getrelnfd(Relation reln)
/* Find the segment of the relation holding the specified block */
static MdfdVec *
_mdfd_getseg(Relation reln, int blkno)
_mdfd_getseg(Relation reln, BlockNumber blkno)
{
MdfdVec *v;
int segno;
int fd;
int i;
#ifndef LET_OS_MANAGE_FILESIZE
BlockNumber segno;
BlockNumber i;
#endif
fd = _mdfd_getrelnfd(reln);
#ifndef LET_OS_MANAGE_FILESIZE
for (v = &Md_fdvec[fd], segno = blkno / RELSEG_SIZE, i = 1;
for (v = &Md_fdvec[fd], segno = blkno / ((BlockNumber) RELSEG_SIZE), i = 1;
segno > 0;
i++, segno--)
{
......@@ -1038,7 +1033,7 @@ _mdfd_getseg(Relation reln, int blkno)
v->mdfd_chain = _mdfd_openseg(reln, i, (segno == 1) ? O_CREAT : 0);
if (v->mdfd_chain == (MdfdVec *) NULL)
elog(ERROR, "cannot open segment %d of relation %s (target block %d): %m",
elog(ERROR, "cannot open segment %u of relation %s (target block %u): %m",
i, RelationGetRelationName(reln), blkno);
}
v = v->mdfd_chain;
......@@ -1064,26 +1059,24 @@ _mdfd_getseg(Relation reln, int blkno)
*/
static int
_mdfd_blind_getseg(RelFileNode rnode, int blkno)
_mdfd_blind_getseg(RelFileNode rnode, BlockNumber blkno)
{
char *path;
int fd;
#ifndef LET_OS_MANAGE_FILESIZE
int segno;
BlockNumber segno;
#endif
path = relpath(rnode);
#ifndef LET_OS_MANAGE_FILESIZE
/* append the '.segno', if needed */
segno = blkno / RELSEG_SIZE;
segno = blkno / ((BlockNumber) RELSEG_SIZE);
if (segno > 0)
{
char *segpath = (char *) palloc(strlen(path) + 12);
sprintf(segpath, "%s.%d", path, segno);
sprintf(segpath, "%s.%u", path, segno);
pfree(path);
path = segpath;
}
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.23 2001/05/10 20:38:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.24 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -489,15 +489,15 @@ mmblindwrt(char *dbstr,
/*
* mmnblocks() -- Get the number of blocks stored in a relation.
*
* Returns # of blocks or -1 on error.
* Returns # of blocks or InvalidBlockNumber on error.
*/
int
BlockNumber
mmnblocks(Relation reln)
{
MMRelTag rtag;
MMRelHashEntry *rentry;
bool found;
int nblocks;
BlockNumber nblocks;
if (reln->rd_rel->relisshared)
rtag.mmrt_dbid = (Oid) 0;
......@@ -520,7 +520,7 @@ mmnblocks(Relation reln)
if (found)
nblocks = rentry->mmrhe_nblocks;
else
nblocks = -1;
nblocks = InvalidBlockNumber;
SpinRelease(MMCacheLock);
......
......@@ -11,13 +11,14 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.49 2001/05/10 20:38:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.50 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "storage/bufmgr.h"
#include "storage/freespace.h"
#include "storage/smgr.h"
#include "utils/memutils.h"
......@@ -44,8 +45,8 @@ typedef struct f_smgr
char *buffer, bool dofsync);
int (*smgr_markdirty) (Relation reln, BlockNumber blkno);
int (*smgr_blindmarkdirty) (RelFileNode, BlockNumber blkno);
int (*smgr_nblocks) (Relation reln);
int (*smgr_truncate) (Relation reln, int nblocks);
BlockNumber (*smgr_nblocks) (Relation reln);
BlockNumber (*smgr_truncate) (Relation reln, BlockNumber nblocks);
int (*smgr_commit) (void); /* may be NULL */
int (*smgr_abort) (void); /* may be NULL */
int (*smgr_sync) (void);
......@@ -433,16 +434,10 @@ smgrblindmarkdirty(int16 which,
* Returns the number of blocks on success, aborts the current
* transaction on failure.
*/
int
BlockNumber
smgrnblocks(int16 which, Relation reln)
{
int nblocks;
if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0)
elog(ERROR, "cannot count blocks for %s: %m",
RelationGetRelationName(reln));
return nblocks;
return (*(smgrsw[which].smgr_nblocks)) (reln);
}
/*
......@@ -452,16 +447,24 @@ smgrnblocks(int16 which, Relation reln)
* Returns the number of blocks on success, aborts the current
* transaction on failure.
*/
int
smgrtruncate(int16 which, Relation reln, int nblocks)
BlockNumber
smgrtruncate(int16 which, Relation reln, BlockNumber nblocks)
{
int newblks;
BlockNumber newblks;
newblks = nblocks;
if (smgrsw[which].smgr_truncate)
{
if ((newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks)) < 0)
elog(ERROR, "cannot truncate %s to %d blocks: %m",
/*
* Tell the free space map to forget this relation, so that it
* stops caching info about the deleted blocks. XXX perhaps
* tell it to forget only info about blocks beyond nblocks?
*/
FreeSpaceMapForgetRel(&reln->rd_node);
newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks);
if (newblks == InvalidBlockNumber)
elog(ERROR, "cannot truncate %s to %u blocks: %m",
RelationGetRelationName(reln), nblocks);
}
......@@ -481,7 +484,6 @@ smgrDoPendingDeletes(bool isCommit)
pendingDeletes = pending->next;
if (pending->atCommit == isCommit)
{
/*
* Get rid of any leftover buffers for the rel (shouldn't be
* any in the commit case, but there can be in the abort
......@@ -489,6 +491,13 @@ smgrDoPendingDeletes(bool isCommit)
*/
DropRelFileNodeBuffers(pending->relnode);
/*
* Tell the free space map to forget this relation. It won't
* be accessed any more anyway, but we may as well recycle the
* map space quickly.
*/
FreeSpaceMapForgetRel(&pending->relnode);
/*
* And delete the physical files.
*
......
This diff is collapsed.
......@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.42 2001/06/23 22:23:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.43 2001/06/27 23:31:39 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
......@@ -31,6 +31,8 @@
#include "optimizer/paths.h"
#include "optimizer/planmain.h"
#include "parser/parse_expr.h"
#include "storage/freespace.h"
#include "storage/lock.h"
#include "storage/proc.h"
#include "tcop/tcopprot.h"
#include "utils/datetime.h"
......@@ -270,11 +272,16 @@ static struct config_int
*/
{"max_connections", PGC_POSTMASTER, &MaxBackends,
DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
{"port", PGC_POSTMASTER, &PostPortNumber,
DEF_PGPORT, 1, 65535, NULL, NULL},
{"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
0777, 0000, 0777, NULL, NULL},
{"sort_mem", PGC_USERSET, &SortMem,
512, 4*BLCKSZ/1024, INT_MAX, NULL, NULL},
......@@ -290,8 +297,13 @@ static struct config_int
{"max_expr_depth", PGC_USERSET, &max_expr_depth,
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL},
{"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
0777, 0000, 0777, NULL, NULL},
{"max_fsm_relations", PGC_POSTMASTER, &MaxFSMRelations,
100, 10, INT_MAX, NULL, NULL},
{"max_fsm_pages", PGC_POSTMASTER, &MaxFSMPages,
10000, 1000, INT_MAX, NULL, NULL},
{"max_locks_per_xact", PGC_POSTMASTER, &max_locks_per_xact,
64, 10, INT_MAX, NULL, NULL},
{"checkpoint_segments", PGC_SIGHUP, &CheckPointSegments,
3, 1, INT_MAX, NULL, NULL},
......
......@@ -44,11 +44,19 @@
#krb_server_keyfile = ''
#
# Shared Memory Size
#
#shared_buffers = 64 # 2*max_connections, min 16
#max_fsm_relations = 100 # min 10
#max_fsm_pages = 10000 # min 1000
#max_locks_per_xact = 64 # min 10
#wal_buffers = 8 # min 4
#
# Performance
#
#sort_mem = 512
#shared_buffers = 64 # 2*max_connections, min 16
#fsync = true
......@@ -78,7 +86,7 @@
# GEQO Optimizer Parameters
#
#geqo_threshold = 11
#geqo_pool_size = 0 #default based in tables, range 128-1024
#geqo_pool_size = 0 #default based on #tables in query, range 128-1024
#geqo_effort = 1
#geqo_generations = 0
#geqo_random_seed = -1 # auto-compute seed
......@@ -87,7 +95,6 @@
#
# Write-ahead log (WAL)
#
#wal_buffers = 8 # min 4
#wal_files = 0 # range 0-64
#wal_sync_method = fsync # fsync or fdatasync or open_sync or open_datasync
# Note: default wal_sync_method varies across platforms
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: vacuum.h,v 1.35 2001/05/07 00:43:25 tgl Exp $
* $Id: vacuum.h,v 1.36 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -15,11 +15,14 @@
#define VACUUM_H
#include "nodes/parsenodes.h"
#include "storage/block.h"
/* in commands/vacuum.c */
extern void vacuum(VacuumStmt *vacstmt);
extern void vac_update_relstats(Oid relid, long num_pages, double num_tuples,
extern void vac_update_relstats(Oid relid,
BlockNumber num_pages,
double num_tuples,
bool hasindex);
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);
......
/*-------------------------------------------------------------------------
*
* freespace.h
* POSTGRES free space map for quickly finding free space in relations
*
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: freespace.h,v 1.1 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef FREESPACE_H_
#define FREESPACE_H_
#include "storage/block.h"
#include "storage/relfilenode.h"
#include "storage/spin.h"
extern SPINLOCK FreeSpaceLock;
extern int MaxFSMRelations;
extern int MaxFSMPages;
/*
* function prototypes
*/
extern void InitFreeSpaceMap(void);
extern int FreeSpaceShmemSize(void);
extern BlockNumber GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded);
extern void RecordFreeSpace(RelFileNode *rel, BlockNumber page,
Size spaceAvail);
extern BlockNumber RecordAndGetPageWithFreeSpace(RelFileNode *rel,
BlockNumber oldPage,
Size oldSpaceAvail,
Size spaceNeeded);
extern void MultiRecordFreeSpace(RelFileNode *rel,
BlockNumber minPage,
BlockNumber maxPage,
int nPages,
BlockNumber *pages,
Size *spaceAvail);
extern void FreeSpaceMapForgetRel(RelFileNode *rel);
#ifdef FREESPACE_DEBUG
extern void DumpFreeSpace(void);
#endif
#endif /* FREESPACE_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: ipc.h,v 1.49 2001/03/22 04:01:05 momjian Exp $
* $Id: ipc.h,v 1.50 2001/06/27 23:31:39 tgl Exp $
*
* Some files that would normally need to include only sys/ipc.h must
* instead include this file because on Ultrix, sys/ipc.h is not designed
......@@ -74,6 +74,7 @@ typedef enum _LockId_
LOCKMGRLOCKID,
SINVALLOCKID,
PROCSTRUCTLOCKID,
FREESPACELOCKID,
#ifdef STABLE_MEMORY_STORAGE
MMCACHELOCKID,
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lock.h,v 1.49 2001/06/22 00:04:59 tgl Exp $
* $Id: lock.h,v 1.50 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -32,6 +32,8 @@ typedef struct proc PROC;
extern SPINLOCK LockMgrLock;
extern int max_locks_per_xact;
#ifdef LOCK_DEBUG
extern int Trace_lock_oidmin;
extern bool Trace_locks;
......@@ -41,19 +43,6 @@ extern bool Debug_deadlocks;
#endif /* LOCK_DEBUG */
/* ----------------------
* The following defines are used to estimate how much shared
* memory the lock manager is going to require.
* See LockShmemSize() in lock.c.
*
* NLOCKS_PER_XACT - The number of unique objects locked in a transaction
* (this should be configurable!)
* NLOCKENTS - The maximum number of lock entries in the lock table.
* ----------------------
*/
#define NLOCKS_PER_XACT 64
#define NLOCKENTS(maxBackends) (NLOCKS_PER_XACT*(maxBackends))
typedef int LOCKMASK;
typedef int LOCKMODE;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: smgr.h,v 1.29 2001/05/10 20:38:49 tgl Exp $
* $Id: smgr.h,v 1.30 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -43,8 +43,9 @@ extern int smgrblindwrt(int16 which, RelFileNode rnode,
extern int smgrblindmarkdirty(int16 which, RelFileNode rnode,
BlockNumber blkno);
extern int smgrmarkdirty(int16 which, Relation reln, BlockNumber blkno);
extern int smgrnblocks(int16 which, Relation reln);
extern int smgrtruncate(int16 which, Relation reln, int nblocks);
extern BlockNumber smgrnblocks(int16 which, Relation reln);
extern BlockNumber smgrtruncate(int16 which, Relation reln,
BlockNumber nblocks);
extern int smgrDoPendingDeletes(bool isCommit);
extern int smgrcommit(void);
extern int smgrabort(void);
......@@ -71,8 +72,8 @@ extern int mdmarkdirty(Relation reln, BlockNumber blkno);
extern int mdblindwrt(RelFileNode rnode, BlockNumber blkno,
char *buffer, bool dofsync);
extern int mdblindmarkdirty(RelFileNode rnode, BlockNumber blkno);
extern int mdnblocks(Relation reln);
extern int mdtruncate(Relation reln, int nblocks);
extern BlockNumber mdnblocks(Relation reln);
extern BlockNumber mdtruncate(Relation reln, BlockNumber nblocks);
extern int mdcommit(void);
extern int mdabort(void);
extern int mdsync(void);
......@@ -95,8 +96,8 @@ extern int mmblindwrt(char *dbname, char *relname, Oid dbid, Oid relid,
extern int mmmarkdirty(Relation reln, BlockNumber blkno);
extern int mmblindmarkdirty(char *dbname, char *relname, Oid dbid, Oid relid,
BlockNumber blkno);
extern int mmnblocks(Relation reln);
extern int mmtruncate(Relation reln, int nblocks);
extern BlockNumber mmnblocks(Relation reln);
extern BlockNumber mmtruncate(Relation reln, BlockNumber nblocks);
extern int mmcommit(void);
extern int mmabort(void);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: rel.h,v 1.50 2001/06/22 19:16:24 wieck Exp $
* $Id: rel.h,v 1.51 2001/06/27 23:31:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -19,8 +19,9 @@
#include "catalog/pg_am.h"
#include "catalog/pg_class.h"
#include "rewrite/prs2lock.h"
#include "storage/relfilenode.h"
#include "storage/block.h"
#include "storage/fd.h"
#include "storage/relfilenode.h"
/* added to prevent circular dependency. bjm 1999/11/15 */
extern char *get_temp_rel_by_physicalname(const char *relname);
......@@ -105,9 +106,11 @@ typedef struct PgStat_Info
typedef struct RelationData
{
File rd_fd; /* open file descriptor, or -1 if none */
RelFileNode rd_node; /* relation file node */
int rd_nblocks; /* number of blocks in rel */
uint16 rd_refcnt; /* reference count */
RelFileNode rd_node; /* file node (physical identifier) */
BlockNumber rd_nblocks; /* number of blocks in rel */
BlockNumber rd_targblock; /* current insertion target block,
* or InvalidBlockNumber */
int rd_refcnt; /* reference count */
bool rd_myxactonly; /* rel uses the local buffer mgr */
bool rd_isnailed; /* rel is nailed in cache */
bool rd_indexfound; /* true if rd_indexlist is valid */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment