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:
parent
b559382134
commit
e0c9301c87
|
@ -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">
|
<Chapter Id="runtime">
|
||||||
|
@ -1131,6 +1131,42 @@ dynamic_library_path = '/usr/local/lib:/home/my_project/lib:$libdir:$libdir/cont
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term>PORT (<type>integer</type>)</term>
|
<term>PORT (<type>integer</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Postgres hash pages look like ordinary relation pages. The opaque
|
* Postgres hash pages look like ordinary relation pages. The opaque
|
||||||
|
@ -70,18 +70,15 @@ _hash_metapinit(Relation rel)
|
||||||
int nbuckets;
|
int nbuckets;
|
||||||
uint32 nelem; /* number elements */
|
uint32 nelem; /* number elements */
|
||||||
uint32 lg2nelem; /* _hash_log2(nelem) */
|
uint32 lg2nelem; /* _hash_log2(nelem) */
|
||||||
uint32 nblocks;
|
|
||||||
uint16 i;
|
uint16 i;
|
||||||
|
|
||||||
/* can't be sharing this with anyone, now... */
|
/* can't be sharing this with anyone, now... */
|
||||||
if (USELOCKING)
|
if (USELOCKING)
|
||||||
LockRelation(rel, AccessExclusiveLock);
|
LockRelation(rel, AccessExclusiveLock);
|
||||||
|
|
||||||
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
|
if (RelationGetNumberOfBlocks(rel) != 0)
|
||||||
{
|
|
||||||
elog(ERROR, "Cannot initialize non-empty hash table %s",
|
elog(ERROR, "Cannot initialize non-empty hash table %s",
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
}
|
|
||||||
|
|
||||||
metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
|
metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
|
||||||
pg = BufferGetPage(metabuf);
|
pg = BufferGetPage(metabuf);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
|
@ -121,8 +121,8 @@ heapgettup(Relation relation,
|
||||||
{
|
{
|
||||||
ItemId lpp;
|
ItemId lpp;
|
||||||
Page dp;
|
Page dp;
|
||||||
int page;
|
BlockNumber page;
|
||||||
int pages;
|
BlockNumber pages;
|
||||||
int lines;
|
int lines;
|
||||||
OffsetNumber lineoff;
|
OffsetNumber lineoff;
|
||||||
int linesleft;
|
int linesleft;
|
||||||
|
@ -172,7 +172,7 @@ heapgettup(Relation relation,
|
||||||
/*
|
/*
|
||||||
* return null immediately if relation is empty
|
* return null immediately if relation is empty
|
||||||
*/
|
*/
|
||||||
if (!(pages = relation->rd_nblocks))
|
if ((pages = relation->rd_nblocks) == 0)
|
||||||
{
|
{
|
||||||
if (BufferIsValid(*buffer))
|
if (BufferIsValid(*buffer))
|
||||||
ReleaseBuffer(*buffer);
|
ReleaseBuffer(*buffer);
|
||||||
|
@ -233,15 +233,8 @@ heapgettup(Relation relation,
|
||||||
{
|
{
|
||||||
page = ItemPointerGetBlockNumber(tid); /* current page */
|
page = ItemPointerGetBlockNumber(tid); /* current page */
|
||||||
}
|
}
|
||||||
if (page < 0)
|
|
||||||
{
|
Assert(page < pages);
|
||||||
if (BufferIsValid(*buffer))
|
|
||||||
ReleaseBuffer(*buffer);
|
|
||||||
*buffer = InvalidBuffer;
|
|
||||||
tuple->t_datamcxt = NULL;
|
|
||||||
tuple->t_data = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = ReleaseAndReadBuffer(*buffer,
|
*buffer = ReleaseAndReadBuffer(*buffer,
|
||||||
relation,
|
relation,
|
||||||
|
@ -283,15 +276,7 @@ heapgettup(Relation relation,
|
||||||
OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
|
OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page >= pages)
|
Assert(page < pages);
|
||||||
{
|
|
||||||
if (BufferIsValid(*buffer))
|
|
||||||
ReleaseBuffer(*buffer);
|
|
||||||
*buffer = InvalidBuffer;
|
|
||||||
tuple->t_datamcxt = NULL;
|
|
||||||
tuple->t_data = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = ReleaseAndReadBuffer(*buffer,
|
*buffer = ReleaseAndReadBuffer(*buffer,
|
||||||
relation,
|
relation,
|
||||||
|
@ -369,12 +354,11 @@ heapgettup(Relation relation,
|
||||||
* and it's time to move to the next.
|
* and it's time to move to the next.
|
||||||
*/
|
*/
|
||||||
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
|
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
|
||||||
page = (dir < 0) ? (page - 1) : (page + 1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return NULL if we've exhausted all the pages
|
* 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))
|
if (BufferIsValid(*buffer))
|
||||||
ReleaseBuffer(*buffer);
|
ReleaseBuffer(*buffer);
|
||||||
|
@ -384,6 +368,10 @@ heapgettup(Relation relation,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
page = (dir < 0) ? (page - 1) : (page + 1);
|
||||||
|
|
||||||
|
Assert(page < pages);
|
||||||
|
|
||||||
*buffer = ReleaseAndReadBuffer(*buffer,
|
*buffer = ReleaseAndReadBuffer(*buffer,
|
||||||
relation,
|
relation,
|
||||||
page,
|
page,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
|
||||||
|
|
||||||
if ((BlockNumber) relation->rd_nblocks > oldnblocks)
|
if (relation->rd_nblocks > oldnblocks)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Someone else has indeed extended the relation recently.
|
* Someone else has indeed extended the relation recently.
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Postgres btree pages look like ordinary relation pages. The opaque
|
* Postgres btree pages look like ordinary relation pages. The opaque
|
||||||
|
@ -55,7 +55,6 @@ _bt_metapinit(Relation rel)
|
||||||
{
|
{
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
Page pg;
|
Page pg;
|
||||||
int nblocks;
|
|
||||||
BTMetaPageData metad;
|
BTMetaPageData metad;
|
||||||
BTPageOpaque op;
|
BTPageOpaque op;
|
||||||
|
|
||||||
|
@ -63,11 +62,9 @@ _bt_metapinit(Relation rel)
|
||||||
if (USELOCKING)
|
if (USELOCKING)
|
||||||
LockRelation(rel, AccessExclusiveLock);
|
LockRelation(rel, AccessExclusiveLock);
|
||||||
|
|
||||||
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
|
if (RelationGetNumberOfBlocks(rel) != 0)
|
||||||
{
|
|
||||||
elog(ERROR, "Cannot initialize non-empty btree %s",
|
elog(ERROR, "Cannot initialize non-empty btree %s",
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
}
|
|
||||||
|
|
||||||
buf = ReadBuffer(rel, P_NEW);
|
buf = ReadBuffer(rel, P_NEW);
|
||||||
pg = BufferGetPage(buf);
|
pg = BufferGetPage(buf);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
|
@ -1089,6 +1089,7 @@ RelationTruncateIndexes(Oid heapId)
|
||||||
/* Now truncate the actual data and set blocks to zero */
|
/* Now truncate the actual data and set blocks to zero */
|
||||||
smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
|
smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
|
||||||
currentIndex->rd_nblocks = 0;
|
currentIndex->rd_nblocks = 0;
|
||||||
|
currentIndex->rd_targblock = InvalidBlockNumber;
|
||||||
|
|
||||||
/* Initialize the index and rebuild */
|
/* Initialize the index and rebuild */
|
||||||
InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
|
InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
|
||||||
|
@ -1143,9 +1144,9 @@ heap_truncate(char *relname)
|
||||||
DropRelationBuffers(rel);
|
DropRelationBuffers(rel);
|
||||||
|
|
||||||
/* Now truncate the actual data and set blocks to zero */
|
/* Now truncate the actual data and set blocks to zero */
|
||||||
|
|
||||||
smgrtruncate(DEFAULT_SMGR, rel, 0);
|
smgrtruncate(DEFAULT_SMGR, rel, 0);
|
||||||
rel->rd_nblocks = 0;
|
rel->rd_nblocks = 0;
|
||||||
|
rel->rd_targblock = InvalidBlockNumber;
|
||||||
|
|
||||||
/* If this relation has indexes, truncate the indexes too */
|
/* If this relation has indexes, truncate the indexes too */
|
||||||
RelationTruncateIndexes(rid);
|
RelationTruncateIndexes(rid);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
|
@ -1456,7 +1456,7 @@ UpdateStats(Oid relid, double reltuples)
|
||||||
Relation pg_class;
|
Relation pg_class;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
HeapTuple newtup;
|
HeapTuple newtup;
|
||||||
long relpages;
|
BlockNumber relpages;
|
||||||
int i;
|
int i;
|
||||||
Form_pg_class rd_rel;
|
Form_pg_class rd_rel;
|
||||||
Relation idescs[Num_pg_class_indices];
|
Relation idescs[Num_pg_class_indices];
|
||||||
|
@ -1558,7 +1558,7 @@ UpdateStats(Oid relid, double reltuples)
|
||||||
reltuples = 1000;
|
reltuples = 1000;
|
||||||
}
|
}
|
||||||
else
|
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
|
* place with the new values so that the cache contains the latest
|
||||||
* copy.
|
* copy.
|
||||||
*/
|
*/
|
||||||
whichRel->rd_rel->relpages = relpages;
|
whichRel->rd_rel->relpages = (int32) relpages;
|
||||||
whichRel->rd_rel->reltuples = reltuples;
|
whichRel->rd_rel->reltuples = reltuples;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1581,7 +1581,7 @@ UpdateStats(Oid relid, double reltuples)
|
||||||
*/
|
*/
|
||||||
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
|
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
|
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
|
||||||
rd_rel->relpages = relpages;
|
rd_rel->relpages = (int32) relpages;
|
||||||
rd_rel->reltuples = reltuples;
|
rd_rel->reltuples = reltuples;
|
||||||
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
|
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
|
||||||
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
|
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
|
||||||
|
@ -1600,7 +1600,7 @@ UpdateStats(Oid relid, double reltuples)
|
||||||
}
|
}
|
||||||
|
|
||||||
replace[Anum_pg_class_relpages - 1] = 'r';
|
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';
|
replace[Anum_pg_class_reltuples - 1] = 'r';
|
||||||
values[Anum_pg_class_reltuples - 1] = Float4GetDatum((float4) reltuples);
|
values[Anum_pg_class_reltuples - 1] = Float4GetDatum((float4) reltuples);
|
||||||
newtup = heap_modifytuple(tuple, pg_class, values, nulls, replace);
|
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 */
|
/* Now truncate the actual data and set blocks to zero */
|
||||||
smgrtruncate(DEFAULT_SMGR, iRel, 0);
|
smgrtruncate(DEFAULT_SMGR, iRel, 0);
|
||||||
iRel->rd_nblocks = 0;
|
iRel->rd_nblocks = 0;
|
||||||
|
iRel->rd_targblock = InvalidBlockNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the index and rebuild */
|
/* Initialize the index and rebuild */
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
typedef struct VRelStats
|
||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
long num_pages;
|
BlockNumber rel_pages;
|
||||||
long num_tuples;
|
double rel_tuples;
|
||||||
Size min_tlen;
|
Size min_tlen;
|
||||||
Size max_tlen;
|
Size max_tlen;
|
||||||
bool hasindex;
|
bool hasindex;
|
||||||
|
@ -143,8 +143,8 @@ static void vacuum_heap(VRelStats *vacrelstats, Relation onerel,
|
||||||
VacPageList vacpagelist);
|
VacPageList vacpagelist);
|
||||||
static void vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage);
|
static void vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage);
|
||||||
static void vacuum_index(VacPageList vacpagelist, Relation indrel,
|
static void vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||||
long num_tuples, int keep_tuples);
|
double num_tuples, int keep_tuples);
|
||||||
static void scan_index(Relation indrel, long num_tuples);
|
static void scan_index(Relation indrel, double num_tuples);
|
||||||
static VacPage tid_reaped(ItemPointer itemptr, VacPageList vacpagelist);
|
static VacPage tid_reaped(ItemPointer itemptr, VacPageList vacpagelist);
|
||||||
static void reap_page(VacPageList vacpagelist, VacPage vacpage);
|
static void reap_page(VacPageList vacpagelist, VacPage vacpage);
|
||||||
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
|
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
|
||||||
|
@ -487,8 +487,8 @@ vacuum_rel(Oid relid)
|
||||||
*/
|
*/
|
||||||
vacrelstats = (VRelStats *) palloc(sizeof(VRelStats));
|
vacrelstats = (VRelStats *) palloc(sizeof(VRelStats));
|
||||||
vacrelstats->relid = relid;
|
vacrelstats->relid = relid;
|
||||||
vacrelstats->num_pages = 0;
|
vacrelstats->rel_pages = 0;
|
||||||
vacrelstats->num_tuples = 0;
|
vacrelstats->rel_tuples = 0;
|
||||||
vacrelstats->hasindex = false;
|
vacrelstats->hasindex = false;
|
||||||
|
|
||||||
GetXmaxRecent(&XmaxRecent);
|
GetXmaxRecent(&XmaxRecent);
|
||||||
|
@ -535,13 +535,13 @@ vacuum_rel(Oid relid)
|
||||||
{
|
{
|
||||||
for (i = 0; i < nindices; i++)
|
for (i = 0; i < nindices; i++)
|
||||||
vacuum_index(&vacuum_pages, Irel[i],
|
vacuum_index(&vacuum_pages, Irel[i],
|
||||||
vacrelstats->num_tuples, 0);
|
vacrelstats->rel_tuples, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* just scan indices to update statistic */
|
/* just scan indices to update statistic */
|
||||||
for (i = 0; i < nindices; i++)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush dirty pages out to disk. We must do this even if we
|
* 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
|
* didn't do anything else, because we want to ensure that all
|
||||||
* tuples have correct on-row commit status on disk (see
|
* tuples have correct on-row commit status on disk (see
|
||||||
* bufmgr.c's comments for FlushRelationBuffers()).
|
* bufmgr.c's comments for FlushRelationBuffers()).
|
||||||
*/
|
*/
|
||||||
i = FlushRelationBuffers(onerel, vacrelstats->num_pages);
|
i = FlushRelationBuffers(onerel, vacrelstats->rel_pages);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
elog(ERROR, "VACUUM (vacuum_rel): FlushRelationBuffers returned %d",
|
elog(ERROR, "VACUUM (vacuum_rel): FlushRelationBuffers returned %d",
|
||||||
i);
|
i);
|
||||||
|
@ -584,8 +583,8 @@ vacuum_rel(Oid relid)
|
||||||
heap_close(onerel, NoLock);
|
heap_close(onerel, NoLock);
|
||||||
|
|
||||||
/* update statistics in pg_class */
|
/* update statistics in pg_class */
|
||||||
vac_update_relstats(vacrelstats->relid, vacrelstats->num_pages,
|
vac_update_relstats(vacrelstats->relid, vacrelstats->rel_pages,
|
||||||
vacrelstats->num_tuples, vacrelstats->hasindex);
|
vacrelstats->rel_tuples, vacrelstats->hasindex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Complete the transaction and free all temporary memory used.
|
* Complete the transaction and free all temporary memory used.
|
||||||
|
@ -637,7 +636,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||||
char *relname;
|
char *relname;
|
||||||
VacPage vacpage,
|
VacPage vacpage,
|
||||||
vp;
|
vp;
|
||||||
long num_tuples;
|
double num_tuples;
|
||||||
uint32 tups_vacuumed,
|
uint32 tups_vacuumed,
|
||||||
nkeep,
|
nkeep,
|
||||||
nunused,
|
nunused,
|
||||||
|
@ -662,8 +661,9 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||||
relname = RelationGetRelationName(onerel);
|
relname = RelationGetRelationName(onerel);
|
||||||
elog(MESSAGE_LEVEL, "--Relation %s--", relname);
|
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;
|
new_pages = changed_pages = empty_end_pages = 0;
|
||||||
|
num_tuples = 0;
|
||||||
free_size = usable_free_size = 0;
|
free_size = usable_free_size = 0;
|
||||||
|
|
||||||
nblocks = RelationGetNumberOfBlocks(onerel);
|
nblocks = RelationGetNumberOfBlocks(onerel);
|
||||||
|
@ -922,7 +922,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
num_tuples++;
|
num_tuples += 1;
|
||||||
notup = false;
|
notup = false;
|
||||||
if (tuple.t_len < min_tlen)
|
if (tuple.t_len < min_tlen)
|
||||||
min_tlen = tuple.t_len;
|
min_tlen = tuple.t_len;
|
||||||
|
@ -966,8 +966,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||||
pfree(vacpage);
|
pfree(vacpage);
|
||||||
|
|
||||||
/* save stats in the rel list for use later */
|
/* save stats in the rel list for use later */
|
||||||
vacrelstats->num_tuples = num_tuples;
|
vacrelstats->rel_tuples = num_tuples;
|
||||||
vacrelstats->num_pages = nblocks;
|
vacrelstats->rel_pages = nblocks;
|
||||||
if (num_tuples == 0)
|
if (num_tuples == 0)
|
||||||
min_tlen = max_tlen = 0;
|
min_tlen = max_tlen = 0;
|
||||||
vacrelstats->min_tlen = min_tlen;
|
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; \
|
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",
|
Re-using: Free/Avail. Space %lu/%lu; EndEmpty/Avail. Pages %u/%u. %s",
|
||||||
nblocks, changed_pages, vacuum_pages->num_pages, empty_pages,
|
nblocks, changed_pages, vacuum_pages->num_pages, empty_pages,
|
||||||
new_pages, num_tuples, tups_vacuumed,
|
new_pages, num_tuples, tups_vacuumed,
|
||||||
|
@ -1048,6 +1048,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
cur_buffer;
|
cur_buffer;
|
||||||
int nblocks,
|
int nblocks,
|
||||||
blkno;
|
blkno;
|
||||||
|
BlockNumber last_move_dest_block = 0,
|
||||||
|
last_vacuum_block;
|
||||||
Page page,
|
Page page,
|
||||||
ToPage = NULL;
|
ToPage = NULL;
|
||||||
OffsetNumber offnum,
|
OffsetNumber offnum,
|
||||||
|
@ -1069,9 +1071,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
vacpage,
|
vacpage,
|
||||||
*curpage;
|
*curpage;
|
||||||
int cur_item = 0;
|
int cur_item = 0;
|
||||||
int last_move_dest_block = -1,
|
int i;
|
||||||
last_vacuum_block,
|
|
||||||
i = 0;
|
|
||||||
Size tuple_len;
|
Size tuple_len;
|
||||||
int num_moved,
|
int num_moved,
|
||||||
num_fraged_pages,
|
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
|
* 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.
|
* 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;
|
for (blkno = nblocks - vacuum_pages->empty_end_pages - 1;
|
||||||
blkno > last_move_dest_block;
|
blkno > last_move_dest_block;
|
||||||
blkno--)
|
blkno--)
|
||||||
|
@ -1152,11 +1152,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
last_vacuum_page = NULL;
|
last_vacuum_page = NULL;
|
||||||
last_vacuum_block = -1;
|
last_vacuum_block = InvalidBlockNumber;
|
||||||
}
|
}
|
||||||
if (num_fraged_pages > 0 &&
|
if (num_fraged_pages > 0 &&
|
||||||
fraged_pages->pagedesc[num_fraged_pages - 1]->blkno ==
|
fraged_pages->pagedesc[num_fraged_pages - 1]->blkno == blkno)
|
||||||
(BlockNumber) blkno)
|
|
||||||
{
|
{
|
||||||
/* page is in fraged_pages too; remove it */
|
/* page is in fraged_pages too; remove it */
|
||||||
--num_fraged_pages;
|
--num_fraged_pages;
|
||||||
|
@ -1577,7 +1576,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
}
|
}
|
||||||
END_CRIT_SECTION();
|
END_CRIT_SECTION();
|
||||||
|
|
||||||
if (((int) destvacpage->blkno) > last_move_dest_block)
|
if (destvacpage->blkno > last_move_dest_block)
|
||||||
last_move_dest_block = destvacpage->blkno;
|
last_move_dest_block = destvacpage->blkno;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1710,9 +1709,9 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||||
InvalidOffsetNumber, LP_USED);
|
InvalidOffsetNumber, LP_USED);
|
||||||
if (newoff == InvalidOffsetNumber)
|
if (newoff == InvalidOffsetNumber)
|
||||||
{
|
{
|
||||||
elog(STOP, "\
|
elog(STOP, "failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)",
|
||||||
failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)",
|
(unsigned long) tuple_len,
|
||||||
(unsigned long) tuple_len, cur_page->blkno, (unsigned long) cur_page->free,
|
cur_page->blkno, (unsigned long) cur_page->free,
|
||||||
cur_page->offsets_used, cur_page->offsets_free);
|
cur_page->offsets_used, cur_page->offsets_free);
|
||||||
}
|
}
|
||||||
newitemid = PageGetItemId(ToPage, newoff);
|
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++;
|
cur_page->offsets_used++;
|
||||||
num_moved++;
|
num_moved++;
|
||||||
cur_page->free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
|
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;
|
last_move_dest_block = cur_page->blkno;
|
||||||
|
|
||||||
vacpage->offsets[vacpage->offsets_free++] = offnum;
|
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;
|
checked_moved = 0;
|
||||||
for (i = 0, curpage = vacuum_pages->pagedesc; i < vacuumed_pages; i++, curpage++)
|
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);
|
buf = ReadBuffer(onerel, (*curpage)->blkno);
|
||||||
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
||||||
page = BufferGetPage(buf);
|
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);
|
Assert(keep_tuples >= 0);
|
||||||
for (i = 0; i < nindices; i++)
|
for (i = 0; i < nindices; i++)
|
||||||
vacuum_index(&Nvacpagelist, Irel[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 */
|
/* clean moved tuples from last page in Nvacpagelist list */
|
||||||
if (vacpage->blkno == (BlockNumber) (blkno - 1) &&
|
if (vacpage->blkno == (blkno - 1) &&
|
||||||
vacpage->offsets_free > 0)
|
vacpage->offsets_free > 0)
|
||||||
{
|
{
|
||||||
OffsetNumber unbuf[BLCKSZ/sizeof(OffsetNumber)];
|
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)
|
if (blkno < nblocks)
|
||||||
{
|
{
|
||||||
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
|
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
|
||||||
Assert(blkno >= 0);
|
vacrelstats->rel_pages = blkno; /* set new number of blocks */
|
||||||
vacrelstats->num_pages = blkno; /* set new number of blocks */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Irel != (Relation *) NULL) /* pfree index' allocations */
|
if (Irel != (Relation *) NULL) /* pfree index' allocations */
|
||||||
|
@ -2063,7 +2061,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
|
||||||
{
|
{
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
VacPage *vacpage;
|
VacPage *vacpage;
|
||||||
long nblocks;
|
BlockNumber relblocks;
|
||||||
|
int nblocks;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
nblocks = vacuum_pages->num_pages;
|
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
|
* tuples have correct on-row commit status on disk (see bufmgr.c's
|
||||||
* comments for FlushRelationBuffers()).
|
* comments for FlushRelationBuffers()).
|
||||||
*/
|
*/
|
||||||
Assert(vacrelstats->num_pages >= vacuum_pages->empty_end_pages);
|
Assert(vacrelstats->rel_pages >= (BlockNumber) vacuum_pages->empty_end_pages);
|
||||||
nblocks = vacrelstats->num_pages - 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)
|
if (i < 0)
|
||||||
elog(ERROR, "VACUUM (vacuum_heap): FlushRelationBuffers returned %d",
|
elog(ERROR, "VACUUM (vacuum_heap): FlushRelationBuffers returned %d",
|
||||||
i);
|
i);
|
||||||
|
@ -2098,12 +2097,11 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
|
||||||
/* truncate relation if there are some empty end-pages */
|
/* truncate relation if there are some empty end-pages */
|
||||||
if (vacuum_pages->empty_end_pages > 0)
|
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),
|
RelationGetRelationName(onerel),
|
||||||
vacrelstats->num_pages, nblocks);
|
vacrelstats->rel_pages, relblocks);
|
||||||
nblocks = smgrtruncate(DEFAULT_SMGR, onerel, nblocks);
|
relblocks = smgrtruncate(DEFAULT_SMGR, onerel, relblocks);
|
||||||
Assert(nblocks >= 0);
|
vacrelstats->rel_pages = relblocks; /* set new number of
|
||||||
vacrelstats->num_pages = nblocks; /* set new number of
|
|
||||||
* blocks */
|
* blocks */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2148,12 +2146,12 @@ vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
scan_index(Relation indrel, long num_tuples)
|
scan_index(Relation indrel, double num_tuples)
|
||||||
{
|
{
|
||||||
RetrieveIndexResult res;
|
RetrieveIndexResult res;
|
||||||
IndexScanDesc iscan;
|
IndexScanDesc iscan;
|
||||||
long nitups;
|
BlockNumber nipages;
|
||||||
int nipages;
|
double nitups;
|
||||||
VacRUsage ru0;
|
VacRUsage ru0;
|
||||||
|
|
||||||
init_rusage(&ru0);
|
init_rusage(&ru0);
|
||||||
|
@ -2165,7 +2163,7 @@ scan_index(Relation indrel, long num_tuples)
|
||||||
while ((res = index_getnext(iscan, ForwardScanDirection))
|
while ((res = index_getnext(iscan, ForwardScanDirection))
|
||||||
!= (RetrieveIndexResult) NULL)
|
!= (RetrieveIndexResult) NULL)
|
||||||
{
|
{
|
||||||
nitups++;
|
nitups += 1;
|
||||||
pfree(res);
|
pfree(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2175,12 +2173,12 @@ scan_index(Relation indrel, long num_tuples)
|
||||||
nipages = RelationGetNumberOfBlocks(indrel);
|
nipages = RelationGetNumberOfBlocks(indrel);
|
||||||
vac_update_relstats(RelationGetRelid(indrel), nipages, nitups, false);
|
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,
|
RelationGetRelationName(indrel), nipages, nitups,
|
||||||
show_rusage(&ru0));
|
show_rusage(&ru0));
|
||||||
|
|
||||||
if (nitups != num_tuples)
|
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.",
|
\n\tRecreate the index.",
|
||||||
RelationGetRelationName(indrel), nitups, num_tuples);
|
RelationGetRelationName(indrel), nitups, num_tuples);
|
||||||
|
|
||||||
|
@ -2200,14 +2198,14 @@ scan_index(Relation indrel, long num_tuples)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vacuum_index(VacPageList vacpagelist, Relation indrel,
|
vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||||
long num_tuples, int keep_tuples)
|
double num_tuples, int keep_tuples)
|
||||||
{
|
{
|
||||||
RetrieveIndexResult res;
|
RetrieveIndexResult res;
|
||||||
IndexScanDesc iscan;
|
IndexScanDesc iscan;
|
||||||
ItemPointer heapptr;
|
ItemPointer heapptr;
|
||||||
int tups_vacuumed;
|
int tups_vacuumed;
|
||||||
long num_index_tuples;
|
BlockNumber num_pages;
|
||||||
int num_pages;
|
double num_index_tuples;
|
||||||
VacPage vp;
|
VacPage vp;
|
||||||
VacRUsage ru0;
|
VacRUsage ru0;
|
||||||
|
|
||||||
|
@ -2242,7 +2240,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||||
index_delete(indrel, &res->index_iptr);
|
index_delete(indrel, &res->index_iptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
num_index_tuples++;
|
num_index_tuples += 1;
|
||||||
|
|
||||||
pfree(res);
|
pfree(res);
|
||||||
}
|
}
|
||||||
|
@ -2254,13 +2252,13 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||||
vac_update_relstats(RelationGetRelid(indrel),
|
vac_update_relstats(RelationGetRelid(indrel),
|
||||||
num_pages, num_index_tuples, false);
|
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,
|
RelationGetRelationName(indrel), num_pages,
|
||||||
num_index_tuples - keep_tuples, tups_vacuumed,
|
num_index_tuples - keep_tuples, tups_vacuumed,
|
||||||
show_rusage(&ru0));
|
show_rusage(&ru0));
|
||||||
|
|
||||||
if (num_index_tuples != num_tuples + keep_tuples)
|
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.",
|
\n\tRecreate the index.",
|
||||||
RelationGetRelationName(indrel), num_index_tuples, num_tuples);
|
RelationGetRelationName(indrel), num_index_tuples, num_tuples);
|
||||||
|
|
||||||
|
@ -2333,7 +2331,7 @@ tid_reaped(ItemPointer itemptr, VacPageList vacpagelist)
|
||||||
* these are.
|
* these are.
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
bool hasindex)
|
||||||
{
|
{
|
||||||
Relation rd;
|
Relation rd;
|
||||||
|
@ -2361,8 +2359,8 @@ vac_update_relstats(Oid relid, long num_pages, double num_tuples,
|
||||||
|
|
||||||
/* overwrite the existing statistics in the tuple */
|
/* overwrite the existing statistics in the tuple */
|
||||||
pgcform = (Form_pg_class) GETSTRUCT(&rtup);
|
pgcform = (Form_pg_class) GETSTRUCT(&rtup);
|
||||||
|
pgcform->relpages = (int32) num_pages;
|
||||||
pgcform->reltuples = num_tuples;
|
pgcform->reltuples = num_tuples;
|
||||||
pgcform->relpages = num_pages;
|
|
||||||
pgcform->relhasindex = hasindex;
|
pgcform->relhasindex = hasindex;
|
||||||
|
|
||||||
/* invalidate the tuple in the cache and write the buffer */
|
/* invalidate the tuple in the cache and write the buffer */
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#
|
#
|
||||||
# Makefile for the storage manager subsystem
|
# 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
|
subdir = src/backend/storage
|
||||||
top_builddir = ../../..
|
top_builddir = ../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
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)
|
SUBDIROBJS := $(SUBDIRS:%=%/SUBSYS.o)
|
||||||
|
|
||||||
all: SUBSYS.o
|
all: SUBSYS.o
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "miscadmin.h"
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
#include "storage/freespace.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "storage/sinval.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
|
* moderately-accurate estimates for the big hogs, plus 100K for the
|
||||||
* stuff that's too small to bother with estimating.
|
* stuff that's too small to bother with estimating.
|
||||||
*/
|
*/
|
||||||
size = BufferShmemSize() + LockShmemSize(maxBackends) +
|
size = BufferShmemSize();
|
||||||
XLOGShmemSize() + SLockShmemSize() + SInvalShmemSize(maxBackends);
|
size += LockShmemSize(maxBackends);
|
||||||
|
size += XLOGShmemSize();
|
||||||
|
size += SLockShmemSize();
|
||||||
|
size += SInvalShmemSize(maxBackends);
|
||||||
|
size += FreeSpaceShmemSize();
|
||||||
#ifdef STABLE_MEMORY_STORAGE
|
#ifdef STABLE_MEMORY_STORAGE
|
||||||
size += MMShmemSize();
|
size += MMShmemSize();
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,4 +101,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int maxBackends)
|
||||||
* Set up shared-inval messaging
|
* Set up shared-inval messaging
|
||||||
*/
|
*/
|
||||||
CreateSharedInvalidationState(maxBackends);
|
CreateSharedInvalidationState(maxBackends);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up free-space map
|
||||||
|
*/
|
||||||
|
InitFreeSpaceMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 */
|
/* Probably should move these to an appropriate header file */
|
||||||
extern SPINLOCK ShmemLock;
|
|
||||||
extern SPINLOCK ShmemIndexLock;
|
|
||||||
extern SPINLOCK BufMgrLock;
|
extern SPINLOCK BufMgrLock;
|
||||||
extern SPINLOCK LockMgrLock;
|
|
||||||
extern SPINLOCK ProcStructLock;
|
|
||||||
extern SPINLOCK SInvalLock;
|
|
||||||
extern SPINLOCK OidGenLockId;
|
extern SPINLOCK OidGenLockId;
|
||||||
extern SPINLOCK XidGenLockId;
|
extern SPINLOCK XidGenLockId;
|
||||||
extern SPINLOCK ControlFileLockId;
|
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
|
#ifdef STABLE_MEMORY_STORAGE
|
||||||
extern SPINLOCK MMCacheLock;
|
extern SPINLOCK MMCacheLock;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,16 +56,16 @@ extern SPINLOCK MMCacheLock;
|
||||||
static void
|
static void
|
||||||
InitSpinLockIDs(void)
|
InitSpinLockIDs(void)
|
||||||
{
|
{
|
||||||
ShmemLock = (SPINLOCK) SHMEMLOCKID;
|
|
||||||
ShmemIndexLock = (SPINLOCK) SHMEMINDEXLOCKID;
|
|
||||||
BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
|
BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
|
||||||
LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
|
|
||||||
ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
|
|
||||||
SInvalLock = (SPINLOCK) SINVALLOCKID;
|
|
||||||
OidGenLockId = (SPINLOCK) OIDGENLOCKID;
|
OidGenLockId = (SPINLOCK) OIDGENLOCKID;
|
||||||
XidGenLockId = (SPINLOCK) XIDGENLOCKID;
|
XidGenLockId = (SPINLOCK) XIDGENLOCKID;
|
||||||
ControlFileLockId = (SPINLOCK) CNTLFILELOCKID;
|
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
|
#ifdef STABLE_MEMORY_STORAGE
|
||||||
MMCacheLock = (SPINLOCK) MMCACHELOCKID;
|
MMCacheLock = (SPINLOCK) MMCACHELOCKID;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Outside modules can create a lock table and acquire/release
|
* Outside modules can create a lock table and acquire/release
|
||||||
|
@ -40,6 +40,13 @@
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/ps_status.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,
|
static int WaitOnLock(LOCKMETHOD lockmethod, LOCKMODE lockmode,
|
||||||
LOCK *lock, HOLDER *holder);
|
LOCK *lock, HOLDER *holder);
|
||||||
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PROC *proc,
|
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PROC *proc,
|
||||||
|
@ -1388,6 +1395,7 @@ int
|
||||||
LockShmemSize(int maxBackends)
|
LockShmemSize(int maxBackends)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
long max_table_size = NLOCKENTS(maxBackends);
|
||||||
|
|
||||||
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
|
||||||
size += maxBackends * MAXALIGN(sizeof(PROC)); /* each MyProc */
|
size += maxBackends * MAXALIGN(sizeof(PROC)); /* each MyProc */
|
||||||
|
@ -1395,12 +1403,12 @@ LockShmemSize(int maxBackends)
|
||||||
* lockMethodTable->ctl */
|
* lockMethodTable->ctl */
|
||||||
|
|
||||||
/* lockHash table */
|
/* lockHash table */
|
||||||
size += hash_estimate_size(NLOCKENTS(maxBackends),
|
size += hash_estimate_size(max_table_size,
|
||||||
SHMEM_LOCKTAB_KEYSIZE,
|
SHMEM_LOCKTAB_KEYSIZE,
|
||||||
SHMEM_LOCKTAB_DATASIZE);
|
SHMEM_LOCKTAB_DATASIZE);
|
||||||
|
|
||||||
/* holderHash table */
|
/* holderHash table */
|
||||||
size += hash_estimate_size(NLOCKENTS(maxBackends),
|
size += hash_estimate_size(max_table_size,
|
||||||
SHMEM_HOLDERTAB_KEYSIZE,
|
SHMEM_HOLDERTAB_KEYSIZE,
|
||||||
SHMEM_HOLDERTAB_DATASIZE);
|
SHMEM_HOLDERTAB_DATASIZE);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 */
|
/* routines declared here */
|
||||||
static void mdclose_fd(int fd);
|
static void mdclose_fd(int fd);
|
||||||
static int _mdfd_getrelnfd(Relation reln);
|
static int _mdfd_getrelnfd(Relation reln);
|
||||||
static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags);
|
static MdfdVec *_mdfd_openseg(Relation reln, BlockNumber segno, int oflags);
|
||||||
static MdfdVec *_mdfd_getseg(Relation reln, int blkno);
|
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 int _fdvec_alloc(void);
|
||||||
static void _fdvec_free(int);
|
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.
|
* Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mdinit()
|
mdinit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -194,11 +194,11 @@ mdunlink(RelFileNode rnode)
|
||||||
if (status == SM_SUCCESS)
|
if (status == SM_SUCCESS)
|
||||||
{
|
{
|
||||||
char *segpath = (char *) palloc(strlen(path) + 12);
|
char *segpath = (char *) palloc(strlen(path) + 12);
|
||||||
int segno;
|
BlockNumber segno;
|
||||||
|
|
||||||
for (segno = 1;; segno++)
|
for (segno = 1;; segno++)
|
||||||
{
|
{
|
||||||
sprintf(segpath, "%s.%d", path, segno);
|
sprintf(segpath, "%s.%u", path, segno);
|
||||||
if (unlink(segpath) < 0)
|
if (unlink(segpath) < 0)
|
||||||
{
|
{
|
||||||
/* ENOENT is expected after the last segment... */
|
/* ENOENT is expected after the last segment... */
|
||||||
|
@ -246,7 +246,7 @@ mdextend(Relation reln, BlockNumber blocknum, char *buffer)
|
||||||
v = _mdfd_getseg(reln, blocknum);
|
v = _mdfd_getseg(reln, blocknum);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
|
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
||||||
elog(FATAL, "seekpos too big!");
|
elog(FATAL, "seekpos too big!");
|
||||||
|
@ -283,7 +283,7 @@ mdextend(Relation reln, BlockNumber blocknum, char *buffer)
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE)
|
if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
|
||||||
elog(FATAL, "segment too big!");
|
elog(FATAL, "segment too big!");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -338,7 +338,7 @@ mdopen(Relation reln)
|
||||||
Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
|
Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (_mdnblocks(fd, BLCKSZ) > RELSEG_SIZE)
|
if (_mdnblocks(fd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
|
||||||
elog(FATAL, "segment too big on relopen!");
|
elog(FATAL, "segment too big on relopen!");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -438,7 +438,7 @@ mdread(Relation reln, BlockNumber blocknum, char *buffer)
|
||||||
v = _mdfd_getseg(reln, blocknum);
|
v = _mdfd_getseg(reln, blocknum);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
|
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
||||||
|
@ -482,7 +482,7 @@ mdwrite(Relation reln, BlockNumber blocknum, char *buffer)
|
||||||
v = _mdfd_getseg(reln, blocknum);
|
v = _mdfd_getseg(reln, blocknum);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
|
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
||||||
elog(FATAL, "seekpos too big!");
|
elog(FATAL, "seekpos too big!");
|
||||||
|
@ -516,7 +516,7 @@ mdflush(Relation reln, BlockNumber blocknum, char *buffer)
|
||||||
v = _mdfd_getseg(reln, blocknum);
|
v = _mdfd_getseg(reln, blocknum);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
|
seekpos = (long) (BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)));
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
||||||
elog(FATAL, "seekpos too big!");
|
elog(FATAL, "seekpos too big!");
|
||||||
|
@ -561,7 +561,7 @@ mdblindwrt(RelFileNode rnode,
|
||||||
return SM_FAIL;
|
return SM_FAIL;
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE));
|
seekpos = (long) (BLCKSZ * (blkno % ((BlockNumber) RELSEG_SIZE)));
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
if (seekpos >= BLCKSZ * RELSEG_SIZE)
|
||||||
elog(FATAL, "seekpos too big!");
|
elog(FATAL, "seekpos too big!");
|
||||||
|
@ -659,16 +659,14 @@ mdblindmarkdirty(RelFileNode rnode,
|
||||||
*
|
*
|
||||||
* Returns # of blocks, elog's on error.
|
* Returns # of blocks, elog's on error.
|
||||||
*/
|
*/
|
||||||
int
|
BlockNumber
|
||||||
mdnblocks(Relation reln)
|
mdnblocks(Relation reln)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
MdfdVec *v;
|
MdfdVec *v;
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
int nblocks;
|
BlockNumber nblocks;
|
||||||
int segno;
|
BlockNumber segno;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fd = _mdfd_getrelnfd(reln);
|
fd = _mdfd_getrelnfd(reln);
|
||||||
|
@ -679,10 +677,10 @@ mdnblocks(Relation reln)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ);
|
nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ);
|
||||||
if (nblocks > RELSEG_SIZE)
|
if (nblocks > ((BlockNumber) RELSEG_SIZE))
|
||||||
elog(FATAL, "segment too big in mdnblocks!");
|
elog(FATAL, "segment too big in mdnblocks!");
|
||||||
if (nblocks < RELSEG_SIZE)
|
if (nblocks < ((BlockNumber) RELSEG_SIZE))
|
||||||
return (segno * RELSEG_SIZE) + nblocks;
|
return (segno * ((BlockNumber) RELSEG_SIZE)) + nblocks;
|
||||||
/*
|
/*
|
||||||
* If segment is exactly RELSEG_SIZE, advance to next one.
|
* 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.
|
* mdtruncate() -- Truncate relation to specified number of blocks.
|
||||||
*
|
*
|
||||||
* Returns # of blocks or -1 on error.
|
* Returns # of blocks or InvalidBlockNumber on error.
|
||||||
*/
|
*/
|
||||||
int
|
BlockNumber
|
||||||
mdtruncate(Relation reln, int nblocks)
|
mdtruncate(Relation reln, BlockNumber nblocks)
|
||||||
{
|
{
|
||||||
int curnblk;
|
|
||||||
int fd;
|
int fd;
|
||||||
MdfdVec *v;
|
MdfdVec *v;
|
||||||
|
BlockNumber curnblk;
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
int priorblocks;
|
BlockNumber priorblocks;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -732,8 +728,8 @@ mdtruncate(Relation reln, int nblocks)
|
||||||
* that truncate/delete loop will get them all!
|
* that truncate/delete loop will get them all!
|
||||||
*/
|
*/
|
||||||
curnblk = mdnblocks(reln);
|
curnblk = mdnblocks(reln);
|
||||||
if (nblocks < 0 || nblocks > curnblk)
|
if (nblocks > curnblk)
|
||||||
return -1; /* bogus request */
|
return InvalidBlockNumber; /* bogus request */
|
||||||
if (nblocks == curnblk)
|
if (nblocks == curnblk)
|
||||||
return nblocks; /* no work */
|
return nblocks; /* no work */
|
||||||
|
|
||||||
|
@ -748,7 +744,6 @@ mdtruncate(Relation reln, int nblocks)
|
||||||
|
|
||||||
if (priorblocks > nblocks)
|
if (priorblocks > nblocks)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This segment is no longer wanted at all (and has already
|
* This segment is no longer wanted at all (and has already
|
||||||
* been unlinked from the mdfd_chain). We truncate the file
|
* been unlinked from the mdfd_chain). We truncate the file
|
||||||
|
@ -763,27 +758,25 @@ mdtruncate(Relation reln, int nblocks)
|
||||||
* segment */
|
* segment */
|
||||||
pfree(ov);
|
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
|
* This is the last segment we want to keep. Truncate the file
|
||||||
* to the right length, and clear chain link that points to
|
* to the right length, and clear chain link that points to
|
||||||
* any remaining segments (which we shall zap). NOTE: if
|
* any remaining segments (which we shall zap). NOTE: if
|
||||||
* nblocks is exactly a multiple K of RELSEG_SIZE, we will
|
* nblocks is exactly a multiple K of RELSEG_SIZE, we will
|
||||||
* truncate the K+1st segment to 0 length but keep it. This is
|
* 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)
|
if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0)
|
||||||
return -1;
|
return InvalidBlockNumber;
|
||||||
v = v->mdfd_chain;
|
v = v->mdfd_chain;
|
||||||
ov->mdfd_chain = (MdfdVec *) NULL;
|
ov->mdfd_chain = (MdfdVec *) NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We still need this segment and 0 or more blocks beyond it,
|
* We still need this segment and 0 or more blocks beyond it,
|
||||||
* so nothing to do here.
|
* so nothing to do here.
|
||||||
|
@ -794,7 +787,7 @@ mdtruncate(Relation reln, int nblocks)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
|
if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
|
||||||
return -1;
|
return InvalidBlockNumber;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return nblocks;
|
return nblocks;
|
||||||
|
@ -940,7 +933,7 @@ _fdvec_free(int fdvec)
|
||||||
}
|
}
|
||||||
|
|
||||||
static MdfdVec *
|
static MdfdVec *
|
||||||
_mdfd_openseg(Relation reln, int segno, int oflags)
|
_mdfd_openseg(Relation reln, BlockNumber segno, int oflags)
|
||||||
{
|
{
|
||||||
MdfdVec *v;
|
MdfdVec *v;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -953,7 +946,7 @@ _mdfd_openseg(Relation reln, int segno, int oflags)
|
||||||
if (segno > 0)
|
if (segno > 0)
|
||||||
{
|
{
|
||||||
fullpath = (char *) palloc(strlen(path) + 12);
|
fullpath = (char *) palloc(strlen(path) + 12);
|
||||||
sprintf(fullpath, "%s.%d", path, segno);
|
sprintf(fullpath, "%s.%u", path, segno);
|
||||||
pfree(path);
|
pfree(path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -977,7 +970,7 @@ _mdfd_openseg(Relation reln, int segno, int oflags)
|
||||||
v->mdfd_chain = (MdfdVec *) NULL;
|
v->mdfd_chain = (MdfdVec *) NULL;
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (_mdnblocks(fd, BLCKSZ) > RELSEG_SIZE)
|
if (_mdnblocks(fd, BLCKSZ) > ((BlockNumber) RELSEG_SIZE))
|
||||||
elog(FATAL, "segment too big on openseg!");
|
elog(FATAL, "segment too big on openseg!");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -1007,17 +1000,19 @@ _mdfd_getrelnfd(Relation reln)
|
||||||
/* Find the segment of the relation holding the specified block */
|
/* Find the segment of the relation holding the specified block */
|
||||||
|
|
||||||
static MdfdVec *
|
static MdfdVec *
|
||||||
_mdfd_getseg(Relation reln, int blkno)
|
_mdfd_getseg(Relation reln, BlockNumber blkno)
|
||||||
{
|
{
|
||||||
MdfdVec *v;
|
MdfdVec *v;
|
||||||
int segno;
|
|
||||||
int fd;
|
int fd;
|
||||||
int i;
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
|
BlockNumber segno;
|
||||||
|
BlockNumber i;
|
||||||
|
#endif
|
||||||
|
|
||||||
fd = _mdfd_getrelnfd(reln);
|
fd = _mdfd_getrelnfd(reln);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#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;
|
segno > 0;
|
||||||
i++, segno--)
|
i++, segno--)
|
||||||
{
|
{
|
||||||
|
@ -1038,7 +1033,7 @@ _mdfd_getseg(Relation reln, int blkno)
|
||||||
v->mdfd_chain = _mdfd_openseg(reln, i, (segno == 1) ? O_CREAT : 0);
|
v->mdfd_chain = _mdfd_openseg(reln, i, (segno == 1) ? O_CREAT : 0);
|
||||||
|
|
||||||
if (v->mdfd_chain == (MdfdVec *) NULL)
|
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);
|
i, RelationGetRelationName(reln), blkno);
|
||||||
}
|
}
|
||||||
v = v->mdfd_chain;
|
v = v->mdfd_chain;
|
||||||
|
@ -1064,26 +1059,24 @@ _mdfd_getseg(Relation reln, int blkno)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_mdfd_blind_getseg(RelFileNode rnode, int blkno)
|
_mdfd_blind_getseg(RelFileNode rnode, BlockNumber blkno)
|
||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
int segno;
|
BlockNumber segno;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
path = relpath(rnode);
|
path = relpath(rnode);
|
||||||
|
|
||||||
#ifndef LET_OS_MANAGE_FILESIZE
|
#ifndef LET_OS_MANAGE_FILESIZE
|
||||||
/* append the '.segno', if needed */
|
/* append the '.segno', if needed */
|
||||||
segno = blkno / RELSEG_SIZE;
|
segno = blkno / ((BlockNumber) RELSEG_SIZE);
|
||||||
if (segno > 0)
|
if (segno > 0)
|
||||||
{
|
{
|
||||||
char *segpath = (char *) palloc(strlen(path) + 12);
|
char *segpath = (char *) palloc(strlen(path) + 12);
|
||||||
|
|
||||||
sprintf(segpath, "%s.%d", path, segno);
|
sprintf(segpath, "%s.%u", path, segno);
|
||||||
pfree(path);
|
pfree(path);
|
||||||
path = segpath;
|
path = segpath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* 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)
|
mmnblocks(Relation reln)
|
||||||
{
|
{
|
||||||
MMRelTag rtag;
|
MMRelTag rtag;
|
||||||
MMRelHashEntry *rentry;
|
MMRelHashEntry *rentry;
|
||||||
bool found;
|
bool found;
|
||||||
int nblocks;
|
BlockNumber nblocks;
|
||||||
|
|
||||||
if (reln->rd_rel->relisshared)
|
if (reln->rd_rel->relisshared)
|
||||||
rtag.mmrt_dbid = (Oid) 0;
|
rtag.mmrt_dbid = (Oid) 0;
|
||||||
|
@ -520,7 +520,7 @@ mmnblocks(Relation reln)
|
||||||
if (found)
|
if (found)
|
||||||
nblocks = rentry->mmrhe_nblocks;
|
nblocks = rentry->mmrhe_nblocks;
|
||||||
else
|
else
|
||||||
nblocks = -1;
|
nblocks = InvalidBlockNumber;
|
||||||
|
|
||||||
SpinRelease(MMCacheLock);
|
SpinRelease(MMCacheLock);
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,14 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "postgres.h"
|
||||||
|
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
#include "storage/freespace.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
@ -44,8 +45,8 @@ typedef struct f_smgr
|
||||||
char *buffer, bool dofsync);
|
char *buffer, bool dofsync);
|
||||||
int (*smgr_markdirty) (Relation reln, BlockNumber blkno);
|
int (*smgr_markdirty) (Relation reln, BlockNumber blkno);
|
||||||
int (*smgr_blindmarkdirty) (RelFileNode, BlockNumber blkno);
|
int (*smgr_blindmarkdirty) (RelFileNode, BlockNumber blkno);
|
||||||
int (*smgr_nblocks) (Relation reln);
|
BlockNumber (*smgr_nblocks) (Relation reln);
|
||||||
int (*smgr_truncate) (Relation reln, int nblocks);
|
BlockNumber (*smgr_truncate) (Relation reln, BlockNumber nblocks);
|
||||||
int (*smgr_commit) (void); /* may be NULL */
|
int (*smgr_commit) (void); /* may be NULL */
|
||||||
int (*smgr_abort) (void); /* may be NULL */
|
int (*smgr_abort) (void); /* may be NULL */
|
||||||
int (*smgr_sync) (void);
|
int (*smgr_sync) (void);
|
||||||
|
@ -433,16 +434,10 @@ smgrblindmarkdirty(int16 which,
|
||||||
* Returns the number of blocks on success, aborts the current
|
* Returns the number of blocks on success, aborts the current
|
||||||
* transaction on failure.
|
* transaction on failure.
|
||||||
*/
|
*/
|
||||||
int
|
BlockNumber
|
||||||
smgrnblocks(int16 which, Relation reln)
|
smgrnblocks(int16 which, Relation reln)
|
||||||
{
|
{
|
||||||
int nblocks;
|
return (*(smgrsw[which].smgr_nblocks)) (reln);
|
||||||
|
|
||||||
if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0)
|
|
||||||
elog(ERROR, "cannot count blocks for %s: %m",
|
|
||||||
RelationGetRelationName(reln));
|
|
||||||
|
|
||||||
return nblocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -452,16 +447,24 @@ smgrnblocks(int16 which, Relation reln)
|
||||||
* Returns the number of blocks on success, aborts the current
|
* Returns the number of blocks on success, aborts the current
|
||||||
* transaction on failure.
|
* transaction on failure.
|
||||||
*/
|
*/
|
||||||
int
|
BlockNumber
|
||||||
smgrtruncate(int16 which, Relation reln, int nblocks)
|
smgrtruncate(int16 which, Relation reln, BlockNumber nblocks)
|
||||||
{
|
{
|
||||||
int newblks;
|
BlockNumber newblks;
|
||||||
|
|
||||||
newblks = nblocks;
|
newblks = nblocks;
|
||||||
if (smgrsw[which].smgr_truncate)
|
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);
|
RelationGetRelationName(reln), nblocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +484,6 @@ smgrDoPendingDeletes(bool isCommit)
|
||||||
pendingDeletes = pending->next;
|
pendingDeletes = pending->next;
|
||||||
if (pending->atCommit == isCommit)
|
if (pending->atCommit == isCommit)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get rid of any leftover buffers for the rel (shouldn't be
|
* Get rid of any leftover buffers for the rel (shouldn't be
|
||||||
* any in the commit case, but there can be in the abort
|
* any in the commit case, but there can be in the abort
|
||||||
|
@ -489,6 +491,13 @@ smgrDoPendingDeletes(bool isCommit)
|
||||||
*/
|
*/
|
||||||
DropRelFileNodeBuffers(pending->relnode);
|
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.
|
* And delete the physical files.
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* The following code contains many undocumented hacks. Please be
|
* The following code contains many undocumented hacks. Please be
|
||||||
* careful....
|
* careful....
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
@ -63,7 +62,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
|
* 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_class[Natts_pg_class] = {Schema_pg_class};
|
||||||
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
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,
|
* Relations are looked up two ways, by name and by id,
|
||||||
* thus there are two hash tables for referencing them.
|
* thus there are two hash tables for referencing them.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static HTAB *RelationNameCache;
|
static HTAB *RelationNameCache;
|
||||||
static HTAB *RelationIdCache;
|
static HTAB *RelationIdCache;
|
||||||
|
@ -105,7 +102,6 @@ static bool criticalRelcachesBuilt = false;
|
||||||
/*
|
/*
|
||||||
* RelationBuildDescInfo exists so code can be shared
|
* RelationBuildDescInfo exists so code can be shared
|
||||||
* between RelationIdGetRelation() and RelationNameGetRelation()
|
* between RelationIdGetRelation() and RelationNameGetRelation()
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
typedef struct RelationBuildDescInfo
|
typedef struct RelationBuildDescInfo
|
||||||
{
|
{
|
||||||
|
@ -139,7 +135,6 @@ typedef struct relnodecacheent
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macros to manipulate name cache and id cache
|
* macros to manipulate name cache and id cache
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#define RelationCacheInsert(RELATION) \
|
#define RelationCacheInsert(RELATION) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -285,7 +280,6 @@ static List *insert_ordered_oid(List *list, Oid datum);
|
||||||
/*
|
/*
|
||||||
* RelationIdGetRelation() and RelationNameGetRelation()
|
* RelationIdGetRelation() and RelationNameGetRelation()
|
||||||
* support functions
|
* 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
|
* NB: the returned tuple has been copied into palloc'd storage
|
||||||
* and must eventually be freed with heap_freetuple.
|
* and must eventually be freed with heap_freetuple.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static HeapTuple
|
static HeapTuple
|
||||||
ScanPgRelation(RelationBuildDescInfo buildinfo)
|
ScanPgRelation(RelationBuildDescInfo buildinfo)
|
||||||
|
@ -327,7 +320,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
switch (buildinfo.infotype)
|
switch (buildinfo.infotype)
|
||||||
{
|
{
|
||||||
|
@ -352,7 +344,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open pg_class and fetch a tuple
|
* open pg_class and fetch a tuple
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
|
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
|
||||||
pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key);
|
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
|
* get set to return tuple
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (!HeapTupleIsValid(pg_class_tuple))
|
if (!HeapTupleIsValid(pg_class_tuple))
|
||||||
return_tuple = 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.
|
* returned here without having the corresponding buffer pinned.
|
||||||
* so when the buffer gets replaced, all hell breaks loose. this
|
* so when the buffer gets replaced, all hell breaks loose. this
|
||||||
* bug is discovered and killed by wei on 9/27/91.
|
* bug is discovered and killed by wei on 9/27/91.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
return_tuple = heap_copytuple(pg_class_tuple);
|
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 'relation' is NULL, allocate a new RelationData object.
|
||||||
* If not, reuse the given object (that path is taken only when
|
* If not, reuse the given object (that path is taken only when
|
||||||
* we have to rebuild a relcache entry during RelationClearRelation).
|
* we have to rebuild a relcache entry during RelationClearRelation).
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static Relation
|
static Relation
|
||||||
AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
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
|
* allocate space for new relation descriptor, if needed
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (relation == NULL)
|
if (relation == NULL)
|
||||||
relation = (Relation) palloc(sizeof(RelationData));
|
relation = (Relation) palloc(sizeof(RelationData));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clear all fields of reldesc
|
* clear all fields of reldesc
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
MemSet((char *) relation, 0, sizeof(RelationData));
|
MemSet((char *) relation, 0, sizeof(RelationData));
|
||||||
|
relation->rd_targblock = InvalidBlockNumber;
|
||||||
|
|
||||||
/* make sure relation is marked as having no open file yet */
|
/* make sure relation is marked as having no open file yet */
|
||||||
relation->rd_fd = -1;
|
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
|
* wouldn't know if the value is valid ... bottom line is that relacl
|
||||||
* *cannot* be retrieved from the relcache. Get it from the syscache
|
* *cannot* be retrieved from the relcache. Get it from the syscache
|
||||||
* if you need it.
|
* if you need it.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
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
|
* Form the relation's tuple descriptor from information in
|
||||||
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
|
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
||||||
|
@ -574,7 +559,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_attribute_attrelid,
|
Anum_pg_attribute_attrelid,
|
||||||
|
@ -583,14 +567,12 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open pg_attribute and begin a scan
|
* open pg_attribute and begin a scan
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
|
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
|
||||||
pg_attribute_scan = heap_beginscan(pg_attribute_desc, 0, SnapshotNow, 1, &key);
|
pg_attribute_scan = heap_beginscan(pg_attribute_desc, 0, SnapshotNow, 1, &key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add attribute data to relation->rd_att
|
* add attribute data to relation->rd_att
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
need = relation->rd_rel->relnatts;
|
need = relation->rd_rel->relnatts;
|
||||||
|
|
||||||
|
@ -639,7 +621,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* end the scan and close the attribute relation
|
* end the scan and close the attribute relation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
heap_endscan(pg_attribute_scan);
|
heap_endscan(pg_attribute_scan);
|
||||||
heap_close(pg_attribute_desc, AccessShareLock);
|
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
|
* The attcacheoff values we read from pg_attribute should all be -1
|
||||||
* ("unknown"). Verify this if assert checking is on. They will be
|
* ("unknown"). Verify this if assert checking is on. They will be
|
||||||
* computed when and if needed during tuple access.
|
* computed when and if needed during tuple access.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
{
|
{
|
||||||
|
@ -664,7 +644,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
* attribute: it must be zero. This eliminates the need for special
|
* attribute: it must be zero. This eliminates the need for special
|
||||||
* cases for attnum=1 that used to exist in fastgetattr() and
|
* cases for attnum=1 that used to exist in fastgetattr() and
|
||||||
* index_getattr().
|
* index_getattr().
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relation->rd_att->attrs[0]->attcacheoff = 0;
|
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
|
* The attcacheoff values we read from pg_attribute should all be -1
|
||||||
* ("unknown"). Verify this if assert checking is on. They will be
|
* ("unknown"). Verify this if assert checking is on. They will be
|
||||||
* computed when and if needed during tuple access.
|
* computed when and if needed during tuple access.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
for (i = 0; i < relation->rd_rel->relnatts; i++)
|
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
|
* attribute: it must be zero. This eliminates the need for special
|
||||||
* cases for attnum=1 that used to exist in fastgetattr() and
|
* cases for attnum=1 that used to exist in fastgetattr() and
|
||||||
* index_getattr().
|
* index_getattr().
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relation->rd_att->attrs[0]->attcacheoff = 0;
|
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()
|
* entry, because that keeps the update logic in RelationClearRelation()
|
||||||
* manageable. The other subsidiary data structures are simple enough
|
* manageable. The other subsidiary data structures are simple enough
|
||||||
* to be easy to free explicitly, anyway.
|
* to be easy to free explicitly, anyway.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationBuildRuleLock(Relation relation)
|
RelationBuildRuleLock(Relation relation)
|
||||||
|
@ -814,7 +790,7 @@ RelationBuildRuleLock(Relation relation)
|
||||||
*/
|
*/
|
||||||
rulescxt = AllocSetContextCreate(CacheMemoryContext,
|
rulescxt = AllocSetContextCreate(CacheMemoryContext,
|
||||||
RelationGetRelationName(relation),
|
RelationGetRelationName(relation),
|
||||||
0, /* minsize */
|
0, /* minsize */
|
||||||
1024, /* initsize */
|
1024, /* initsize */
|
||||||
1024); /* maxsize */
|
1024); /* maxsize */
|
||||||
relation->rd_rulescxt = rulescxt;
|
relation->rd_rulescxt = rulescxt;
|
||||||
|
@ -822,7 +798,6 @@ RelationBuildRuleLock(Relation relation)
|
||||||
/*
|
/*
|
||||||
* form an array to hold the rewrite rules (the array is extended if
|
* form an array to hold the rewrite rules (the array is extended if
|
||||||
* necessary)
|
* necessary)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
maxlocks = 4;
|
maxlocks = 4;
|
||||||
rules = (RewriteRule **)
|
rules = (RewriteRule **)
|
||||||
|
@ -831,7 +806,6 @@ RelationBuildRuleLock(Relation relation)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_rewrite_ev_class,
|
Anum_pg_rewrite_ev_class,
|
||||||
|
@ -840,7 +814,6 @@ RelationBuildRuleLock(Relation relation)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open pg_rewrite and begin a scan
|
* open pg_rewrite and begin a scan
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
|
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
pg_rewrite_scan = heap_beginscan(pg_rewrite_desc, 0, SnapshotNow, 1, &key);
|
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
|
* end the scan and close the attribute relation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
heap_endscan(pg_rewrite_scan);
|
heap_endscan(pg_rewrite_scan);
|
||||||
heap_close(pg_rewrite_desc, AccessShareLock);
|
heap_close(pg_rewrite_desc, AccessShareLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a RuleLock and insert into relation
|
* form a RuleLock and insert into relation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
|
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
|
||||||
rulelock->numLocks = numlocks;
|
rulelock->numLocks = numlocks;
|
||||||
|
@ -930,7 +901,6 @@ RelationBuildRuleLock(Relation relation)
|
||||||
* Determine whether two RuleLocks are equivalent
|
* Determine whether two RuleLocks are equivalent
|
||||||
*
|
*
|
||||||
* Probably this should be in the rules code someplace...
|
* Probably this should be in the rules code someplace...
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
||||||
|
@ -994,9 +964,9 @@ equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
||||||
* fields:
|
* fields:
|
||||||
*
|
*
|
||||||
* File rd_fd; open file descriptor
|
* 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()
|
* 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_am rd_am; AM tuple
|
||||||
* Form_pg_class rd_rel; RELATION tuple
|
* Form_pg_class rd_rel; RELATION tuple
|
||||||
* Oid rd_id; relation's object id
|
* 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
|
* find the tuple in pg_class corresponding to the given relation id
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
pg_class_tuple = ScanPgRelation(buildinfo);
|
pg_class_tuple = ScanPgRelation(buildinfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if no such tuple exists, return NULL
|
* if no such tuple exists, return NULL
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (!HeapTupleIsValid(pg_class_tuple))
|
if (!HeapTupleIsValid(pg_class_tuple))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get information from the pg_class_tuple
|
* get information from the pg_class_tuple
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relid = pg_class_tuple->t_data->t_oid;
|
relid = pg_class_tuple->t_data->t_oid;
|
||||||
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
||||||
|
@ -1043,37 +1010,31 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
/*
|
/*
|
||||||
* allocate storage for the relation descriptor, and copy
|
* allocate storage for the relation descriptor, and copy
|
||||||
* pg_class_tuple to relation->rd_rel.
|
* pg_class_tuple to relation->rd_rel.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relation = AllocateRelationDesc(oldrelation, relp);
|
relation = AllocateRelationDesc(oldrelation, relp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we can free the memory allocated for pg_class_tuple
|
* now we can free the memory allocated for pg_class_tuple
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
heap_freetuple(pg_class_tuple);
|
heap_freetuple(pg_class_tuple);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the relation's relation id (relation->rd_id)
|
* initialize the relation's relation id (relation->rd_id)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
RelationGetRelid(relation) = relid;
|
RelationGetRelid(relation) = relid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize relation->rd_refcnt
|
* initialize relation->rd_refcnt
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
RelationSetReferenceCount(relation, 1);
|
RelationSetReferenceCount(relation, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* normal relations are not nailed into the cache
|
* normal relations are not nailed into the cache
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relation->rd_isnailed = false;
|
relation->rd_isnailed = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the access method information (relation->rd_am)
|
* initialize the access method information (relation->rd_am)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relam = relation->rd_rel->relam;
|
relam = relation->rd_rel->relam;
|
||||||
if (OidIsValid(relam))
|
if (OidIsValid(relam))
|
||||||
|
@ -1082,13 +1043,11 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the tuple descriptor (relation->rd_att).
|
* initialize the tuple descriptor (relation->rd_att).
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
RelationBuildTupleDesc(buildinfo, relation);
|
RelationBuildTupleDesc(buildinfo, relation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch rules and triggers that affect this relation
|
* Fetch rules and triggers that affect this relation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (relation->rd_rel->relhasrules)
|
if (relation->rd_rel->relhasrules)
|
||||||
RelationBuildRuleLock(relation);
|
RelationBuildRuleLock(relation);
|
||||||
|
@ -1105,14 +1064,12 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize index strategy and support information for this relation
|
* initialize index strategy and support information for this relation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (OidIsValid(relam))
|
if (OidIsValid(relam))
|
||||||
IndexedAccessMethodInitialize(relation);
|
IndexedAccessMethodInitialize(relation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the relation lock manager information
|
* initialize the relation lock manager information
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
RelationInitLockInfo(relation); /* see lmgr.c */
|
RelationInitLockInfo(relation); /* see lmgr.c */
|
||||||
|
|
||||||
|
@ -1144,7 +1101,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
/*
|
/*
|
||||||
* insert newly created relation into proper relcaches, restore memory
|
* insert newly created relation into proper relcaches, restore memory
|
||||||
* context and return the new reldesc.
|
* context and return the new reldesc.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
RelationCacheInsert(relation);
|
RelationCacheInsert(relation);
|
||||||
|
@ -1214,11 +1170,14 @@ formrdesc(char *relationName,
|
||||||
* allocate new relation desc
|
* allocate new relation desc
|
||||||
*/
|
*/
|
||||||
relation = (Relation) palloc(sizeof(RelationData));
|
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;
|
relation->rd_fd = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1329,7 +1288,6 @@ fixrdesc(char *relationName)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find the tuple in pg_class corresponding to the given relation name
|
* find the tuple in pg_class corresponding to the given relation name
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELNAME;
|
buildinfo.infotype = INFO_RELNAME;
|
||||||
buildinfo.i.info_name = relationName;
|
buildinfo.i.info_name = relationName;
|
||||||
|
@ -1343,7 +1301,6 @@ fixrdesc(char *relationName)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find the pre-made relcache entry (better be there!)
|
* find the pre-made relcache entry (better be there!)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
relation = RelationNameCacheGetRelation(relationName);
|
relation = RelationNameCacheGetRelation(relationName);
|
||||||
if (!RelationIsValid(relation))
|
if (!RelationIsValid(relation))
|
||||||
|
@ -1353,7 +1310,6 @@ fixrdesc(char *relationName)
|
||||||
/*
|
/*
|
||||||
* and copy pg_class_tuple to relation->rd_rel. (See notes in
|
* and copy pg_class_tuple to relation->rd_rel. (See notes in
|
||||||
* AllocateRelationDesc())
|
* AllocateRelationDesc())
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Assert(relation->rd_rel != NULL);
|
Assert(relation->rd_rel != NULL);
|
||||||
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
|
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.
|
* NB: relation ref count is incremented if successful.
|
||||||
* Caller should eventually decrement count. (Usually,
|
* Caller should eventually decrement count. (Usually,
|
||||||
* that happens by calling RelationClose().)
|
* that happens by calling RelationClose().)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationIdCacheGetRelation(Oid relationId)
|
RelationIdCacheGetRelation(Oid relationId)
|
||||||
|
@ -1403,7 +1358,6 @@ RelationIdCacheGetRelation(Oid relationId)
|
||||||
* RelationNameCacheGetRelation
|
* RelationNameCacheGetRelation
|
||||||
*
|
*
|
||||||
* As above, but lookup by name.
|
* As above, but lookup by name.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static Relation
|
static Relation
|
||||||
RelationNameCacheGetRelation(const char *relationName)
|
RelationNameCacheGetRelation(const char *relationName)
|
||||||
|
@ -1457,7 +1411,6 @@ RelationNodeCacheGetRelation(RelFileNode rnode)
|
||||||
* NB: relation ref count is incremented, or set to 1 if new entry.
|
* NB: relation ref count is incremented, or set to 1 if new entry.
|
||||||
* Caller should eventually decrement count. (Usually,
|
* Caller should eventually decrement count. (Usually,
|
||||||
* that happens by calling RelationClose().)
|
* that happens by calling RelationClose().)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationIdGetRelation(Oid relationId)
|
RelationIdGetRelation(Oid relationId)
|
||||||
|
@ -1467,14 +1420,12 @@ RelationIdGetRelation(Oid relationId)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* increment access statistics
|
* increment access statistics
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
IncrHeapAccessStat(local_RelationIdGetRelation);
|
IncrHeapAccessStat(local_RelationIdGetRelation);
|
||||||
IncrHeapAccessStat(global_RelationIdGetRelation);
|
IncrHeapAccessStat(global_RelationIdGetRelation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first try and get a reldesc from the cache
|
* first try and get a reldesc from the cache
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
rd = RelationIdCacheGetRelation(relationId);
|
rd = RelationIdCacheGetRelation(relationId);
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
|
@ -1483,7 +1434,6 @@ RelationIdGetRelation(Oid relationId)
|
||||||
/*
|
/*
|
||||||
* no reldesc in the cache, so have RelationBuildDesc() build one and
|
* no reldesc in the cache, so have RelationBuildDesc() build one and
|
||||||
* add it.
|
* add it.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELID;
|
buildinfo.infotype = INFO_RELID;
|
||||||
buildinfo.i.info_id = relationId;
|
buildinfo.i.info_id = relationId;
|
||||||
|
@ -1496,7 +1446,6 @@ RelationIdGetRelation(Oid relationId)
|
||||||
* RelationNameGetRelation
|
* RelationNameGetRelation
|
||||||
*
|
*
|
||||||
* As above, but lookup by name.
|
* As above, but lookup by name.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationNameGetRelation(const char *relationName)
|
RelationNameGetRelation(const char *relationName)
|
||||||
|
@ -1507,7 +1456,6 @@ RelationNameGetRelation(const char *relationName)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* increment access statistics
|
* increment access statistics
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
IncrHeapAccessStat(local_RelationNameGetRelation);
|
IncrHeapAccessStat(local_RelationNameGetRelation);
|
||||||
IncrHeapAccessStat(global_RelationNameGetRelation);
|
IncrHeapAccessStat(global_RelationNameGetRelation);
|
||||||
|
@ -1515,7 +1463,6 @@ RelationNameGetRelation(const char *relationName)
|
||||||
/*
|
/*
|
||||||
* if caller is looking for a temp relation, substitute its real name;
|
* if caller is looking for a temp relation, substitute its real name;
|
||||||
* we only index temp rels by their real names.
|
* we only index temp rels by their real names.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
temprelname = get_temp_rel_by_username(relationName);
|
temprelname = get_temp_rel_by_username(relationName);
|
||||||
if (temprelname != NULL)
|
if (temprelname != NULL)
|
||||||
|
@ -1523,7 +1470,6 @@ RelationNameGetRelation(const char *relationName)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first try and get a reldesc from the cache
|
* first try and get a reldesc from the cache
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
rd = RelationNameCacheGetRelation(relationName);
|
rd = RelationNameCacheGetRelation(relationName);
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
|
@ -1532,7 +1478,6 @@ RelationNameGetRelation(const char *relationName)
|
||||||
/*
|
/*
|
||||||
* no reldesc in the cache, so have RelationBuildDesc() build one and
|
* no reldesc in the cache, so have RelationBuildDesc() build one and
|
||||||
* add it.
|
* add it.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELNAME;
|
buildinfo.infotype = INFO_RELNAME;
|
||||||
buildinfo.i.info_name = (char *) relationName;
|
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
|
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
|
||||||
* to catch references to already-released relcache entries. It slows
|
* to catch references to already-released relcache entries. It slows
|
||||||
* things down quite a bit, however.
|
* things down quite a bit, however.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationClose(Relation relation)
|
RelationClose(Relation relation)
|
||||||
|
@ -1577,7 +1521,6 @@ RelationClose(Relation relation)
|
||||||
* This function is especially for nailed relations.
|
* This function is especially for nailed relations.
|
||||||
* relhasindex/relfilenode could be changed even for
|
* relhasindex/relfilenode could be changed even for
|
||||||
* nailed relations.
|
* nailed relations.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationReloadClassinfo(Relation relation)
|
RelationReloadClassinfo(Relation relation)
|
||||||
|
@ -1616,7 +1559,6 @@ RelationReloadClassinfo(Relation relation)
|
||||||
* usually used when we are notified of a change to an open relation
|
* usually used when we are notified of a change to an open relation
|
||||||
* (one with refcount > 0). However, this routine just does whichever
|
* (one with refcount > 0). However, this routine just does whichever
|
||||||
* it's told to do; callers must determine which they want.
|
* it's told to do; callers must determine which they want.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationClearRelation(Relation relation, bool rebuildIt)
|
RelationClearRelation(Relation relation, bool rebuildIt)
|
||||||
|
@ -1631,7 +1573,10 @@ RelationClearRelation(Relation relation, bool rebuildIt)
|
||||||
* a vacuum truncation.
|
* a vacuum truncation.
|
||||||
*/
|
*/
|
||||||
if (relation->rd_fd >= 0)
|
if (relation->rd_fd >= 0)
|
||||||
|
{
|
||||||
smgrclose(DEFAULT_SMGR, relation);
|
smgrclose(DEFAULT_SMGR, relation);
|
||||||
|
relation->rd_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Never, never ever blow away a nailed-in system relation, because
|
* 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)
|
* we save/restore rd_nblocks (in case it is a local relation)
|
||||||
* *and* call RelationGetNumberOfBlocks (in case it isn't).
|
* *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;
|
bool old_myxactonly = relation->rd_myxactonly;
|
||||||
TupleDesc old_att = relation->rd_att;
|
TupleDesc old_att = relation->rd_att;
|
||||||
RuleLock *old_rules = relation->rd_rules;
|
RuleLock *old_rules = relation->rd_rules;
|
||||||
MemoryContext old_rulescxt = relation->rd_rulescxt;
|
MemoryContext old_rulescxt = relation->rd_rulescxt;
|
||||||
TriggerDesc *old_trigdesc = relation->trigdesc;
|
TriggerDesc *old_trigdesc = relation->trigdesc;
|
||||||
int old_nblocks = relation->rd_nblocks;
|
BlockNumber old_nblocks = relation->rd_nblocks;
|
||||||
RelationBuildDescInfo buildinfo;
|
RelationBuildDescInfo buildinfo;
|
||||||
|
|
||||||
buildinfo.infotype = INFO_RELID;
|
buildinfo.infotype = INFO_RELID;
|
||||||
|
@ -1767,7 +1712,6 @@ RelationClearRelation(Relation relation, bool rebuildIt)
|
||||||
* RelationFlushRelation
|
* RelationFlushRelation
|
||||||
*
|
*
|
||||||
* Rebuild the relation if it is open (refcount > 0), else blow it away.
|
* Rebuild the relation if it is open (refcount > 0), else blow it away.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationFlushRelation(Relation relation)
|
RelationFlushRelation(Relation relation)
|
||||||
|
@ -1801,7 +1745,6 @@ RelationFlushRelation(Relation relation)
|
||||||
* RelationClearRelation + if the relation is myxactonly then
|
* RelationClearRelation + if the relation is myxactonly then
|
||||||
* remove the relation descriptor from the newly created
|
* remove the relation descriptor from the newly created
|
||||||
* relation list.
|
* relation list.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationForgetRelation(Oid rid)
|
RelationForgetRelation(Oid rid)
|
||||||
|
@ -1851,7 +1794,6 @@ RelationForgetRelation(Oid rid)
|
||||||
* safer to process them, so that our *own* SI update messages will
|
* safer to process them, so that our *own* SI update messages will
|
||||||
* have the same effects during CommandCounterIncrement for both
|
* have the same effects during CommandCounterIncrement for both
|
||||||
* local and nonlocal relations.
|
* local and nonlocal relations.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
|
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
|
||||||
|
@ -1989,7 +1931,6 @@ RelationCacheAbortWalker(Relation *relationPtr, Datum dummy)
|
||||||
* RelationRegisterRelation -
|
* RelationRegisterRelation -
|
||||||
* register the Relation descriptor of a newly created relation
|
* register the Relation descriptor of a newly created relation
|
||||||
* with the relation descriptor Cache.
|
* with the relation descriptor Cache.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationRegisterRelation(Relation relation)
|
RelationRegisterRelation(Relation relation)
|
||||||
|
@ -2048,7 +1989,6 @@ RelationPurgeLocalRelation(bool xactCommitted)
|
||||||
* RelationCacheInitialize
|
* RelationCacheInitialize
|
||||||
*
|
*
|
||||||
* This initializes the relation descriptor cache.
|
* This initializes the relation descriptor cache.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INITRELCACHESIZE 400
|
#define INITRELCACHESIZE 400
|
||||||
|
@ -2061,7 +2001,6 @@ RelationCacheInitialize(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to cache memory context
|
* switch to cache memory context
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (!CacheMemoryContext)
|
if (!CacheMemoryContext)
|
||||||
CreateCacheMemoryContext();
|
CreateCacheMemoryContext();
|
||||||
|
@ -2070,7 +2009,6 @@ RelationCacheInitialize(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create global caches
|
* create global caches
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
MemSet(&ctl, 0, (int) sizeof(ctl));
|
MemSet(&ctl, 0, (int) sizeof(ctl));
|
||||||
ctl.keysize = sizeof(NameData);
|
ctl.keysize = sizeof(NameData);
|
||||||
|
@ -2093,7 +2031,6 @@ RelationCacheInitialize(void)
|
||||||
* be in the cache.
|
* be in the cache.
|
||||||
*
|
*
|
||||||
* NB: see also the list in RelationCacheInitializePhase2().
|
* NB: see also the list in RelationCacheInitializePhase2().
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
|
formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
|
||||||
formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
|
formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
|
||||||
|
@ -2115,7 +2052,6 @@ RelationCacheInitialize(void)
|
||||||
*
|
*
|
||||||
* This completes initialization of the relcache after catcache
|
* This completes initialization of the relcache after catcache
|
||||||
* is functional and we are able to actually load data from pg_class.
|
* is functional and we are able to actually load data from pg_class.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationCacheInitializePhase2(void)
|
RelationCacheInitializePhase2(void)
|
||||||
|
@ -2658,7 +2594,8 @@ init_irels(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the file descriptor is not yet opened */
|
/* reset transient fields */
|
||||||
|
ird->rd_targblock = InvalidBlockNumber;
|
||||||
ird->rd_fd = -1;
|
ird->rd_fd = -1;
|
||||||
|
|
||||||
ird->rd_node.tblNode = MyDatabaseId;
|
ird->rd_node.tblNode = MyDatabaseId;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Support for grand unified configuration scheme, including SET
|
* Support for grand unified configuration scheme, including SET
|
||||||
* command, configuration file, and command line options.
|
* 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
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
|
@ -31,6 +31,8 @@
|
||||||
#include "optimizer/paths.h"
|
#include "optimizer/paths.h"
|
||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
|
#include "storage/freespace.h"
|
||||||
|
#include "storage/lock.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#include "utils/datetime.h"
|
#include "utils/datetime.h"
|
||||||
|
@ -270,11 +272,16 @@ static struct config_int
|
||||||
*/
|
*/
|
||||||
{"max_connections", PGC_POSTMASTER, &MaxBackends,
|
{"max_connections", PGC_POSTMASTER, &MaxBackends,
|
||||||
DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
|
DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
|
||||||
|
|
||||||
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
|
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
|
||||||
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
|
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
|
||||||
|
|
||||||
{"port", PGC_POSTMASTER, &PostPortNumber,
|
{"port", PGC_POSTMASTER, &PostPortNumber,
|
||||||
DEF_PGPORT, 1, 65535, NULL, NULL},
|
DEF_PGPORT, 1, 65535, NULL, NULL},
|
||||||
|
|
||||||
|
{"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
|
||||||
|
0777, 0000, 0777, NULL, NULL},
|
||||||
|
|
||||||
{"sort_mem", PGC_USERSET, &SortMem,
|
{"sort_mem", PGC_USERSET, &SortMem,
|
||||||
512, 4*BLCKSZ/1024, INT_MAX, NULL, NULL},
|
512, 4*BLCKSZ/1024, INT_MAX, NULL, NULL},
|
||||||
|
|
||||||
|
@ -290,8 +297,13 @@ static struct config_int
|
||||||
{"max_expr_depth", PGC_USERSET, &max_expr_depth,
|
{"max_expr_depth", PGC_USERSET, &max_expr_depth,
|
||||||
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL},
|
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL},
|
||||||
|
|
||||||
{"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
|
{"max_fsm_relations", PGC_POSTMASTER, &MaxFSMRelations,
|
||||||
0777, 0000, 0777, NULL, NULL},
|
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,
|
{"checkpoint_segments", PGC_SIGHUP, &CheckPointSegments,
|
||||||
3, 1, INT_MAX, NULL, NULL},
|
3, 1, INT_MAX, NULL, NULL},
|
||||||
|
|
|
@ -44,11 +44,19 @@
|
||||||
#krb_server_keyfile = ''
|
#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
|
# Performance
|
||||||
#
|
#
|
||||||
#sort_mem = 512
|
#sort_mem = 512
|
||||||
#shared_buffers = 64 # 2*max_connections, min 16
|
|
||||||
#fsync = true
|
#fsync = true
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,7 +86,7 @@
|
||||||
# GEQO Optimizer Parameters
|
# GEQO Optimizer Parameters
|
||||||
#
|
#
|
||||||
#geqo_threshold = 11
|
#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_effort = 1
|
||||||
#geqo_generations = 0
|
#geqo_generations = 0
|
||||||
#geqo_random_seed = -1 # auto-compute seed
|
#geqo_random_seed = -1 # auto-compute seed
|
||||||
|
@ -87,7 +95,6 @@
|
||||||
#
|
#
|
||||||
# Write-ahead log (WAL)
|
# Write-ahead log (WAL)
|
||||||
#
|
#
|
||||||
#wal_buffers = 8 # min 4
|
|
||||||
#wal_files = 0 # range 0-64
|
#wal_files = 0 # range 0-64
|
||||||
#wal_sync_method = fsync # fsync or fdatasync or open_sync or open_datasync
|
#wal_sync_method = fsync # fsync or fdatasync or open_sync or open_datasync
|
||||||
# Note: default wal_sync_method varies across platforms
|
# Note: default wal_sync_method varies across platforms
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
#define VACUUM_H
|
||||||
|
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "storage/block.h"
|
||||||
|
|
||||||
|
|
||||||
/* in commands/vacuum.c */
|
/* in commands/vacuum.c */
|
||||||
extern void vacuum(VacuumStmt *vacstmt);
|
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);
|
bool hasindex);
|
||||||
/* in commands/analyze.c */
|
/* in commands/analyze.c */
|
||||||
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);
|
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);
|
||||||
|
|
|
@ -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 */
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* 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
|
* instead include this file because on Ultrix, sys/ipc.h is not designed
|
||||||
|
@ -74,6 +74,7 @@ typedef enum _LockId_
|
||||||
LOCKMGRLOCKID,
|
LOCKMGRLOCKID,
|
||||||
SINVALLOCKID,
|
SINVALLOCKID,
|
||||||
PROCSTRUCTLOCKID,
|
PROCSTRUCTLOCKID,
|
||||||
|
FREESPACELOCKID,
|
||||||
|
|
||||||
#ifdef STABLE_MEMORY_STORAGE
|
#ifdef STABLE_MEMORY_STORAGE
|
||||||
MMCACHELOCKID,
|
MMCACHELOCKID,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 SPINLOCK LockMgrLock;
|
||||||
|
|
||||||
|
extern int max_locks_per_xact;
|
||||||
|
|
||||||
#ifdef LOCK_DEBUG
|
#ifdef LOCK_DEBUG
|
||||||
extern int Trace_lock_oidmin;
|
extern int Trace_lock_oidmin;
|
||||||
extern bool Trace_locks;
|
extern bool Trace_locks;
|
||||||
|
@ -41,19 +43,6 @@ extern bool Debug_deadlocks;
|
||||||
#endif /* LOCK_DEBUG */
|
#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 LOCKMASK;
|
||||||
|
|
||||||
typedef int LOCKMODE;
|
typedef int LOCKMODE;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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,
|
extern int smgrblindmarkdirty(int16 which, RelFileNode rnode,
|
||||||
BlockNumber blkno);
|
BlockNumber blkno);
|
||||||
extern int smgrmarkdirty(int16 which, Relation reln, BlockNumber blkno);
|
extern int smgrmarkdirty(int16 which, Relation reln, BlockNumber blkno);
|
||||||
extern int smgrnblocks(int16 which, Relation reln);
|
extern BlockNumber smgrnblocks(int16 which, Relation reln);
|
||||||
extern int smgrtruncate(int16 which, Relation reln, int nblocks);
|
extern BlockNumber smgrtruncate(int16 which, Relation reln,
|
||||||
|
BlockNumber nblocks);
|
||||||
extern int smgrDoPendingDeletes(bool isCommit);
|
extern int smgrDoPendingDeletes(bool isCommit);
|
||||||
extern int smgrcommit(void);
|
extern int smgrcommit(void);
|
||||||
extern int smgrabort(void);
|
extern int smgrabort(void);
|
||||||
|
@ -71,8 +72,8 @@ extern int mdmarkdirty(Relation reln, BlockNumber blkno);
|
||||||
extern int mdblindwrt(RelFileNode rnode, BlockNumber blkno,
|
extern int mdblindwrt(RelFileNode rnode, BlockNumber blkno,
|
||||||
char *buffer, bool dofsync);
|
char *buffer, bool dofsync);
|
||||||
extern int mdblindmarkdirty(RelFileNode rnode, BlockNumber blkno);
|
extern int mdblindmarkdirty(RelFileNode rnode, BlockNumber blkno);
|
||||||
extern int mdnblocks(Relation reln);
|
extern BlockNumber mdnblocks(Relation reln);
|
||||||
extern int mdtruncate(Relation reln, int nblocks);
|
extern BlockNumber mdtruncate(Relation reln, BlockNumber nblocks);
|
||||||
extern int mdcommit(void);
|
extern int mdcommit(void);
|
||||||
extern int mdabort(void);
|
extern int mdabort(void);
|
||||||
extern int mdsync(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 mmmarkdirty(Relation reln, BlockNumber blkno);
|
||||||
extern int mmblindmarkdirty(char *dbname, char *relname, Oid dbid, Oid relid,
|
extern int mmblindmarkdirty(char *dbname, char *relname, Oid dbid, Oid relid,
|
||||||
BlockNumber blkno);
|
BlockNumber blkno);
|
||||||
extern int mmnblocks(Relation reln);
|
extern BlockNumber mmnblocks(Relation reln);
|
||||||
extern int mmtruncate(Relation reln, int nblocks);
|
extern BlockNumber mmtruncate(Relation reln, BlockNumber nblocks);
|
||||||
extern int mmcommit(void);
|
extern int mmcommit(void);
|
||||||
extern int mmabort(void);
|
extern int mmabort(void);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_am.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "rewrite/prs2lock.h"
|
#include "rewrite/prs2lock.h"
|
||||||
#include "storage/relfilenode.h"
|
#include "storage/block.h"
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
|
#include "storage/relfilenode.h"
|
||||||
|
|
||||||
/* added to prevent circular dependency. bjm 1999/11/15 */
|
/* added to prevent circular dependency. bjm 1999/11/15 */
|
||||||
extern char *get_temp_rel_by_physicalname(const char *relname);
|
extern char *get_temp_rel_by_physicalname(const char *relname);
|
||||||
|
@ -105,9 +106,11 @@ typedef struct PgStat_Info
|
||||||
typedef struct RelationData
|
typedef struct RelationData
|
||||||
{
|
{
|
||||||
File rd_fd; /* open file descriptor, or -1 if none */
|
File rd_fd; /* open file descriptor, or -1 if none */
|
||||||
RelFileNode rd_node; /* relation file node */
|
RelFileNode rd_node; /* file node (physical identifier) */
|
||||||
int rd_nblocks; /* number of blocks in rel */
|
BlockNumber rd_nblocks; /* number of blocks in rel */
|
||||||
uint16 rd_refcnt; /* reference count */
|
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_myxactonly; /* rel uses the local buffer mgr */
|
||||||
bool rd_isnailed; /* rel is nailed in cache */
|
bool rd_isnailed; /* rel is nailed in cache */
|
||||||
bool rd_indexfound; /* true if rd_indexlist is valid */
|
bool rd_indexfound; /* true if rd_indexlist is valid */
|
||||||
|
|
Loading…
Reference in New Issue