diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 2de35efbd4..726db7b7f1 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -39,6 +39,11 @@ */ bool proc_exit_inprogress = false; +/* + * Set when shmem_exit() is in progress. + */ +bool shmem_exit_inprogress = false; + /* * This flag tracks whether we've called atexit() in the current process * (or in the parent postmaster). @@ -214,6 +219,8 @@ proc_exit_prepare(int code) void shmem_exit(int code) { + shmem_exit_inprogress = true; + /* * Call before_shmem_exit callbacks. * diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c index f3f0add1d6..75a6dde32b 100644 --- a/src/backend/utils/mmgr/portalmem.c +++ b/src/backend/utils/mmgr/portalmem.c @@ -22,6 +22,7 @@ #include "catalog/pg_type.h" #include "commands/portalcmds.h" #include "miscadmin.h" +#include "storage/ipc.h" #include "utils/builtins.h" #include "utils/memutils.h" #include "utils/snapmgr.h" @@ -757,6 +758,13 @@ AtAbort_Portals(void) { Portal portal = hentry->portal; + /* + * When elog(FATAL) is progress, we need to set the active portal to + * failed, so that PortalCleanup() doesn't run the executor shutdown. + */ + if (portal->status == PORTAL_ACTIVE && shmem_exit_inprogress) + MarkPortalFailed(portal); + /* * Do nothing else to cursors held over from a previous transaction. */ diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index e934a83a1c..6a05a89349 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -63,6 +63,7 @@ typedef void (*shmem_startup_hook_type) (void); /* ipc.c */ extern PGDLLIMPORT bool proc_exit_inprogress; +extern PGDLLIMPORT bool shmem_exit_inprogress; extern void proc_exit(int code) pg_attribute_noreturn(); extern void shmem_exit(int code);