summaryrefslogtreecommitdiff
path: root/src/backend/catalog
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-02-03 01:14:17 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-02-03 01:14:17 +0000
commit70a2b05a59c02464e36d8c9bf23d2eef8502eccd (patch)
tree367ea4f6b3285ec31e88868276f27524fc495674 /src/backend/catalog
parentab7c49c98811f539db9294c8f2d1a15380e025f6 (diff)
downloadpostgresql-70a2b05a59c02464e36d8c9bf23d2eef8502eccd.tar.gz
Assorted cleanups in preparation for using a map file to support altering
the relfilenode of currently-not-relocatable system catalogs. 1. Get rid of inval.c's dependency on relfilenode, by not having it emit smgr invalidations as a result of relcache flushes. Instead, smgr sinval messages are sent directly from smgr.c when an actual relation delete or truncate is done. This makes considerably more structural sense and allows elimination of a large number of useless smgr inval messages that were formerly sent even in cases where nothing was changing at the physical-relation level. Note that this reintroduces the concept of nontransactional inval messages, but that's okay --- because the messages are sent by smgr.c, they will be sent in Hot Standby slaves, just from a lower logical level than before. 2. Move setNewRelfilenode out of catalog/index.c, where it never logically belonged, into relcache.c; which is a somewhat debatable choice as well but better than before. (I considered catalog/storage.c, but that seemed too low level.) Rename to RelationSetNewRelfilenode. 3. Cosmetic cleanups of some other relfilenode manipulations.
Diffstat (limited to 'src/backend/catalog')
-rw-r--r--src/backend/catalog/heap.c55
-rw-r--r--src/backend/catalog/index.c125
-rw-r--r--src/backend/catalog/toasting.c10
3 files changed, 59 insertions, 131 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index f86747e149..c344b8e01c 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.368 2010/01/28 23:21:11 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.369 2010/02/03 01:14:16 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -70,6 +70,10 @@
#include "utils/tqual.h"
+/* Kluge for upgrade-in-place support */
+Oid binary_upgrade_next_heap_relfilenode = InvalidOid;
+Oid binary_upgrade_next_toast_relfilenode = InvalidOid;
+
static void AddNewRelationTuple(Relation pg_class_desc,
Relation new_rel_desc,
Oid new_rel_oid,
@@ -98,9 +102,6 @@ static Node *cookConstraint(ParseState *pstate,
char *relname);
static List *insert_ordered_unique_oid(List *list, Oid datum);
-Oid binary_upgrade_next_heap_relfilenode = InvalidOid;
-Oid binary_upgrade_next_toast_relfilenode = InvalidOid;
-
/* ----------------------------------------------------------------
* XXX UGLY HARD CODED BADNESS FOLLOWS XXX
@@ -955,29 +956,31 @@ heap_create_with_catalog(const char *relname,
errmsg("only shared relations can be placed in pg_global tablespace")));
}
- if ((relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
- relkind == RELKIND_VIEW || relkind == RELKIND_COMPOSITE_TYPE) &&
- OidIsValid(binary_upgrade_next_heap_relfilenode))
- {
- relid = binary_upgrade_next_heap_relfilenode;
- binary_upgrade_next_heap_relfilenode = InvalidOid;
- }
- else if (relkind == RELKIND_TOASTVALUE &&
- OidIsValid(binary_upgrade_next_toast_relfilenode))
- {
- relid = binary_upgrade_next_toast_relfilenode;
- binary_upgrade_next_toast_relfilenode = InvalidOid;
- }
- else if (!OidIsValid(relid))
+ /*
+ * Allocate an OID for the relation, unless we were told what to use.
+ *
+ * The OID will be the relfilenode as well, so make sure it doesn't
+ * collide with either pg_class OIDs or existing physical files.
+ */
+ if (!OidIsValid(relid))
{
- /*
- * Allocate an OID for the relation, unless we were told what to use.
- *
- * The OID will be the relfilenode as well, so make sure it doesn't
- * collide with either pg_class OIDs or existing physical files.
- */
- relid = GetNewRelFileNode(reltablespace, shared_relation,
- pg_class_desc);
+ /* Use binary-upgrade overrides if applicable */
+ if (OidIsValid(binary_upgrade_next_heap_relfilenode) &&
+ (relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
+ relkind == RELKIND_VIEW || relkind == RELKIND_COMPOSITE_TYPE))
+ {
+ relid = binary_upgrade_next_heap_relfilenode;
+ binary_upgrade_next_heap_relfilenode = InvalidOid;
+ }
+ else if (OidIsValid(binary_upgrade_next_toast_relfilenode) &&
+ relkind == RELKIND_TOASTVALUE)
+ {
+ relid = binary_upgrade_next_toast_relfilenode;
+ binary_upgrade_next_toast_relfilenode = InvalidOid;
+ }
+ else
+ relid = GetNewRelFileNode(reltablespace, shared_relation,
+ pg_class_desc);
}
/*
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index ed70f97329..c6b6e76933 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.331 2010/01/22 16:40:18 rhaas Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.332 2010/02/03 01:14:16 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -69,6 +69,9 @@
#include "utils/tqual.h"
+/* Kluge for upgrade-in-place support */
+Oid binary_upgrade_next_index_relfilenode = InvalidOid;
+
/* state info for validate_index bulkdelete callback */
typedef struct
{
@@ -79,9 +82,6 @@ typedef struct
tups_inserted;
} v_i_state;
-/* For simple relation creation, this is the toast index relfilenode */
-Oid binary_upgrade_next_index_relfilenode = InvalidOid;
-
/* non-export function prototypes */
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
IndexInfo *indexInfo,
@@ -642,21 +642,23 @@ index_create(Oid heapRelationId,
accessMethodObjectId,
classObjectId);
- if (OidIsValid(binary_upgrade_next_index_relfilenode))
- {
- indexRelationId = binary_upgrade_next_index_relfilenode;
- binary_upgrade_next_index_relfilenode = InvalidOid;
- }
- else if (!OidIsValid(indexRelationId))
+ /*
+ * Allocate an OID for the index, unless we were told what to use.
+ *
+ * The OID will be the relfilenode as well, so make sure it doesn't
+ * collide with either pg_class OIDs or existing physical files.
+ */
+ if (!OidIsValid(indexRelationId))
{
- /*
- * Allocate an OID for the index, unless we were told what to use.
- *
- * The OID will be the relfilenode as well, so make sure it doesn't
- * collide with either pg_class OIDs or existing physical files.
- */
- indexRelationId = GetNewRelFileNode(tableSpaceId, shared_relation,
- pg_class);
+ /* Use binary-upgrade override if applicable */
+ if (OidIsValid(binary_upgrade_next_index_relfilenode))
+ {
+ indexRelationId = binary_upgrade_next_index_relfilenode;
+ binary_upgrade_next_index_relfilenode = InvalidOid;
+ }
+ else
+ indexRelationId = GetNewRelFileNode(tableSpaceId, shared_relation,
+ pg_class);
}
/*
@@ -1391,87 +1393,6 @@ index_update_stats(Relation rel,
heap_close(pg_class, RowExclusiveLock);
}
-/*
- * setNewRelfilenode - assign a new relfilenode value to the relation
- *
- * Caller must already hold exclusive lock on the relation.
- *
- * The relation is marked with relfrozenxid=freezeXid (InvalidTransactionId
- * must be passed for indexes)
- */
-void
-setNewRelfilenode(Relation relation, TransactionId freezeXid)
-{
- Oid newrelfilenode;
- RelFileNode newrnode;
- Relation pg_class;
- HeapTuple tuple;
- Form_pg_class rd_rel;
-
- /* Can't change relfilenode for nailed tables (indexes ok though) */
- Assert(!relation->rd_isnailed ||
- relation->rd_rel->relkind == RELKIND_INDEX);
- /* Can't change for shared tables or indexes */
- Assert(!relation->rd_rel->relisshared);
- /* Indexes must have Invalid frozenxid; other relations must not */
- Assert((relation->rd_rel->relkind == RELKIND_INDEX &&
- freezeXid == InvalidTransactionId) ||
- TransactionIdIsNormal(freezeXid));
-
- /* Allocate a new relfilenode */
- newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace,
- relation->rd_rel->relisshared,
- NULL);
-
- /*
- * Find the pg_class tuple for the given relation. This is not used
- * during bootstrap, so okay to use heap_update always.
- */
- pg_class = heap_open(RelationRelationId, RowExclusiveLock);
-
- tuple = SearchSysCacheCopy(RELOID,
- ObjectIdGetDatum(RelationGetRelid(relation)),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "could not find tuple for relation %u",
- RelationGetRelid(relation));
- rd_rel = (Form_pg_class) GETSTRUCT(tuple);
-
- /*
- * ... and create storage for corresponding forks in the new relfilenode.
- *
- * NOTE: any conflict in relfilenode value will be caught here
- */
- newrnode = relation->rd_node;
- newrnode.relNode = newrelfilenode;
-
- /*
- * Create the main fork, like heap_create() does, and drop the old
- * storage.
- */
- RelationCreateStorage(newrnode, relation->rd_istemp);
- smgrclosenode(newrnode);
- RelationDropStorage(relation);
-
- /* update the pg_class row */
- rd_rel->relfilenode = newrelfilenode;
- rd_rel->relpages = 0; /* it's empty until further notice */
- rd_rel->reltuples = 0;
- rd_rel->relfrozenxid = freezeXid;
- simple_heap_update(pg_class, &tuple->t_self, tuple);
- CatalogUpdateIndexes(pg_class, tuple);
-
- heap_freetuple(tuple);
-
- heap_close(pg_class, RowExclusiveLock);
-
- /* Make sure the relfilenode change is visible */
- CommandCounterIncrement();
-
- /* Mark the rel as having a new relfilenode in current transaction */
- RelationCacheMarkNewRelfilenode(relation);
-}
-
/*
* index_build - invoke access-method-specific index build procedure
@@ -2562,7 +2483,7 @@ reindex_index(Oid indexId)
/*
* We'll build a new physical relation for the index.
*/
- setNewRelfilenode(iRel, InvalidTransactionId);
+ RelationSetNewRelfilenode(iRel, InvalidTransactionId);
}
/* Initialize the index and rebuild */
@@ -2660,8 +2581,8 @@ reindex_relation(Oid relid, bool toast_too)
* yet because all of this is transaction-safe. If we fail partway
* through, the updated rows are dead and it doesn't matter whether they
* have index entries. Also, a new pg_class index will be created with an
- * entry for its own pg_class row because we do setNewRelfilenode() before
- * we do index_build().
+ * entry for its own pg_class row because we do RelationSetNewRelfilenode()
+ * before we do index_build().
*
* Note that we also clear pg_class's rd_oidindex until the loop is done,
* so that that index can't be accessed either. This means we cannot
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 58890aa6a0..ca70f19bf3 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.28 2010/01/28 23:21:11 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.29 2010/02/03 01:14:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,9 +31,11 @@
#include "utils/builtins.h"
#include "utils/syscache.h"
-Oid binary_upgrade_next_pg_type_toast_oid = InvalidOid;
+/* Kluges for upgrade-in-place support */
extern Oid binary_upgrade_next_toast_relfilenode;
+Oid binary_upgrade_next_pg_type_toast_oid = InvalidOid;
+
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
Datum reloptions);
static bool needs_toast_table(Relation rel);
@@ -145,7 +147,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
/*
* Check to see whether the table actually needs a TOAST table.
- * If the relfilenode is specified, force toast file creation.
+ *
+ * If an update-in-place relfilenode is specified, force toast file
+ * creation even if it seems not to need one.
*/
if (!needs_toast_table(rel) &&
!OidIsValid(binary_upgrade_next_toast_relfilenode))