aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/dbsize.c43
-rw-r--r--src/backend/utils/cache/inval.c20
-rw-r--r--src/backend/utils/cache/relcache.c34
-rw-r--r--src/backend/utils/misc/guc.c40
-rw-r--r--src/backend/utils/probes.d12
5 files changed, 98 insertions, 51 deletions
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index e11c13a9ccf..01a4a17915d 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -5,7 +5,7 @@
* Copyright (c) 2002-2010, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.32 2010/08/05 14:45:04 rhaas Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.33 2010/08/13 20:10:52 rhaas Exp $
*
*/
@@ -244,14 +244,14 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
* calculate size of (one fork of) a relation
*/
static int64
-calculate_relation_size(RelFileNode *rfn, ForkNumber forknum)
+calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
{
int64 totalsize = 0;
char *relationpath;
char pathname[MAXPGPATH];
unsigned int segcount = 0;
- relationpath = relpath(*rfn, forknum);
+ relationpath = relpathbackend(*rfn, backend, forknum);
for (segcount = 0;; segcount++)
{
@@ -291,7 +291,7 @@ pg_relation_size(PG_FUNCTION_ARGS)
rel = relation_open(relOid, AccessShareLock);
- size = calculate_relation_size(&(rel->rd_node),
+ size = calculate_relation_size(&(rel->rd_node), rel->rd_backend,
forkname_to_number(text_to_cstring(forkName)));
relation_close(rel, AccessShareLock);
@@ -315,12 +315,14 @@ calculate_toast_table_size(Oid toastrelid)
/* toast heap size, including FSM and VM size */
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
- size += calculate_relation_size(&(toastRel->rd_node), forkNum);
+ size += calculate_relation_size(&(toastRel->rd_node),
+ toastRel->rd_backend, forkNum);
/* toast index size, including FSM and VM size */
toastIdxRel = relation_open(toastRel->rd_rel->reltoastidxid, AccessShareLock);
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
- size += calculate_relation_size(&(toastIdxRel->rd_node), forkNum);
+ size += calculate_relation_size(&(toastIdxRel->rd_node),
+ toastIdxRel->rd_backend, forkNum);
relation_close(toastIdxRel, AccessShareLock);
relation_close(toastRel, AccessShareLock);
@@ -349,7 +351,8 @@ calculate_table_size(Oid relOid)
* heap size, including FSM and VM
*/
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
- size += calculate_relation_size(&(rel->rd_node), forkNum);
+ size += calculate_relation_size(&(rel->rd_node), rel->rd_backend,
+ forkNum);
/*
* Size of toast relation
@@ -392,7 +395,9 @@ calculate_indexes_size(Oid relOid)
idxRel = relation_open(idxOid, AccessShareLock);
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
- size += calculate_relation_size(&(idxRel->rd_node), forkNum);
+ size += calculate_relation_size(&(idxRel->rd_node),
+ idxRel->rd_backend,
+ forkNum);
relation_close(idxRel, AccessShareLock);
}
@@ -563,6 +568,7 @@ pg_relation_filepath(PG_FUNCTION_ARGS)
HeapTuple tuple;
Form_pg_class relform;
RelFileNode rnode;
+ BackendId backend;
char *path;
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
@@ -600,12 +606,27 @@ pg_relation_filepath(PG_FUNCTION_ARGS)
break;
}
- ReleaseSysCache(tuple);
-
if (!OidIsValid(rnode.relNode))
+ {
+ ReleaseSysCache(tuple);
PG_RETURN_NULL();
+ }
+
+ /* If temporary, determine owning backend. */
+ if (!relform->relistemp)
+ backend = InvalidBackendId;
+ else if (isTempOrToastNamespace(relform->relnamespace))
+ backend = MyBackendId;
+ else
+ {
+ /* Do it the hard way. */
+ backend = GetTempNamespaceBackendId(relform->relnamespace);
+ Assert(backend != InvalidBackendId);
+ }
+
+ ReleaseSysCache(tuple);
- path = relpath(rnode, MAIN_FORKNUM);
+ path = relpathbackend(rnode, backend, MAIN_FORKNUM);
PG_RETURN_TEXT_P(cstring_to_text(path));
}
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 7a67f4a85e8..14904839222 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.98 2010/02/26 02:01:11 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.99 2010/08/13 20:10:52 rhaas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -319,7 +319,8 @@ AddCatcacheInvalidationMessage(InvalidationListHeader *hdr,
{
SharedInvalidationMessage msg;
- msg.cc.id = (int16) id;
+ Assert(id < CHAR_MAX);
+ msg.cc.id = (int8) id;
msg.cc.tuplePtr = *tuplePtr;
msg.cc.dbId = dbId;
msg.cc.hashValue = hashValue;
@@ -513,7 +514,10 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
* We could have smgr entries for relations of other databases, so no
* short-circuit test is possible here.
*/
- smgrclosenode(msg->sm.rnode);
+ RelFileNodeBackend rnode;
+ rnode.node = msg->sm.rnode;
+ rnode.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
+ smgrclosenode(rnode);
}
else if (msg->id == SHAREDINVALRELMAP_ID)
{
@@ -1163,14 +1167,20 @@ CacheInvalidateRelcacheByRelid(Oid relid)
* in commit/abort WAL entries. Instead, calls to CacheInvalidateSmgr()
* should happen in low-level smgr.c routines, which are executed while
* replaying WAL as well as when creating it.
+ *
+ * Note: In order to avoid bloating SharedInvalidationMessage, we store only
+ * three bytes of the backend ID using what would otherwise be padding space.
+ * Thus, the maximum possible backend ID is 2^23-1.
*/
void
-CacheInvalidateSmgr(RelFileNode rnode)
+CacheInvalidateSmgr(RelFileNodeBackend rnode)
{
SharedInvalidationMessage msg;
msg.sm.id = SHAREDINVALSMGR_ID;
- msg.sm.rnode = rnode;
+ msg.sm.backend_hi = rnode.backend >> 16;
+ msg.sm.backend_lo = rnode.backend & 0xffff;
+ msg.sm.rnode = rnode.node;
SendSharedInvalidMessages(&msg, 1);
}
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index f4304bce728..166beb25b15 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.311 2010/07/06 19:18:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.312 2010/08/13 20:10:52 rhaas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -858,10 +858,20 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
relation->rd_istemp = relation->rd_rel->relistemp;
- if (relation->rd_istemp)
- relation->rd_islocaltemp = isTempOrToastNamespace(relation->rd_rel->relnamespace);
+ if (!relation->rd_istemp)
+ relation->rd_backend = InvalidBackendId;
+ else if (isTempOrToastNamespace(relation->rd_rel->relnamespace))
+ relation->rd_backend = MyBackendId;
else
- relation->rd_islocaltemp = false;
+ {
+ /*
+ * If it's a temporary table, but not one of ours, we have to use
+ * the slow, grotty method to figure out the owning backend.
+ */
+ relation->rd_backend =
+ GetTempNamespaceBackendId(relation->rd_rel->relnamespace);
+ Assert(relation->rd_backend != InvalidBackendId);
+ }
/*
* initialize the tuple descriptor (relation->rd_att).
@@ -1424,7 +1434,7 @@ formrdesc(const char *relationName, Oid relationReltype,
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
relation->rd_istemp = false;
- relation->rd_islocaltemp = false;
+ relation->rd_backend = InvalidBackendId;
/*
* initialize relation tuple form
@@ -2515,7 +2525,7 @@ RelationBuildLocalRelation(const char *relname,
/* it is temporary if and only if it is in my temp-table namespace */
rel->rd_istemp = isTempOrToastNamespace(relnamespace);
- rel->rd_islocaltemp = rel->rd_istemp;
+ rel->rd_backend = rel->rd_istemp ? MyBackendId : InvalidBackendId;
/*
* create a new tuple descriptor from the one passed in. We do this
@@ -2629,7 +2639,7 @@ void
RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
{
Oid newrelfilenode;
- RelFileNode newrnode;
+ RelFileNodeBackend newrnode;
Relation pg_class;
HeapTuple tuple;
Form_pg_class classform;
@@ -2640,7 +2650,8 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
TransactionIdIsNormal(freezeXid));
/* Allocate a new relfilenode */
- newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL);
+ newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL,
+ relation->rd_backend);
/*
* Get a writable copy of the pg_class tuple for the given relation.
@@ -2660,9 +2671,10 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
* NOTE: any conflict in relfilenode value will be caught here, if
* GetNewRelFileNode messes up for any reason.
*/
- newrnode = relation->rd_node;
- newrnode.relNode = newrelfilenode;
- RelationCreateStorage(newrnode, relation->rd_istemp);
+ newrnode.node = relation->rd_node;
+ newrnode.node.relNode = newrelfilenode;
+ newrnode.backend = relation->rd_backend;
+ RelationCreateStorage(newrnode.node, relation->rd_istemp);
smgrclosenode(newrnode);
/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 97ed5b72474..dac704ee4cd 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.566 2010/08/06 14:51:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.567 2010/08/13 20:10:53 rhaas Exp $
*
*--------------------------------------------------------------------
*/
@@ -96,6 +96,16 @@
#define MAX_KILOBYTES (INT_MAX / 1024)
#endif
+/*
+ * Note: MAX_BACKENDS is limited to 2^23-1 because inval.c stores the
+ * backend ID as a 3-byte signed integer. Even if that limitation were
+ * removed, we still could not exceed INT_MAX/4 because some places compute
+ * 4*MaxBackends without any overflow check. This is rechecked in
+ * assign_maxconnections, since MaxBackends is computed as MaxConnections
+ * plus autovacuum_max_workers plus one (for the autovacuum launcher).
+ */
+#define MAX_BACKENDS 0x7fffff
+
#define KB_PER_MB (1024)
#define KB_PER_GB (1024*1024)
@@ -1414,23 +1424,13 @@ static struct config_int ConfigureNamesInt[] =
30 * 1000, -1, INT_MAX / 1000, NULL, NULL
},
- /*
- * Note: MaxBackends is limited to INT_MAX/4 because some places compute
- * 4*MaxBackends without any overflow check. This check is made in
- * assign_maxconnections, since MaxBackends is computed as MaxConnections
- * plus autovacuum_max_workers plus one (for the autovacuum launcher).
- *
- * Likewise we have to limit NBuffers to INT_MAX/2.
- *
- * See also CheckRequiredParameterValues() if this parameter changes
- */
{
{"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
gettext_noop("Sets the maximum number of concurrent connections."),
NULL
},
&MaxConnections,
- 100, 1, INT_MAX / 4, assign_maxconnections, NULL
+ 100, 1, MAX_BACKENDS, assign_maxconnections, NULL
},
{
@@ -1439,9 +1439,13 @@ static struct config_int ConfigureNamesInt[] =
NULL
},
&ReservedBackends,
- 3, 0, INT_MAX / 4, NULL, NULL
+ 3, 0, MAX_BACKENDS, NULL, NULL
},
+ /*
+ * We sometimes multiply the number of shared buffers by two without
+ * checking for overflow, so we mustn't allow more than INT_MAX / 2.
+ */
{
{"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM,
gettext_noop("Sets the number of shared memory buffers used by the server."),
@@ -1618,7 +1622,7 @@ static struct config_int ConfigureNamesInt[] =
NULL
},
&max_prepared_xacts,
- 0, 0, INT_MAX / 4, NULL, NULL
+ 0, 0, MAX_BACKENDS, NULL, NULL
},
#ifdef LOCK_DEBUG
@@ -1782,7 +1786,7 @@ static struct config_int ConfigureNamesInt[] =
NULL
},
&max_wal_senders,
- 0, 0, INT_MAX / 4, NULL, NULL
+ 0, 0, MAX_BACKENDS, NULL, NULL
},
{
@@ -2022,7 +2026,7 @@ static struct config_int ConfigureNamesInt[] =
NULL
},
&autovacuum_max_workers,
- 3, 1, INT_MAX / 4, assign_autovacuum_max_workers, NULL
+ 3, 1, MAX_BACKENDS, assign_autovacuum_max_workers, NULL
},
{
@@ -7995,7 +7999,7 @@ show_tcp_keepalives_count(void)
static bool
assign_maxconnections(int newval, bool doit, GucSource source)
{
- if (newval + autovacuum_max_workers + 1 > INT_MAX / 4)
+ if (newval + autovacuum_max_workers + 1 > MAX_BACKENDS)
return false;
if (doit)
@@ -8007,7 +8011,7 @@ assign_maxconnections(int newval, bool doit, GucSource source)
static bool
assign_autovacuum_max_workers(int newval, bool doit, GucSource source)
{
- if (MaxConnections + newval + 1 > INT_MAX / 4)
+ if (MaxConnections + newval + 1 > MAX_BACKENDS)
return false;
if (doit)
diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d
index 2874bf51412..2ea6b7798f2 100644
--- a/src/backend/utils/probes.d
+++ b/src/backend/utils/probes.d
@@ -3,7 +3,7 @@
*
* Copyright (c) 2006-2010, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/probes.d,v 1.12 2010/01/02 16:57:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/probes.d,v 1.13 2010/08/13 20:10:52 rhaas Exp $
* ----------
*/
@@ -55,7 +55,7 @@ provider postgresql {
probe sort__done(bool, long);
probe buffer__read__start(ForkNumber, BlockNumber, Oid, Oid, Oid, bool, bool);
- probe buffer__read__done(ForkNumber, BlockNumber, Oid, Oid, Oid, bool, bool, bool);
+ probe buffer__read__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool);
probe buffer__flush__start(ForkNumber, BlockNumber, Oid, Oid, Oid);
probe buffer__flush__done(ForkNumber, BlockNumber, Oid, Oid, Oid);
@@ -81,10 +81,10 @@ provider postgresql {
probe twophase__checkpoint__start();
probe twophase__checkpoint__done();
- probe smgr__md__read__start(ForkNumber, BlockNumber, Oid, Oid, Oid);
- probe smgr__md__read__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int);
- probe smgr__md__write__start(ForkNumber, BlockNumber, Oid, Oid, Oid);
- probe smgr__md__write__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int);
+ probe smgr__md__read__start(ForkNumber, BlockNumber, Oid, Oid, Oid, int);
+ probe smgr__md__read__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int);
+ probe smgr__md__write__start(ForkNumber, BlockNumber, Oid, Oid, Oid, int);
+ probe smgr__md__write__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int);
probe xlog__insert(unsigned char, unsigned char);
probe xlog__switch();