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

Commit7981c34

Browse files
committed
Force READY portals into FAILED state when a transaction or subtransaction
is aborted, if they were created within the failed xact. This preventsExecutorEnd from being run on them, which is a good idea because they maycontain references to tables or other objects that no longer exist.In particular this is hazardous when auto_explain is active, but it'sreally rather surprising that nobody has seen an issue with this before.I'm back-patching this to 8.4, since that's the first version that containsauto_explain or an ExecutorEnd hook, but I wonder whether we shouldn'tback-patch further.
1 parentc0d5be5 commit7981c34

File tree

1 file changed

+38
-48
lines changed

1 file changed

+38
-48
lines changed

‎src/backend/utils/mmgr/portalmem.c

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.116 2010/01/1802:30:25 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.117 2010/02/1803:06:46 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -668,6 +668,7 @@ AtAbort_Portals(void)
668668
{
669669
Portalportal=hentry->portal;
670670

671+
/* Any portal that was actually running has to be considered broken */
671672
if (portal->status==PORTAL_ACTIVE)
672673
portal->status=PORTAL_FAILED;
673674

@@ -677,6 +678,15 @@ AtAbort_Portals(void)
677678
if (portal->createSubid==InvalidSubTransactionId)
678679
continue;
679680

681+
/*
682+
* If it was created in the current transaction, we can't do normal
683+
* shutdown on a READY portal either; it might refer to objects
684+
* created in the failed transaction. See comments in
685+
* AtSubAbort_Portals.
686+
*/
687+
if (portal->status==PORTAL_READY)
688+
portal->status=PORTAL_FAILED;
689+
680690
/* let portalcmds.c clean up the state it knows about */
681691
if (PointerIsValid(portal->cleanup))
682692
{
@@ -789,61 +799,41 @@ AtSubAbort_Portals(SubTransactionId mySubid,
789799
continue;
790800

791801
/*
792-
* Force anyactive portals of my owntransaction into FAILED state.
793-
*This is mostlytoensure that a portal running a FETCH will go
794-
*FAILED if theunderlying cursor fails. (Note we do NOT wanttodo
795-
*this to upper-level portals, since they may be abletocontinue.)
796-
*
797-
*This is only needed to dodge the sanity check in PortalDrop.
802+
* Force anylive portals of my ownsubtransaction into FAILED state.
803+
*We havetodo this because they might refer to objects created or
804+
*changed in thefailed subtransaction, leadingtocrashes if
805+
*execution is resumed, or even if we just trytorun ExecutorEnd.
806+
* (Note we do NOT do this to upper-level portals, since they cannot
807+
*have such references and hence may be able to continue.)
798808
*/
799-
if (portal->status==PORTAL_ACTIVE)
809+
if (portal->status==PORTAL_READY||
810+
portal->status==PORTAL_ACTIVE)
800811
portal->status=PORTAL_FAILED;
801812

802-
/*
803-
* If the portal is READY then allow it to survive into the parent
804-
* transaction; otherwise shut it down.
805-
*
806-
* Currently, we can't actually support that because the portal's
807-
* query might refer to objects created or changed in the failed
808-
* subtransaction, leading to crashes if execution is resumed. So,
809-
* even READY portals are deleted.It would be nice to detect whether
810-
* the query actually depends on any such object, instead.
811-
*/
812-
#ifdefNOT_USED
813-
if (portal->status==PORTAL_READY)
813+
/* let portalcmds.c clean up the state it knows about */
814+
if (PointerIsValid(portal->cleanup))
814815
{
815-
portal->createSubid=parentSubid;
816-
if (portal->resowner)
817-
ResourceOwnerNewParent(portal->resowner,parentXactOwner);
816+
(*portal->cleanup) (portal);
817+
portal->cleanup=NULL;
818818
}
819-
else
820-
#endif
821-
{
822-
/* let portalcmds.c clean up the state it knows about */
823-
if (PointerIsValid(portal->cleanup))
824-
{
825-
(*portal->cleanup) (portal);
826-
portal->cleanup=NULL;
827-
}
828819

829-
/* drop cached plan reference, if any */
830-
PortalReleaseCachedPlan(portal);
820+
/* drop cached plan reference, if any */
821+
PortalReleaseCachedPlan(portal);
831822

832-
/*
833-
* Any resources belonging to the portal will be released in the
834-
* upcoming transaction-wide cleanup; they will be gone before we
835-
* run PortalDrop.
836-
*/
837-
portal->resowner=NULL;
823+
/*
824+
* Any resources belonging to the portal will be released in the
825+
* upcoming transaction-wide cleanup; they will be gone before we
826+
* run PortalDrop.
827+
*/
828+
portal->resowner=NULL;
838829

839-
/*
840-
* Although we can't delete the portal data structure proper, we
841-
* can release any memory in subsidiary contexts, such as executor
842-
* state. The cleanup hook was the last thing that might have
843-
* needed data there.
844-
*/
845-
MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
846-
}
830+
/*
831+
* Although we can't delete the portal data structure proper, we
832+
* can release any memory in subsidiary contexts, such as executor
833+
* state. The cleanup hook was the last thing that might have
834+
* needed data there.
835+
*/
836+
MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
847837
}
848838
}
849839

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp