diff options
author | Peter Eisentraut | 2018-08-23 13:13:48 +0000 |
---|---|---|
committer | Peter Eisentraut | 2018-08-27 20:16:15 +0000 |
commit | 7a3b7bbfded3142aaa8edae2dbc88999568cc1cd (patch) | |
tree | 03984a905f939f36c31b94a66b5835b2b6e55942 /src/backend/utils/mmgr/portalmem.c | |
parent | cbdca00bef59ee204313fe8f0e4f36bc804a38aa (diff) |
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 <[email protected]>
Reviewed-by: Jonathan S. Katz <[email protected]>
Diffstat (limited to 'src/backend/utils/mmgr/portalmem.c')
-rw-r--r-- | src/backend/utils/mmgr/portalmem.c | 14 |
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; } |