Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3acf422

Browse files
committed
Revise mechanism for getting rid of temp tables at backend shutdown.
Instead of grovelling through pg_class to find them, make use of thehandy dandy dependency mechanism: just delete everything that dependson our temp schema. Unlike the pg_class scan, the dependency mechanismis smart enough to delete things in an order that doesn't fall foul ofany dependency restrictions. Fixes problem reported by David Heggie:a temp table with a serial column may cause a backend FATAL exit atshutdown time, if it chances to try to delete the temp sequence first.
1 parent00f1a41 commit3acf422

File tree

3 files changed

+157
-88
lines changed

3 files changed

+157
-88
lines changed

‎src/backend/catalog/dependency.c

Lines changed: 144 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.19 2003/01/10 21:08:07 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.20 2003/02/07 01:33:06 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -100,6 +100,11 @@ static bool recursiveDeletion(const ObjectAddress *object,
100100
constObjectAddress*callingObject,
101101
ObjectAddresses*oktodelete,
102102
RelationdepRel);
103+
staticbooldeleteDependentObjects(constObjectAddress*object,
104+
constchar*objDescription,
105+
DropBehaviorbehavior,
106+
ObjectAddresses*oktodelete,
107+
RelationdepRel);
103108
staticvoiddoDeletion(constObjectAddress*object);
104109
staticboolfind_expr_references_walker(Node*node,
105110
find_expr_references_context*context);
@@ -172,6 +177,64 @@ performDeletion(const ObjectAddress *object,
172177
}
173178

174179

180+
/*
181+
* deleteWhatDependsOn: attempt to drop everything that depends on the
182+
* specified object, though not the object itself. Behavior is always
183+
* CASCADE.
184+
*
185+
* This is currently used only to clean out the contents of a schema
186+
* (namespace): the passed object is a namespace.
187+
*/
188+
void
189+
deleteWhatDependsOn(constObjectAddress*object)
190+
{
191+
char*objDescription;
192+
RelationdepRel;
193+
ObjectAddressesoktodelete;
194+
195+
/*
196+
* Get object description for possible use in failure messages
197+
*/
198+
objDescription=getObjectDescription(object);
199+
200+
/*
201+
* We save some cycles by opening pg_depend just once and passing the
202+
* Relation pointer down to all the recursive deletion steps.
203+
*/
204+
depRel=heap_openr(DependRelationName,RowExclusiveLock);
205+
206+
/*
207+
* Construct a list of objects that are reachable by AUTO or INTERNAL
208+
* dependencies from the target object. These should be deleted silently,
209+
* even if the actual deletion pass first reaches one of them via a
210+
* non-auto dependency.
211+
*/
212+
init_object_addresses(&oktodelete);
213+
214+
findAutoDeletableObjects(object,&oktodelete,depRel);
215+
216+
/*
217+
* Now invoke only step 2 of recursiveDeletion: just recurse to the
218+
* stuff dependent on the given object.
219+
*/
220+
if (!deleteDependentObjects(object,objDescription,
221+
DROP_CASCADE,&oktodelete,depRel))
222+
elog(ERROR,"Failed to drop all objects depending on %s",
223+
objDescription);
224+
225+
/*
226+
* We do not need CommandCounterIncrement here, since if step 2 did
227+
* anything then each recursive call will have ended with one.
228+
*/
229+
230+
term_object_addresses(&oktodelete);
231+
232+
heap_close(depRel,RowExclusiveLock);
233+
234+
pfree(objDescription);
235+
}
236+
237+
175238
/*
176239
* findAutoDeletableObjects: find all objects that are reachable by AUTO or
177240
* INTERNAL dependency paths from the given object. Add them all to the
@@ -476,22 +539,90 @@ recursiveDeletion(const ObjectAddress *object,
476539

477540
/*
478541
* Step 2: scan pg_depend records that link to this object, showing
479-
* the things that depend on it. Recursively delete those things. (We
480-
* don't delete the pg_depend records here, as the recursive call will
481-
* do that.) Note it's important to delete the dependent objects
542+
* the things that depend on it. Recursively delete those things.
543+
* Note it's important to delete the dependent objects
482544
* before the referenced one, since the deletion routines might do
483545
* things like try to update the pg_class record when deleting a check
484546
* constraint.
485-
*
486-
* Again, when dropping a whole object (subId = 0), find pg_depend
487-
* records for its sub-objects too.
488-
*
489-
* NOTE: because we are using SnapshotNow, if a recursive call deletes
490-
* any pg_depend tuples that our scan hasn't yet visited, we will not
491-
* see them as good when we do visit them.This is essential for
492-
* correct behavior if there are multiple dependency paths between two
493-
* objects --- else we might try to delete an already-deleted object.
494547
*/
548+
if (!deleteDependentObjects(object,objDescription,
549+
behavior,oktodelete,depRel))
550+
ok= false;
551+
552+
/*
553+
* We do not need CommandCounterIncrement here, since if step 2 did
554+
* anything then each recursive call will have ended with one.
555+
*/
556+
557+
/*
558+
* Step 3: delete the object itself.
559+
*/
560+
doDeletion(object);
561+
562+
/*
563+
* Delete any comments associated with this object. (This is a
564+
* convenient place to do it instead of having every object type know
565+
* to do it.)
566+
*/
567+
DeleteComments(object->objectId,object->classId,object->objectSubId);
568+
569+
/*
570+
* CommandCounterIncrement here to ensure that preceding changes are
571+
* all visible.
572+
*/
573+
CommandCounterIncrement();
574+
575+
/*
576+
* And we're done!
577+
*/
578+
pfree(objDescription);
579+
580+
returnok;
581+
}
582+
583+
584+
/*
585+
* deleteDependentObjects - find and delete objects that depend on 'object'
586+
*
587+
* Scan pg_depend records that link to the given object, showing
588+
* the things that depend on it. Recursively delete those things. (We
589+
* don't delete the pg_depend records here, as the recursive call will
590+
* do that.) Note it's important to delete the dependent objects
591+
* before the referenced one, since the deletion routines might do
592+
* things like try to update the pg_class record when deleting a check
593+
* constraint.
594+
*
595+
* When dropping a whole object (subId = 0), find pg_depend records for
596+
* its sub-objects too.
597+
*
598+
*object: the object to find dependencies on
599+
*objDescription: description of object (only used for error messages)
600+
*behavior: desired drop behavior
601+
*oktodelete: stuff that's AUTO-deletable
602+
*depRel: already opened pg_depend relation
603+
*
604+
* Returns TRUE if all is well, false if any problem found.
605+
*
606+
* NOTE: because we are using SnapshotNow, if a recursive call deletes
607+
* any pg_depend tuples that our scan hasn't yet visited, we will not
608+
* see them as good when we do visit them.This is essential for
609+
* correct behavior if there are multiple dependency paths between two
610+
* objects --- else we might try to delete an already-deleted object.
611+
*/
612+
staticbool
613+
deleteDependentObjects(constObjectAddress*object,
614+
constchar*objDescription,
615+
DropBehaviorbehavior,
616+
ObjectAddresses*oktodelete,
617+
RelationdepRel)
618+
{
619+
boolok= true;
620+
ScanKeyDatakey[3];
621+
intnkeys;
622+
SysScanDescscan;
623+
HeapTupletup;
624+
ObjectAddressotherObject;
625+
495626
ScanKeyEntryInitialize(&key[0],0x0,
496627
Anum_pg_depend_refclassid,F_OIDEQ,
497628
ObjectIdGetDatum(object->classId));
@@ -581,34 +712,6 @@ recursiveDeletion(const ObjectAddress *object,
581712

582713
systable_endscan(scan);
583714

584-
/*
585-
* We do not need CommandCounterIncrement here, since if step 2 did
586-
* anything then each recursive call will have ended with one.
587-
*/
588-
589-
/*
590-
* Step 3: delete the object itself.
591-
*/
592-
doDeletion(object);
593-
594-
/*
595-
* Delete any comments associated with this object. (This is a
596-
* convenient place to do it instead of having every object type know
597-
* to do it.)
598-
*/
599-
DeleteComments(object->objectId,object->classId,object->objectSubId);
600-
601-
/*
602-
* CommandCounterIncrement here to ensure that preceding changes are
603-
* all visible.
604-
*/
605-
CommandCounterIncrement();
606-
607-
/*
608-
* And we're done!
609-
*/
610-
pfree(objDescription);
611-
612715
returnok;
613716
}
614717

‎src/backend/catalog/namespace.c

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,17 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.45 2003/01/12 18:19:37 petere Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.46 2003/02/07 01:33:06 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
2020
#include"postgres.h"
2121

22-
#include"access/heapam.h"
2322
#include"access/xact.h"
24-
#include"catalog/catalog.h"
2523
#include"catalog/catname.h"
2624
#include"catalog/dependency.h"
27-
#include"catalog/heap.h"
2825
#include"catalog/namespace.h"
2926
#include"catalog/pg_conversion.h"
30-
#include"catalog/pg_inherits.h"
3127
#include"catalog/pg_namespace.h"
3228
#include"catalog/pg_opclass.h"
3329
#include"catalog/pg_operator.h"
@@ -42,10 +38,9 @@
4238
#include"utils/acl.h"
4339
#include"utils/builtins.h"
4440
#include"utils/catcache.h"
45-
#include"utils/fmgroids.h"
46-
#include"utils/guc.h"
4741
#include"utils/inval.h"
4842
#include"utils/lsyscache.h"
43+
#include"utils/memutils.h"
4944
#include"utils/syscache.h"
5045

5146

@@ -1691,50 +1686,19 @@ AtEOXact_Namespace(bool isCommit)
16911686
staticvoid
16921687
RemoveTempRelations(OidtempNamespaceId)
16931688
{
1694-
Relationpgclass;
1695-
HeapScanDescscan;
1696-
HeapTupletuple;
1697-
ScanKeyDatakey;
16981689
ObjectAddressobject;
16991690

17001691
/*
1701-
* Scan pg_class to find all the relations in the target namespace.
1702-
* Ignore indexes, though, on the assumption that they'll go away when
1703-
* their tables are deleted.
1704-
*
1705-
* NOTE: if there are deletion constraints between temp relations, then
1706-
* our CASCADE delete call may cause as-yet-unvisited objects to go
1707-
* away. This is okay because we are using SnapshotNow; when the scan
1708-
* does reach those pg_class tuples, they'll be ignored as already
1709-
* deleted.
1692+
* We want to get rid of everything in the target namespace, but not
1693+
* the namespace itself (deleting it only to recreate it later would be
1694+
* a waste of cycles). We do this by finding everything that has a
1695+
* dependency on the namespace.
17101696
*/
1711-
ScanKeyEntryInitialize(&key,0x0,
1712-
Anum_pg_class_relnamespace,
1713-
F_OIDEQ,
1714-
ObjectIdGetDatum(tempNamespaceId));
1715-
1716-
pgclass=heap_openr(RelationRelationName,AccessShareLock);
1717-
scan=heap_beginscan(pgclass,SnapshotNow,1,&key);
1718-
1719-
while ((tuple=heap_getnext(scan,ForwardScanDirection))!=NULL)
1720-
{
1721-
switch (((Form_pg_class)GETSTRUCT(tuple))->relkind)
1722-
{
1723-
caseRELKIND_RELATION:
1724-
caseRELKIND_SEQUENCE:
1725-
caseRELKIND_VIEW:
1726-
object.classId=RelOid_pg_class;
1727-
object.objectId=HeapTupleGetOid(tuple);
1728-
object.objectSubId=0;
1729-
performDeletion(&object,DROP_CASCADE);
1730-
break;
1731-
default:
1732-
break;
1733-
}
1734-
}
1697+
object.classId=get_system_catalog_relid(NamespaceRelationName);
1698+
object.objectId=tempNamespaceId;
1699+
object.objectSubId=0;
17351700

1736-
heap_endscan(scan);
1737-
heap_close(pgclass,AccessShareLock);
1701+
deleteWhatDependsOn(&object);
17381702
}
17391703

17401704
/*

‎src/include/catalog/dependency.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: dependency.h,v 1.5 2002/09/04 20:31:37 momjian Exp $
10+
* $Id: dependency.h,v 1.6 2003/02/07 01:33:06 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -84,6 +84,8 @@ typedef struct ObjectAddress
8484
externvoidperformDeletion(constObjectAddress*object,
8585
DropBehaviorbehavior);
8686

87+
externvoiddeleteWhatDependsOn(constObjectAddress*object);
88+
8789
externvoidrecordDependencyOnExpr(constObjectAddress*depender,
8890
Node*expr,List*rtable,
8991
DependencyTypebehavior);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp