Skip to content

Commit 448eb08

Browse files
committed
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.
1 parent a0a61f4 commit 448eb08

File tree

4 files changed

+68
-69
lines changed

4 files changed

+68
-69
lines changed

src/backend/catalog/heap.c

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.272 2004/07/11 19:52:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.273 2004/08/28 21:05:26 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -71,7 +71,7 @@ static void AddNewRelationType(const char *typeName,
7171
Oid new_rel_oid,
7272
char new_rel_kind,
7373
Oid new_type_oid);
74-
static void RelationRemoveInheritance(Relation relation);
74+
static void RelationRemoveInheritance(Oid relid);
7575
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
7676
static void StoreConstraints(Relation rel, TupleDesc tupdesc);
7777
static void SetRelationNumChecks(Relation rel, int numchecks);
@@ -836,7 +836,7 @@ heap_create_with_catalog(const char *relname,
836836
* linking this relation to its parent(s).
837837
*/
838838
static void
839-
RelationRemoveInheritance(Relation relation)
839+
RelationRemoveInheritance(Oid relid)
840840
{
841841
Relation catalogRelation;
842842
SysScanDesc scan;
@@ -848,7 +848,7 @@ RelationRemoveInheritance(Relation relation)
848848
ScanKeyInit(&key,
849849
Anum_pg_inherits_inhrelid,
850850
BTEqualStrategyNumber, F_OIDEQ,
851-
ObjectIdGetDatum(RelationGetRelid(relation)));
851+
ObjectIdGetDatum(relid));
852852

853853
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
854854
SnapshotNow, 1, &key);
@@ -1015,7 +1015,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
10151015
heap_close(attr_rel, RowExclusiveLock);
10161016

10171017
if (attnum > 0)
1018-
RemoveStatistics(rel, attnum);
1018+
RemoveStatistics(relid, attnum);
10191019

10201020
relation_close(rel, NoLock);
10211021
}
@@ -1147,33 +1147,24 @@ RemoveAttrDefaultById(Oid attrdefId)
11471147
relation_close(myrel, NoLock);
11481148
}
11491149

1150-
/* ----------------------------------------------------------------
1151-
* heap_drop_with_catalog - removes specified relation from catalogs
1152-
*
1153-
* 1) open relation, acquire exclusive lock.
1154-
* 2) flush relation buffers from bufmgr
1155-
* 3) remove inheritance information
1156-
* 4) remove pg_statistic tuples
1157-
* 5) remove pg_attribute tuples
1158-
* 6) remove pg_class tuple
1159-
* 7) unlink relation file
1150+
/*
1151+
* heap_drop_with_catalog - removes specified relation from catalogs
11601152
*
11611153
* Note that this routine is not responsible for dropping objects that are
11621154
* linked to the pg_class entry via dependencies (for example, indexes and
11631155
* constraints). Those are deleted by the dependency-tracing logic in
11641156
* dependency.c before control gets here. In general, therefore, this routine
11651157
* should never be called directly; go through performDeletion() instead.
1166-
* ----------------------------------------------------------------
11671158
*/
11681159
void
1169-
heap_drop_with_catalog(Oid rid)
1160+
heap_drop_with_catalog(Oid relid)
11701161
{
11711162
Relation rel;
11721163

11731164
/*
11741165
* Open and lock the relation.
11751166
*/
1176-
rel = relation_open(rid, AccessExclusiveLock);
1167+
rel = relation_open(relid, AccessExclusiveLock);
11771168

11781169
/*
11791170
* Release all buffers that belong to this relation, after writing any
@@ -1182,53 +1173,57 @@ heap_drop_with_catalog(Oid rid)
11821173
FlushRelationBuffers(rel, (BlockNumber) 0);
11831174

11841175
/*
1185-
* remove inheritance information
1176+
* Schedule unlinking of the relation's physical file at commit.
11861177
*/
1187-
RelationRemoveInheritance(rel);
1178+
if (rel->rd_rel->relkind != RELKIND_VIEW &&
1179+
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
1180+
{
1181+
if (rel->rd_smgr == NULL)
1182+
rel->rd_smgr = smgropen(rel->rd_node);
1183+
smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
1184+
rel->rd_smgr = NULL;
1185+
}
11881186

11891187
/*
1190-
* delete statistics
1188+
* Close relcache entry, but *keep* AccessExclusiveLock on the
1189+
* relation until transaction commit. This ensures no one else will
1190+
* try to do something with the doomed relation.
11911191
*/
1192-
RemoveStatistics(rel, 0);
1192+
relation_close(rel, NoLock);
11931193

11941194
/*
1195-
* delete attribute tuples
1195+
* Forget any ON COMMIT action for the rel
11961196
*/
1197-
DeleteAttributeTuples(RelationGetRelid(rel));
1197+
remove_on_commit_action(relid);
11981198

11991199
/*
1200-
* delete relation tuple
1200+
* Flush the relation from the relcache. We want to do this before
1201+
* starting to remove catalog entries, just to be certain that no
1202+
* relcache entry rebuild will happen partway through. (That should
1203+
* not really matter, since we don't do CommandCounterIncrement here,
1204+
* but let's be safe.)
12011205
*/
1202-
DeleteRelationTuple(RelationGetRelid(rel));
1206+
RelationForgetRelation(relid);
12031207

12041208
/*
1205-
* forget any ON COMMIT action for the rel
1209+
* remove inheritance information
12061210
*/
1207-
remove_on_commit_action(rid);
1211+
RelationRemoveInheritance(relid);
12081212

12091213
/*
1210-
* unlink the relation's physical file and finish up.
1214+
* delete statistics
12111215
*/
1212-
if (rel->rd_rel->relkind != RELKIND_VIEW &&
1213-
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
1214-
{
1215-
if (rel->rd_smgr == NULL)
1216-
rel->rd_smgr = smgropen(rel->rd_node);
1217-
smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
1218-
rel->rd_smgr = NULL;
1219-
}
1216+
RemoveStatistics(relid, 0);
12201217

12211218
/*
1222-
* Close relcache entry, but *keep* AccessExclusiveLock on the
1223-
* relation until transaction commit. This ensures no one else will
1224-
* try to do something with the doomed relation.
1219+
* delete attribute tuples
12251220
*/
1226-
relation_close(rel, NoLock);
1221+
DeleteAttributeTuples(relid);
12271222

12281223
/*
1229-
* flush the relation from the relcache
1224+
* delete relation tuple
12301225
*/
1231-
RelationForgetRelation(rid);
1226+
DeleteRelationTuple(relid);
12321227
}
12331228

12341229

@@ -1884,7 +1879,7 @@ RemoveRelConstraints(Relation rel, const char *constrName,
18841879
* for that column.
18851880
*/
18861881
void
1887-
RemoveStatistics(Relation rel, AttrNumber attnum)
1882+
RemoveStatistics(Oid relid, AttrNumber attnum)
18881883
{
18891884
Relation pgstatistic;
18901885
SysScanDesc scan;
@@ -1897,7 +1892,7 @@ RemoveStatistics(Relation rel, AttrNumber attnum)
18971892
ScanKeyInit(&key[0],
18981893
Anum_pg_statistic_starelid,
18991894
BTEqualStrategyNumber, F_OIDEQ,
1900-
ObjectIdGetDatum(RelationGetRelid(rel)));
1895+
ObjectIdGetDatum(relid));
19011896

19021897
if (attnum == 0)
19031898
nkeys = 1;

src/backend/catalog/index.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.235 2004/08/01 17:32:14 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.236 2004/08/28 21:05:26 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -769,8 +769,6 @@ index_drop(Oid indexId)
769769
HeapTuple tuple;
770770
bool hasexprs;
771771

772-
Assert(OidIsValid(indexId));
773-
774772
/*
775773
* To drop an index safely, we must grab exclusive lock on its parent
776774
* table; otherwise there could be other backends using the index!
@@ -790,14 +788,24 @@ index_drop(Oid indexId)
790788
LockRelation(userIndexRelation, AccessExclusiveLock);
791789

792790
/*
793-
* fix RELATION relation
791+
* flush buffer cache and schedule physical removal of the file
794792
*/
795-
DeleteRelationTuple(indexId);
793+
FlushRelationBuffers(userIndexRelation, (BlockNumber) 0);
794+
795+
if (userIndexRelation->rd_smgr == NULL)
796+
userIndexRelation->rd_smgr = smgropen(userIndexRelation->rd_node);
797+
smgrscheduleunlink(userIndexRelation->rd_smgr,
798+
userIndexRelation->rd_istemp);
799+
userIndexRelation->rd_smgr = NULL;
796800

797801
/*
798-
* fix ATTRIBUTE relation
802+
* Close and flush the index's relcache entry, to ensure relcache
803+
* doesn't try to rebuild it while we're deleting catalog entries.
804+
* We keep the lock though.
799805
*/
800-
DeleteAttributeTuples(indexId);
806+
index_close(userIndexRelation);
807+
808+
RelationForgetRelation(indexId);
801809

802810
/*
803811
* fix INDEX relation, and check for expressional index
@@ -822,18 +830,17 @@ index_drop(Oid indexId)
822830
* statistics about them.
823831
*/
824832
if (hasexprs)
825-
RemoveStatistics(userIndexRelation, 0);
833+
RemoveStatistics(indexId, 0);
826834

827835
/*
828-
* flush buffer cache and physically remove the file
836+
* fix ATTRIBUTE relation
829837
*/
830-
FlushRelationBuffers(userIndexRelation, (BlockNumber) 0);
838+
DeleteAttributeTuples(indexId);
831839

832-
if (userIndexRelation->rd_smgr == NULL)
833-
userIndexRelation->rd_smgr = smgropen(userIndexRelation->rd_node);
834-
smgrscheduleunlink(userIndexRelation->rd_smgr,
835-
userIndexRelation->rd_istemp);
836-
userIndexRelation->rd_smgr = NULL;
840+
/*
841+
* fix RELATION relation
842+
*/
843+
DeleteRelationTuple(indexId);
837844

838845
/*
839846
* We are presently too lazy to attempt to compute the new correct
@@ -846,12 +853,9 @@ index_drop(Oid indexId)
846853
CacheInvalidateRelcache(userHeapRelation);
847854

848855
/*
849-
* Close rels, but keep locks
856+
* Close owning rel, but keep lock
850857
*/
851-
index_close(userIndexRelation);
852858
heap_close(userHeapRelation, NoLock);
853-
854-
RelationForgetRelation(indexId);
855859
}
856860

857861
/* ----------------------------------------------------------------

src/backend/commands/tablecmds.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.126 2004/08/15 23:44:46 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.127 2004/08/28 21:05:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -4924,7 +4924,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
49244924
add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
49254925

49264926
/* Drop any pg_statistic entry for the column, since it's now wrong type */
4927-
RemoveStatistics(rel, attnum);
4927+
RemoveStatistics(RelationGetRelid(rel), attnum);
49284928

49294929
/*
49304930
* Update the default, if present, by brute force --- remove and re-add

src/include/catalog/heap.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.68 2004/07/11 19:52:51 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.69 2004/08/28 21:05:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -54,7 +54,7 @@ extern Oid heap_create_with_catalog(const char *relname,
5454
OnCommitAction oncommit,
5555
bool allow_system_table_mods);
5656

57-
extern void heap_drop_with_catalog(Oid rid);
57+
extern void heap_drop_with_catalog(Oid relid);
5858

5959
extern void heap_truncate(Oid rid);
6060

@@ -81,7 +81,7 @@ extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
8181
extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
8282
DropBehavior behavior, bool complain);
8383
extern void RemoveAttrDefaultById(Oid attrdefId);
84-
extern void RemoveStatistics(Relation rel, AttrNumber attnum);
84+
extern void RemoveStatistics(Oid relid, AttrNumber attnum);
8585

8686
extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
8787
bool relhasoids);

0 commit comments

Comments
 (0)