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.
This commit is contained in:
Tom Lane 2001-06-27 23:31:40 +00:00
parent b559382134
commit e0c9301c87
26 changed files with 572 additions and 316 deletions

View File

@ -1,5 +1,5 @@
<!--
$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>

View File

@ -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);

View File

@ -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,

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.197 2001/06/22 19:16:21 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.198 2001/06/27 23:31:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -107,8 +107,8 @@ typedef VTupleMoveData *VTupleMove;
typedef struct VRelStats
{
Oid relid;
long num_pages;
long num_tuples;
BlockNumber rel_pages;
double rel_tuples;
Size min_tlen;
Size max_tlen;
bool hasindex;
@ -143,8 +143,8 @@ static void vacuum_heap(VRelStats *vacrelstats, Relation onerel,
VacPageList vacpagelist);
static void vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage);
static void vacuum_index(VacPageList vacpagelist, Relation indrel,
long num_tuples, int keep_tuples);
static void scan_index(Relation indrel, long num_tuples);
double num_tuples, int keep_tuples);
static void scan_index(Relation indrel, double num_tuples);
static VacPage tid_reaped(ItemPointer itemptr, VacPageList vacpagelist);
static void reap_page(VacPageList vacpagelist, VacPage vacpage);
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
@ -487,8 +487,8 @@ vacuum_rel(Oid relid)
*/
vacrelstats = (VRelStats *) palloc(sizeof(VRelStats));
vacrelstats->relid = relid;
vacrelstats->num_pages = 0;
vacrelstats->num_tuples = 0;
vacrelstats->rel_pages = 0;
vacrelstats->rel_tuples = 0;
vacrelstats->hasindex = false;
GetXmaxRecent(&XmaxRecent);
@ -535,13 +535,13 @@ vacuum_rel(Oid relid)
{
for (i = 0; i < nindices; i++)
vacuum_index(&vacuum_pages, Irel[i],
vacrelstats->num_tuples, 0);
vacrelstats->rel_tuples, 0);
}
else
{
/* just scan indices to update statistic */
for (i = 0; i < nindices; i++)
scan_index(Irel[i], vacrelstats->num_tuples);
scan_index(Irel[i], vacrelstats->rel_tuples);
}
}
@ -562,14 +562,13 @@ vacuum_rel(Oid relid)
}
else
{
/*
* Flush dirty pages out to disk. We must do this even if we
* didn't do anything else, because we want to ensure that all
* tuples have correct on-row commit status on disk (see
* bufmgr.c's comments for FlushRelationBuffers()).
*/
i = FlushRelationBuffers(onerel, vacrelstats->num_pages);
i = FlushRelationBuffers(onerel, vacrelstats->rel_pages);
if (i < 0)
elog(ERROR, "VACUUM (vacuum_rel): FlushRelationBuffers returned %d",
i);
@ -584,8 +583,8 @@ vacuum_rel(Oid relid)
heap_close(onerel, NoLock);
/* update statistics in pg_class */
vac_update_relstats(vacrelstats->relid, vacrelstats->num_pages,
vacrelstats->num_tuples, vacrelstats->hasindex);
vac_update_relstats(vacrelstats->relid, vacrelstats->rel_pages,
vacrelstats->rel_tuples, vacrelstats->hasindex);
/*
* Complete the transaction and free all temporary memory used.
@ -637,7 +636,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
char *relname;
VacPage vacpage,
vp;
long num_tuples;
double num_tuples;
uint32 tups_vacuumed,
nkeep,
nunused,
@ -662,8 +661,9 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
relname = RelationGetRelationName(onerel);
elog(MESSAGE_LEVEL, "--Relation %s--", relname);
tups_vacuumed = num_tuples = nkeep = nunused = ncrash = empty_pages =
tups_vacuumed = nkeep = nunused = ncrash = empty_pages =
new_pages = changed_pages = empty_end_pages = 0;
num_tuples = 0;
free_size = usable_free_size = 0;
nblocks = RelationGetNumberOfBlocks(onerel);
@ -922,7 +922,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
}
else
{
num_tuples++;
num_tuples += 1;
notup = false;
if (tuple.t_len < min_tlen)
min_tlen = tuple.t_len;
@ -966,8 +966,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
pfree(vacpage);
/* save stats in the rel list for use later */
vacrelstats->num_tuples = num_tuples;
vacrelstats->num_pages = nblocks;
vacrelstats->rel_tuples = num_tuples;
vacrelstats->rel_pages = nblocks;
if (num_tuples == 0)
min_tlen = max_tlen = 0;
vacrelstats->min_tlen = min_tlen;
@ -1014,7 +1014,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
}
elog(MESSAGE_LEVEL, "Pages %u: Changed %u, reaped %u, Empty %u, New %u; \
Tup %lu: Vac %u, Keep/VTL %u/%u, Crash %u, UnUsed %u, MinLen %lu, MaxLen %lu; \
Tup %.0f: Vac %u, Keep/VTL %u/%u, Crash %u, UnUsed %u, MinLen %lu, MaxLen %lu; \
Re-using: Free/Avail. Space %lu/%lu; EndEmpty/Avail. Pages %u/%u. %s",
nblocks, changed_pages, vacuum_pages->num_pages, empty_pages,
new_pages, num_tuples, tups_vacuumed,
@ -1048,6 +1048,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
cur_buffer;
int nblocks,
blkno;
BlockNumber last_move_dest_block = 0,
last_vacuum_block;
Page page,
ToPage = NULL;
OffsetNumber offnum,
@ -1069,9 +1071,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
vacpage,
*curpage;
int cur_item = 0;
int last_move_dest_block = -1,
last_vacuum_block,
i = 0;
int i;
Size tuple_len;
int num_moved,
num_fraged_pages,
@ -1117,7 +1117,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
* NB: this code depends on the vacuum_pages and fraged_pages lists being
* in order, and on fraged_pages being a subset of vacuum_pages.
*/
nblocks = vacrelstats->num_pages;
nblocks = vacrelstats->rel_pages;
for (blkno = nblocks - vacuum_pages->empty_end_pages - 1;
blkno > last_move_dest_block;
blkno--)
@ -1152,11 +1152,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
else
{
last_vacuum_page = NULL;
last_vacuum_block = -1;
last_vacuum_block = InvalidBlockNumber;
}
if (num_fraged_pages > 0 &&
fraged_pages->pagedesc[num_fraged_pages - 1]->blkno ==
(BlockNumber) blkno)
fraged_pages->pagedesc[num_fraged_pages - 1]->blkno == blkno)
{
/* page is in fraged_pages too; remove it */
--num_fraged_pages;
@ -1577,7 +1576,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
}
END_CRIT_SECTION();
if (((int) destvacpage->blkno) > last_move_dest_block)
if (destvacpage->blkno > last_move_dest_block)
last_move_dest_block = destvacpage->blkno;
/*
@ -1710,9 +1709,9 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
InvalidOffsetNumber, LP_USED);
if (newoff == InvalidOffsetNumber)
{
elog(STOP, "\
failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)",
(unsigned long) tuple_len, cur_page->blkno, (unsigned long) cur_page->free,
elog(STOP, "failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)",
(unsigned long) tuple_len,
cur_page->blkno, (unsigned long) cur_page->free,
cur_page->offsets_used, cur_page->offsets_free);
}
newitemid = PageGetItemId(ToPage, newoff);
@ -1746,7 +1745,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
cur_page->offsets_used++;
num_moved++;
cur_page->free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
if (((int) cur_page->blkno) > last_move_dest_block)
if (cur_page->blkno > last_move_dest_block)
last_move_dest_block = cur_page->blkno;
vacpage->offsets[vacpage->offsets_free++] = offnum;
@ -1882,7 +1881,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
checked_moved = 0;
for (i = 0, curpage = vacuum_pages->pagedesc; i < vacuumed_pages; i++, curpage++)
{
Assert((*curpage)->blkno < (BlockNumber) blkno);
Assert((*curpage)->blkno < blkno);
buf = ReadBuffer(onerel, (*curpage)->blkno);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
page = BufferGetPage(buf);
@ -1959,11 +1958,11 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
Assert(keep_tuples >= 0);
for (i = 0; i < nindices; i++)
vacuum_index(&Nvacpagelist, Irel[i],
vacrelstats->num_tuples, keep_tuples);
vacrelstats->rel_tuples, keep_tuples);
}
/* clean moved tuples from last page in Nvacpagelist list */
if (vacpage->blkno == (BlockNumber) (blkno - 1) &&
if (vacpage->blkno == (blkno - 1) &&
vacpage->offsets_free > 0)
{
OffsetNumber unbuf[BLCKSZ/sizeof(OffsetNumber)];
@ -2037,8 +2036,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
if (blkno < nblocks)
{
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
Assert(blkno >= 0);
vacrelstats->num_pages = blkno; /* set new number of blocks */
vacrelstats->rel_pages = blkno; /* set new number of blocks */
}
if (Irel != (Relation *) NULL) /* pfree index' allocations */
@ -2063,7 +2061,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
{
Buffer buf;
VacPage *vacpage;
long nblocks;
BlockNumber relblocks;
int nblocks;
int i;
nblocks = vacuum_pages->num_pages;
@ -2087,10 +2086,10 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
* tuples have correct on-row commit status on disk (see bufmgr.c's
* comments for FlushRelationBuffers()).
*/
Assert(vacrelstats->num_pages >= vacuum_pages->empty_end_pages);
nblocks = vacrelstats->num_pages - vacuum_pages->empty_end_pages;
Assert(vacrelstats->rel_pages >= (BlockNumber) vacuum_pages->empty_end_pages);
relblocks = vacrelstats->rel_pages - vacuum_pages->empty_end_pages;
i = FlushRelationBuffers(onerel, nblocks);
i = FlushRelationBuffers(onerel, relblocks);
if (i < 0)
elog(ERROR, "VACUUM (vacuum_heap): FlushRelationBuffers returned %d",
i);
@ -2098,12 +2097,11 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
/* truncate relation if there are some empty end-pages */
if (vacuum_pages->empty_end_pages > 0)
{
elog(MESSAGE_LEVEL, "Rel %s: Pages: %lu --> %lu.",
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
RelationGetRelationName(onerel),
vacrelstats->num_pages, nblocks);
nblocks = smgrtruncate(DEFAULT_SMGR, onerel, nblocks);
Assert(nblocks >= 0);
vacrelstats->num_pages = nblocks; /* set new number of
vacrelstats->rel_pages, relblocks);
relblocks = smgrtruncate(DEFAULT_SMGR, onerel, relblocks);
vacrelstats->rel_pages = relblocks; /* set new number of
* blocks */
}
}
@ -2148,12 +2146,12 @@ vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
*
*/
static void
scan_index(Relation indrel, long num_tuples)
scan_index(Relation indrel, double num_tuples)
{
RetrieveIndexResult res;
IndexScanDesc iscan;
long nitups;
int nipages;
BlockNumber nipages;
double nitups;
VacRUsage ru0;
init_rusage(&ru0);
@ -2165,7 +2163,7 @@ scan_index(Relation indrel, long num_tuples)
while ((res = index_getnext(iscan, ForwardScanDirection))
!= (RetrieveIndexResult) NULL)
{
nitups++;
nitups += 1;
pfree(res);
}
@ -2175,12 +2173,12 @@ scan_index(Relation indrel, long num_tuples)
nipages = RelationGetNumberOfBlocks(indrel);
vac_update_relstats(RelationGetRelid(indrel), nipages, nitups, false);
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %lu. %s",
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %.0f. %s",
RelationGetRelationName(indrel), nipages, nitups,
show_rusage(&ru0));
if (nitups != num_tuples)
elog(NOTICE, "Index %s: NUMBER OF INDEX' TUPLES (%lu) IS NOT THE SAME AS HEAP' (%lu).\
elog(NOTICE, "Index %s: NUMBER OF INDEX' TUPLES (%.0f) IS NOT THE SAME AS HEAP' (%.0f).\
\n\tRecreate the index.",
RelationGetRelationName(indrel), nitups, num_tuples);
@ -2200,14 +2198,14 @@ scan_index(Relation indrel, long num_tuples)
*/
static void
vacuum_index(VacPageList vacpagelist, Relation indrel,
long num_tuples, int keep_tuples)
double num_tuples, int keep_tuples)
{
RetrieveIndexResult res;
IndexScanDesc iscan;
ItemPointer heapptr;
int tups_vacuumed;
long num_index_tuples;
int num_pages;
BlockNumber num_pages;
double num_index_tuples;
VacPage vp;
VacRUsage ru0;
@ -2242,7 +2240,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
index_delete(indrel, &res->index_iptr);
}
else
num_index_tuples++;
num_index_tuples += 1;
pfree(res);
}
@ -2254,13 +2252,13 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
vac_update_relstats(RelationGetRelid(indrel),
num_pages, num_index_tuples, false);
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %lu: Deleted %u. %s",
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %.0f: Deleted %u. %s",
RelationGetRelationName(indrel), num_pages,
num_index_tuples - keep_tuples, tups_vacuumed,
show_rusage(&ru0));
if (num_index_tuples != num_tuples + keep_tuples)
elog(NOTICE, "Index %s: NUMBER OF INDEX' TUPLES (%lu) IS NOT THE SAME AS HEAP' (%lu).\
elog(NOTICE, "Index %s: NUMBER OF INDEX' TUPLES (%.0f) IS NOT THE SAME AS HEAP' (%.0f).\
\n\tRecreate the index.",
RelationGetRelationName(indrel), num_index_tuples, num_tuples);
@ -2333,7 +2331,7 @@ tid_reaped(ItemPointer itemptr, VacPageList vacpagelist)
* these are.
*/
void
vac_update_relstats(Oid relid, long num_pages, double num_tuples,
vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
bool hasindex)
{
Relation rd;
@ -2361,8 +2359,8 @@ vac_update_relstats(Oid relid, long num_pages, double num_tuples,
/* overwrite the existing statistics in the tuple */
pgcform = (Form_pg_class) GETSTRUCT(&rtup);
pgcform->relpages = (int32) num_pages;
pgcform->reltuples = num_tuples;
pgcform->relpages = num_pages;
pgcform->relhasindex = hasindex;
/* invalidate the tuple in the cache and write the buffer */

View File

@ -1,14 +1,14 @@
#
# 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

View File

@ -0,0 +1,30 @@
#-------------------------------------------------------------------------
#
# 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

View File

@ -0,0 +1,183 @@
/*-------------------------------------------------------------------------
*
* 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 */

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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.
*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.139 2001/06/22 19:16:23 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.140 2001/06/27 23:31:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -25,7 +25,6 @@
* NOTES
* The following code contains many undocumented hacks. Please be
* careful....
*
*/
#include "postgres.h"
@ -63,7 +62,6 @@
/*
* hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
*
*/
static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
@ -76,7 +74,6 @@ static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
*
* Relations are looked up two ways, by name and by id,
* thus there are two hash tables for referencing them.
*
*/
static HTAB *RelationNameCache;
static HTAB *RelationIdCache;
@ -105,7 +102,6 @@ static bool criticalRelcachesBuilt = false;
/*
* RelationBuildDescInfo exists so code can be shared
* between RelationIdGetRelation() and RelationNameGetRelation()
*
*/
typedef struct RelationBuildDescInfo
{
@ -139,7 +135,6 @@ typedef struct relnodecacheent
/*
* macros to manipulate name cache and id cache
*
*/
#define RelationCacheInsert(RELATION) \
do { \
@ -285,7 +280,6 @@ static List *insert_ordered_oid(List *list, Oid datum);
/*
* RelationIdGetRelation() and RelationNameGetRelation()
* support functions
*
*/
@ -298,7 +292,6 @@ static List *insert_ordered_oid(List *list, Oid datum);
*
* NB: the returned tuple has been copied into palloc'd storage
* and must eventually be freed with heap_freetuple.
*
*/
static HeapTuple
ScanPgRelation(RelationBuildDescInfo buildinfo)
@ -327,7 +320,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
/*
* form a scan key
*
*/
switch (buildinfo.infotype)
{
@ -352,7 +344,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
/*
* open pg_class and fetch a tuple
*
*/
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key);
@ -360,7 +351,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
/*
* get set to return tuple
*
*/
if (!HeapTupleIsValid(pg_class_tuple))
return_tuple = pg_class_tuple;
@ -372,7 +362,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
* returned here without having the corresponding buffer pinned.
* so when the buffer gets replaced, all hell breaks loose. this
* bug is discovered and killed by wei on 9/27/91.
*
*/
return_tuple = heap_copytuple(pg_class_tuple);
}
@ -435,7 +424,6 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
* If 'relation' is NULL, allocate a new RelationData object.
* If not, reuse the given object (that path is taken only when
* we have to rebuild a relcache entry during RelationClearRelation).
*
*/
static Relation
AllocateRelationDesc(Relation relation, Form_pg_class relp)
@ -448,16 +436,15 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
/*
* allocate space for new relation descriptor, if needed
*
*/
if (relation == NULL)
relation = (Relation) palloc(sizeof(RelationData));
/*
* clear all fields of reldesc
*
*/
MemSet((char *) relation, 0, sizeof(RelationData));
relation->rd_targblock = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
relation->rd_fd = -1;
@ -471,7 +458,6 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
* wouldn't know if the value is valid ... bottom line is that relacl
* *cannot* be retrieved from the relcache. Get it from the syscache
* if you need it.
*
*/
relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
@ -493,7 +479,6 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
*
* Form the relation's tuple descriptor from information in
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
*
*/
static void
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
@ -574,7 +559,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
/*
* form a scan key
*
*/
ScanKeyEntryInitialize(&key, 0,
Anum_pg_attribute_attrelid,
@ -583,14 +567,12 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
/*
* open pg_attribute and begin a scan
*
*/
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
pg_attribute_scan = heap_beginscan(pg_attribute_desc, 0, SnapshotNow, 1, &key);
/*
* add attribute data to relation->rd_att
*
*/
need = relation->rd_rel->relnatts;
@ -639,7 +621,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
/*
* end the scan and close the attribute relation
*
*/
heap_endscan(pg_attribute_scan);
heap_close(pg_attribute_desc, AccessShareLock);
@ -648,7 +629,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
* The attcacheoff values we read from pg_attribute should all be -1
* ("unknown"). Verify this if assert checking is on. They will be
* computed when and if needed during tuple access.
*
*/
#ifdef USE_ASSERT_CHECKING
{
@ -664,7 +644,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
* attribute: it must be zero. This eliminates the need for special
* cases for attnum=1 that used to exist in fastgetattr() and
* index_getattr().
*
*/
relation->rd_att->attrs[0]->attcacheoff = 0;
@ -758,7 +737,6 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
* The attcacheoff values we read from pg_attribute should all be -1
* ("unknown"). Verify this if assert checking is on. They will be
* computed when and if needed during tuple access.
*
*/
#ifdef USE_ASSERT_CHECKING
for (i = 0; i < relation->rd_rel->relnatts; i++)
@ -770,7 +748,6 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
* attribute: it must be zero. This eliminates the need for special
* cases for attnum=1 that used to exist in fastgetattr() and
* index_getattr().
*
*/
relation->rd_att->attrs[0]->attcacheoff = 0;
@ -791,7 +768,6 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
* entry, because that keeps the update logic in RelationClearRelation()
* manageable. The other subsidiary data structures are simple enough
* to be easy to free explicitly, anyway.
*
*/
static void
RelationBuildRuleLock(Relation relation)
@ -814,7 +790,7 @@ RelationBuildRuleLock(Relation relation)
*/
rulescxt = AllocSetContextCreate(CacheMemoryContext,
RelationGetRelationName(relation),
0, /* minsize */
0, /* minsize */
1024, /* initsize */
1024); /* maxsize */
relation->rd_rulescxt = rulescxt;
@ -822,7 +798,6 @@ RelationBuildRuleLock(Relation relation)
/*
* form an array to hold the rewrite rules (the array is extended if
* necessary)
*
*/
maxlocks = 4;
rules = (RewriteRule **)
@ -831,7 +806,6 @@ RelationBuildRuleLock(Relation relation)
/*
* form a scan key
*
*/
ScanKeyEntryInitialize(&key, 0,
Anum_pg_rewrite_ev_class,
@ -840,7 +814,6 @@ RelationBuildRuleLock(Relation relation)
/*
* open pg_rewrite and begin a scan
*
*/
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
pg_rewrite_scan = heap_beginscan(pg_rewrite_desc, 0, SnapshotNow, 1, &key);
@ -908,14 +881,12 @@ RelationBuildRuleLock(Relation relation)
/*
* end the scan and close the attribute relation
*
*/
heap_endscan(pg_rewrite_scan);
heap_close(pg_rewrite_desc, AccessShareLock);
/*
* form a RuleLock and insert into relation
*
*/
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
rulelock->numLocks = numlocks;
@ -930,7 +901,6 @@ RelationBuildRuleLock(Relation relation)
* Determine whether two RuleLocks are equivalent
*
* Probably this should be in the rules code someplace...
*
*/
static bool
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
@ -994,9 +964,9 @@ equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
* fields:
*
* File rd_fd; open file descriptor
* int rd_nblocks; number of blocks in rel
* BlockNumber rd_nblocks; number of blocks in rel
* it will be set in ambeginscan()
* uint16 rd_refcnt; reference count
* int rd_refcnt; reference count
* Form_pg_am rd_am; AM tuple
* Form_pg_class rd_rel; RELATION tuple
* Oid rd_id; relation's object id
@ -1022,20 +992,17 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
/*
* find the tuple in pg_class corresponding to the given relation id
*
*/
pg_class_tuple = ScanPgRelation(buildinfo);
/*
* if no such tuple exists, return NULL
*
*/
if (!HeapTupleIsValid(pg_class_tuple))
return NULL;
/*
* get information from the pg_class_tuple
*
*/
relid = pg_class_tuple->t_data->t_oid;
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
@ -1043,37 +1010,31 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
/*
* allocate storage for the relation descriptor, and copy
* pg_class_tuple to relation->rd_rel.
*
*/
relation = AllocateRelationDesc(oldrelation, relp);
/*
* now we can free the memory allocated for pg_class_tuple
*
*/
heap_freetuple(pg_class_tuple);
/*
* initialize the relation's relation id (relation->rd_id)
*
*/
RelationGetRelid(relation) = relid;
/*
* initialize relation->rd_refcnt
*
*/
RelationSetReferenceCount(relation, 1);
/*
* normal relations are not nailed into the cache
*
*/
relation->rd_isnailed = false;
/*
* initialize the access method information (relation->rd_am)
*
*/
relam = relation->rd_rel->relam;
if (OidIsValid(relam))
@ -1082,13 +1043,11 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
/*
* initialize the tuple descriptor (relation->rd_att).
*
*/
RelationBuildTupleDesc(buildinfo, relation);
/*
* Fetch rules and triggers that affect this relation
*
*/
if (relation->rd_rel->relhasrules)
RelationBuildRuleLock(relation);
@ -1105,14 +1064,12 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
/*
* initialize index strategy and support information for this relation
*
*/
if (OidIsValid(relam))
IndexedAccessMethodInitialize(relation);
/*
* initialize the relation lock manager information
*
*/
RelationInitLockInfo(relation); /* see lmgr.c */
@ -1144,7 +1101,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
/*
* insert newly created relation into proper relcaches, restore memory
* context and return the new reldesc.
*
*/
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
RelationCacheInsert(relation);
@ -1214,11 +1170,14 @@ formrdesc(char *relationName,
* allocate new relation desc
*/
relation = (Relation) palloc(sizeof(RelationData));
MemSet((char *) relation, 0, sizeof(RelationData));
/*
* don't open the unix file yet..
* clear all fields of reldesc
*/
MemSet((char *) relation, 0, sizeof(RelationData));
relation->rd_targblock = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
relation->rd_fd = -1;
/*
@ -1329,7 +1288,6 @@ fixrdesc(char *relationName)
/*
* find the tuple in pg_class corresponding to the given relation name
*
*/
buildinfo.infotype = INFO_RELNAME;
buildinfo.i.info_name = relationName;
@ -1343,7 +1301,6 @@ fixrdesc(char *relationName)
/*
* find the pre-made relcache entry (better be there!)
*
*/
relation = RelationNameCacheGetRelation(relationName);
if (!RelationIsValid(relation))
@ -1353,7 +1310,6 @@ fixrdesc(char *relationName)
/*
* and copy pg_class_tuple to relation->rd_rel. (See notes in
* AllocateRelationDesc())
*
*/
Assert(relation->rd_rel != NULL);
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
@ -1378,7 +1334,6 @@ fixrdesc(char *relationName)
* NB: relation ref count is incremented if successful.
* Caller should eventually decrement count. (Usually,
* that happens by calling RelationClose().)
*
*/
Relation
RelationIdCacheGetRelation(Oid relationId)
@ -1403,7 +1358,6 @@ RelationIdCacheGetRelation(Oid relationId)
* RelationNameCacheGetRelation
*
* As above, but lookup by name.
*
*/
static Relation
RelationNameCacheGetRelation(const char *relationName)
@ -1457,7 +1411,6 @@ RelationNodeCacheGetRelation(RelFileNode rnode)
* NB: relation ref count is incremented, or set to 1 if new entry.
* Caller should eventually decrement count. (Usually,
* that happens by calling RelationClose().)
*
*/
Relation
RelationIdGetRelation(Oid relationId)
@ -1467,14 +1420,12 @@ RelationIdGetRelation(Oid relationId)
/*
* increment access statistics
*
*/
IncrHeapAccessStat(local_RelationIdGetRelation);
IncrHeapAccessStat(global_RelationIdGetRelation);
/*
* first try and get a reldesc from the cache
*
*/
rd = RelationIdCacheGetRelation(relationId);
if (RelationIsValid(rd))
@ -1483,7 +1434,6 @@ RelationIdGetRelation(Oid relationId)
/*
* no reldesc in the cache, so have RelationBuildDesc() build one and
* add it.
*
*/
buildinfo.infotype = INFO_RELID;
buildinfo.i.info_id = relationId;
@ -1496,7 +1446,6 @@ RelationIdGetRelation(Oid relationId)
* RelationNameGetRelation
*
* As above, but lookup by name.
*
*/
Relation
RelationNameGetRelation(const char *relationName)
@ -1507,7 +1456,6 @@ RelationNameGetRelation(const char *relationName)
/*
* increment access statistics
*
*/
IncrHeapAccessStat(local_RelationNameGetRelation);
IncrHeapAccessStat(global_RelationNameGetRelation);
@ -1515,7 +1463,6 @@ RelationNameGetRelation(const char *relationName)
/*
* if caller is looking for a temp relation, substitute its real name;
* we only index temp rels by their real names.
*
*/
temprelname = get_temp_rel_by_username(relationName);
if (temprelname != NULL)
@ -1523,7 +1470,6 @@ RelationNameGetRelation(const char *relationName)
/*
* first try and get a reldesc from the cache
*
*/
rd = RelationNameCacheGetRelation(relationName);
if (RelationIsValid(rd))
@ -1532,7 +1478,6 @@ RelationNameGetRelation(const char *relationName)
/*
* no reldesc in the cache, so have RelationBuildDesc() build one and
* add it.
*
*/
buildinfo.infotype = INFO_RELNAME;
buildinfo.i.info_name = (char *) relationName;
@ -1556,7 +1501,6 @@ RelationNameGetRelation(const char *relationName)
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
* to catch references to already-released relcache entries. It slows
* things down quite a bit, however.
*
*/
void
RelationClose(Relation relation)
@ -1577,7 +1521,6 @@ RelationClose(Relation relation)
* This function is especially for nailed relations.
* relhasindex/relfilenode could be changed even for
* nailed relations.
*
*/
static void
RelationReloadClassinfo(Relation relation)
@ -1616,7 +1559,6 @@ RelationReloadClassinfo(Relation relation)
* usually used when we are notified of a change to an open relation
* (one with refcount > 0). However, this routine just does whichever
* it's told to do; callers must determine which they want.
*
*/
static void
RelationClearRelation(Relation relation, bool rebuildIt)
@ -1631,7 +1573,10 @@ RelationClearRelation(Relation relation, bool rebuildIt)
* a vacuum truncation.
*/
if (relation->rd_fd >= 0)
{
smgrclose(DEFAULT_SMGR, relation);
relation->rd_fd = -1;
}
/*
* Never, never ever blow away a nailed-in system relation, because
@ -1702,13 +1647,13 @@ RelationClearRelation(Relation relation, bool rebuildIt)
* we save/restore rd_nblocks (in case it is a local relation)
* *and* call RelationGetNumberOfBlocks (in case it isn't).
*/
uint16 old_refcnt = relation->rd_refcnt;
int old_refcnt = relation->rd_refcnt;
bool old_myxactonly = relation->rd_myxactonly;
TupleDesc old_att = relation->rd_att;
RuleLock *old_rules = relation->rd_rules;
MemoryContext old_rulescxt = relation->rd_rulescxt;
TriggerDesc *old_trigdesc = relation->trigdesc;
int old_nblocks = relation->rd_nblocks;
BlockNumber old_nblocks = relation->rd_nblocks;
RelationBuildDescInfo buildinfo;
buildinfo.infotype = INFO_RELID;
@ -1767,7 +1712,6 @@ RelationClearRelation(Relation relation, bool rebuildIt)
* RelationFlushRelation
*
* Rebuild the relation if it is open (refcount > 0), else blow it away.
*
*/
static void
RelationFlushRelation(Relation relation)
@ -1801,7 +1745,6 @@ RelationFlushRelation(Relation relation)
* RelationClearRelation + if the relation is myxactonly then
* remove the relation descriptor from the newly created
* relation list.
*
*/
void
RelationForgetRelation(Oid rid)
@ -1851,7 +1794,6 @@ RelationForgetRelation(Oid rid)
* safer to process them, so that our *own* SI update messages will
* have the same effects during CommandCounterIncrement for both
* local and nonlocal relations.
*
*/
void
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
@ -1989,7 +1931,6 @@ RelationCacheAbortWalker(Relation *relationPtr, Datum dummy)
* RelationRegisterRelation -
* register the Relation descriptor of a newly created relation
* with the relation descriptor Cache.
*
*/
void
RelationRegisterRelation(Relation relation)
@ -2048,7 +1989,6 @@ RelationPurgeLocalRelation(bool xactCommitted)
* RelationCacheInitialize
*
* This initializes the relation descriptor cache.
*
*/
#define INITRELCACHESIZE 400
@ -2061,7 +2001,6 @@ RelationCacheInitialize(void)
/*
* switch to cache memory context
*
*/
if (!CacheMemoryContext)
CreateCacheMemoryContext();
@ -2070,7 +2009,6 @@ RelationCacheInitialize(void)
/*
* create global caches
*
*/
MemSet(&ctl, 0, (int) sizeof(ctl));
ctl.keysize = sizeof(NameData);
@ -2093,7 +2031,6 @@ RelationCacheInitialize(void)
* be in the cache.
*
* NB: see also the list in RelationCacheInitializePhase2().
*
*/
formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
@ -2115,7 +2052,6 @@ RelationCacheInitialize(void)
*
* This completes initialization of the relcache after catcache
* is functional and we are able to actually load data from pg_class.
*
*/
void
RelationCacheInitializePhase2(void)
@ -2658,7 +2594,8 @@ init_irels(void)
return;
}
/* the file descriptor is not yet opened */
/* reset transient fields */
ird->rd_targblock = InvalidBlockNumber;
ird->rd_fd = -1;
ird->rd_node.tblNode = MyDatabaseId;

View File

@ -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},

View File

@ -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

View File

@ -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);

View File

@ -0,0 +1,53 @@
/*-------------------------------------------------------------------------
*
* 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 */

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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 */