aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2018-08-23 15:13:48 +0200
committerPeter Eisentraut <peter_e@gmx.net>2018-08-27 22:15:39 +0200
commit2657d4ea66c775c3334181722115be2d6128c5cd (patch)
treed42cae822e260a54c487527db13c8cc131840889 /src/backend/utils
parentc5e235ff8ad0f4907a736a6440dc4be6f939e65c (diff)
downloadpostgresql-2657d4ea66c775c3334181722115be2d6128c5cd.tar.gz
postgresql-2657d4ea66c775c3334181722115be2d6128c5cd.zip
Fix snapshot leak warning for some procedures
The problem arises with the combination of CALL with output parameters and doing a COMMIT inside the procedure. When a CALL has output parameters, the portal uses the strategy PORTAL_UTIL_SELECT instead of PORTAL_MULTI_QUERY. Using PORTAL_UTIL_SELECT causes the portal's snapshot to be registered with the current resource owner (portal->holdSnapshot); see 9ee1cf04ab6bcefe03a11837b53f29ca9dc24c7a for the reason. Normally, PortalDrop() unregisters the snapshot. If not, then ResourceOwnerRelease() will print a warning about a snapshot leak on transaction commit. A transaction commit normally drops all portals (PreCommit_Portals()), except the active portal. So in case of the active portal, we need to manually release the snapshot to avoid the warning. Reported-by: Prabhat Sahu <prabhat.sahu@enterprisedb.com> Reviewed-by: Jonathan S. Katz <jkatz@postgresql.org>
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/mmgr/portalmem.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 04ea32f49f2..d34cab0eb88 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -689,13 +689,23 @@ PreCommit_Portals(bool isPrepare)
/*
* Do not touch active portals --- this can only happen in the case of
- * a multi-transaction utility command, such as VACUUM.
+ * a multi-transaction utility command, such as VACUUM, or a commit in
+ * a procedure.
*
* Note however that any resource owner attached to such a portal is
- * still going to go away, so don't leave a dangling pointer.
+ * still going to go away, so don't leave a dangling pointer. Also
+ * unregister any snapshots held by the portal, mainly to avoid
+ * snapshot leak warnings from ResourceOwnerRelease().
*/
if (portal->status == PORTAL_ACTIVE)
{
+ if (portal->holdSnapshot)
+ {
+ if (portal->resowner)
+ UnregisterSnapshotFromOwner(portal->holdSnapshot,
+ portal->resowner);
+ portal->holdSnapshot = NULL;
+ }
portal->resowner = NULL;
continue;
}