Commit 448eb083 authored by Tom Lane's avatar Tom Lane

Rearrange order of operations in heap_drop_with_catalog and index_drop

so that we close and flush the doomed relation's relcache entry before
we start to delete the underlying catalog rows, rather than afterwards.
For awhile yesterday I thought that an unexpected relcache entry rebuild
partway through this sequence might explain the infrequent parallel
regression failures we were chasing.  It doesn't, mainly because there's
no CommandCounterIncrement in the sequence and so the deletions aren't
"really" done yet.  But it sure seems like trouble waiting to happen.
parent a0a61f49
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.272 2004/07/11 19:52:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.273 2004/08/28 21:05:26 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -71,7 +71,7 @@ static void AddNewRelationType(const char *typeName, ...@@ -71,7 +71,7 @@ static void AddNewRelationType(const char *typeName,
Oid new_rel_oid, Oid new_rel_oid,
char new_rel_kind, char new_rel_kind,
Oid new_type_oid); Oid new_type_oid);
static void RelationRemoveInheritance(Relation relation); static void RelationRemoveInheritance(Oid relid);
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
static void StoreConstraints(Relation rel, TupleDesc tupdesc); static void StoreConstraints(Relation rel, TupleDesc tupdesc);
static void SetRelationNumChecks(Relation rel, int numchecks); static void SetRelationNumChecks(Relation rel, int numchecks);
...@@ -836,7 +836,7 @@ heap_create_with_catalog(const char *relname, ...@@ -836,7 +836,7 @@ heap_create_with_catalog(const char *relname,
* linking this relation to its parent(s). * linking this relation to its parent(s).
*/ */
static void static void
RelationRemoveInheritance(Relation relation) RelationRemoveInheritance(Oid relid)
{ {
Relation catalogRelation; Relation catalogRelation;
SysScanDesc scan; SysScanDesc scan;
...@@ -848,7 +848,7 @@ RelationRemoveInheritance(Relation relation) ...@@ -848,7 +848,7 @@ RelationRemoveInheritance(Relation relation)
ScanKeyInit(&key, ScanKeyInit(&key,
Anum_pg_inherits_inhrelid, Anum_pg_inherits_inhrelid,
BTEqualStrategyNumber, F_OIDEQ, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(RelationGetRelid(relation))); ObjectIdGetDatum(relid));
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true, scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
SnapshotNow, 1, &key); SnapshotNow, 1, &key);
...@@ -1015,7 +1015,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) ...@@ -1015,7 +1015,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
heap_close(attr_rel, RowExclusiveLock); heap_close(attr_rel, RowExclusiveLock);
if (attnum > 0) if (attnum > 0)
RemoveStatistics(rel, attnum); RemoveStatistics(relid, attnum);
relation_close(rel, NoLock); relation_close(rel, NoLock);
} }
...@@ -1147,33 +1147,24 @@ RemoveAttrDefaultById(Oid attrdefId) ...@@ -1147,33 +1147,24 @@ RemoveAttrDefaultById(Oid attrdefId)
relation_close(myrel, NoLock); relation_close(myrel, NoLock);
} }
/* ---------------------------------------------------------------- /*
* heap_drop_with_catalog - removes specified relation from catalogs * heap_drop_with_catalog - removes specified relation from catalogs
* *
* 1) open relation, acquire exclusive lock.
* 2) flush relation buffers from bufmgr
* 3) remove inheritance information
* 4) remove pg_statistic tuples
* 5) remove pg_attribute tuples
* 6) remove pg_class tuple
* 7) unlink relation file
*
* Note that this routine is not responsible for dropping objects that are * Note that this routine is not responsible for dropping objects that are
* linked to the pg_class entry via dependencies (for example, indexes and * linked to the pg_class entry via dependencies (for example, indexes and
* constraints). Those are deleted by the dependency-tracing logic in * constraints). Those are deleted by the dependency-tracing logic in
* dependency.c before control gets here. In general, therefore, this routine * dependency.c before control gets here. In general, therefore, this routine
* should never be called directly; go through performDeletion() instead. * should never be called directly; go through performDeletion() instead.
* ----------------------------------------------------------------
*/ */
void void
heap_drop_with_catalog(Oid rid) heap_drop_with_catalog(Oid relid)
{ {
Relation rel; Relation rel;
/* /*
* Open and lock the relation. * Open and lock the relation.
*/ */
rel = relation_open(rid, AccessExclusiveLock); rel = relation_open(relid, AccessExclusiveLock);
/* /*
* Release all buffers that belong to this relation, after writing any * Release all buffers that belong to this relation, after writing any
...@@ -1182,53 +1173,57 @@ heap_drop_with_catalog(Oid rid) ...@@ -1182,53 +1173,57 @@ heap_drop_with_catalog(Oid rid)
FlushRelationBuffers(rel, (BlockNumber) 0); FlushRelationBuffers(rel, (BlockNumber) 0);
/* /*
* remove inheritance information * Schedule unlinking of the relation's physical file at commit.
*/ */
RelationRemoveInheritance(rel); if (rel->rd_rel->relkind != RELKIND_VIEW &&
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
{
if (rel->rd_smgr == NULL)
rel->rd_smgr = smgropen(rel->rd_node);
smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
rel->rd_smgr = NULL;
}
/* /*
* delete statistics * Close relcache entry, but *keep* AccessExclusiveLock on the
* relation until transaction commit. This ensures no one else will
* try to do something with the doomed relation.
*/ */
RemoveStatistics(rel, 0); relation_close(rel, NoLock);
/* /*
* delete attribute tuples * Forget any ON COMMIT action for the rel
*/ */
DeleteAttributeTuples(RelationGetRelid(rel)); remove_on_commit_action(relid);
/* /*
* delete relation tuple * Flush the relation from the relcache. We want to do this before
* starting to remove catalog entries, just to be certain that no
* relcache entry rebuild will happen partway through. (That should
* not really matter, since we don't do CommandCounterIncrement here,
* but let's be safe.)
*/ */
DeleteRelationTuple(RelationGetRelid(rel)); RelationForgetRelation(relid);
/* /*
* forget any ON COMMIT action for the rel * remove inheritance information
*/ */
remove_on_commit_action(rid); RelationRemoveInheritance(relid);
/* /*
* unlink the relation's physical file and finish up. * delete statistics
*/ */
if (rel->rd_rel->relkind != RELKIND_VIEW && RemoveStatistics(relid, 0);
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
{
if (rel->rd_smgr == NULL)
rel->rd_smgr = smgropen(rel->rd_node);
smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
rel->rd_smgr = NULL;
}
/* /*
* Close relcache entry, but *keep* AccessExclusiveLock on the * delete attribute tuples
* relation until transaction commit. This ensures no one else will
* try to do something with the doomed relation.
*/ */
relation_close(rel, NoLock); DeleteAttributeTuples(relid);
/* /*
* flush the relation from the relcache * delete relation tuple
*/ */
RelationForgetRelation(rid); DeleteRelationTuple(relid);
} }
...@@ -1884,7 +1879,7 @@ RemoveRelConstraints(Relation rel, const char *constrName, ...@@ -1884,7 +1879,7 @@ RemoveRelConstraints(Relation rel, const char *constrName,
* for that column. * for that column.
*/ */
void void
RemoveStatistics(Relation rel, AttrNumber attnum) RemoveStatistics(Oid relid, AttrNumber attnum)
{ {
Relation pgstatistic; Relation pgstatistic;
SysScanDesc scan; SysScanDesc scan;
...@@ -1897,7 +1892,7 @@ RemoveStatistics(Relation rel, AttrNumber attnum) ...@@ -1897,7 +1892,7 @@ RemoveStatistics(Relation rel, AttrNumber attnum)
ScanKeyInit(&key[0], ScanKeyInit(&key[0],
Anum_pg_statistic_starelid, Anum_pg_statistic_starelid,
BTEqualStrategyNumber, F_OIDEQ, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(RelationGetRelid(rel))); ObjectIdGetDatum(relid));
if (attnum == 0) if (attnum == 0)
nkeys = 1; nkeys = 1;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.235 2004/08/01 17:32:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.236 2004/08/28 21:05:26 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -769,8 +769,6 @@ index_drop(Oid indexId) ...@@ -769,8 +769,6 @@ index_drop(Oid indexId)
HeapTuple tuple; HeapTuple tuple;
bool hasexprs; bool hasexprs;
Assert(OidIsValid(indexId));
/* /*
* To drop an index safely, we must grab exclusive lock on its parent * To drop an index safely, we must grab exclusive lock on its parent
* table; otherwise there could be other backends using the index! * table; otherwise there could be other backends using the index!
...@@ -790,14 +788,24 @@ index_drop(Oid indexId) ...@@ -790,14 +788,24 @@ index_drop(Oid indexId)
LockRelation(userIndexRelation, AccessExclusiveLock); LockRelation(userIndexRelation, AccessExclusiveLock);
/* /*
* fix RELATION relation * flush buffer cache and schedule physical removal of the file
*/ */
DeleteRelationTuple(indexId); FlushRelationBuffers(userIndexRelation, (BlockNumber) 0);
if (userIndexRelation->rd_smgr == NULL)
userIndexRelation->rd_smgr = smgropen(userIndexRelation->rd_node);
smgrscheduleunlink(userIndexRelation->rd_smgr,
userIndexRelation->rd_istemp);
userIndexRelation->rd_smgr = NULL;
/* /*
* fix ATTRIBUTE relation * Close and flush the index's relcache entry, to ensure relcache
* doesn't try to rebuild it while we're deleting catalog entries.
* We keep the lock though.
*/ */
DeleteAttributeTuples(indexId); index_close(userIndexRelation);
RelationForgetRelation(indexId);
/* /*
* fix INDEX relation, and check for expressional index * fix INDEX relation, and check for expressional index
...@@ -822,18 +830,17 @@ index_drop(Oid indexId) ...@@ -822,18 +830,17 @@ index_drop(Oid indexId)
* statistics about them. * statistics about them.
*/ */
if (hasexprs) if (hasexprs)
RemoveStatistics(userIndexRelation, 0); RemoveStatistics(indexId, 0);
/* /*
* flush buffer cache and physically remove the file * fix ATTRIBUTE relation
*/ */
FlushRelationBuffers(userIndexRelation, (BlockNumber) 0); DeleteAttributeTuples(indexId);
if (userIndexRelation->rd_smgr == NULL) /*
userIndexRelation->rd_smgr = smgropen(userIndexRelation->rd_node); * fix RELATION relation
smgrscheduleunlink(userIndexRelation->rd_smgr, */
userIndexRelation->rd_istemp); DeleteRelationTuple(indexId);
userIndexRelation->rd_smgr = NULL;
/* /*
* We are presently too lazy to attempt to compute the new correct * We are presently too lazy to attempt to compute the new correct
...@@ -846,12 +853,9 @@ index_drop(Oid indexId) ...@@ -846,12 +853,9 @@ index_drop(Oid indexId)
CacheInvalidateRelcache(userHeapRelation); CacheInvalidateRelcache(userHeapRelation);
/* /*
* Close rels, but keep locks * Close owning rel, but keep lock
*/ */
index_close(userIndexRelation);
heap_close(userHeapRelation, NoLock); heap_close(userHeapRelation, NoLock);
RelationForgetRelation(indexId);
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.126 2004/08/15 23:44:46 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.127 2004/08/28 21:05:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -4924,7 +4924,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -4924,7 +4924,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype); add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
/* Drop any pg_statistic entry for the column, since it's now wrong type */ /* Drop any pg_statistic entry for the column, since it's now wrong type */
RemoveStatistics(rel, attnum); RemoveStatistics(RelationGetRelid(rel), attnum);
/* /*
* Update the default, if present, by brute force --- remove and re-add * Update the default, if present, by brute force --- remove and re-add
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.68 2004/07/11 19:52:51 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.69 2004/08/28 21:05:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -54,7 +54,7 @@ extern Oid heap_create_with_catalog(const char *relname, ...@@ -54,7 +54,7 @@ extern Oid heap_create_with_catalog(const char *relname,
OnCommitAction oncommit, OnCommitAction oncommit,
bool allow_system_table_mods); bool allow_system_table_mods);
extern void heap_drop_with_catalog(Oid rid); extern void heap_drop_with_catalog(Oid relid);
extern void heap_truncate(Oid rid); extern void heap_truncate(Oid rid);
...@@ -81,7 +81,7 @@ extern void RemoveAttributeById(Oid relid, AttrNumber attnum); ...@@ -81,7 +81,7 @@ extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
DropBehavior behavior, bool complain); DropBehavior behavior, bool complain);
extern void RemoveAttrDefaultById(Oid attrdefId); extern void RemoveAttrDefaultById(Oid attrdefId);
extern void RemoveStatistics(Relation rel, AttrNumber attnum); extern void RemoveStatistics(Oid relid, AttrNumber attnum);
extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
bool relhasoids); bool relhasoids);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment