aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2018-02-01 17:07:38 -0500
committerPeter Eisentraut <peter_e@gmx.net>2018-02-16 16:21:24 -0500
commitad9a274778d2d88c46b90309212b92ee7fdf9afe (patch)
treee48bd1ffc725696fde3279ffabd4fb316743ab45 /src
parent49bff412edd9eb226e146f6e4db7b5a8e843bd1f (diff)
downloadpostgresql-ad9a274778d2d88c46b90309212b92ee7fdf9afe.tar.gz
postgresql-ad9a274778d2d88c46b90309212b92ee7fdf9afe.zip
Fix crash when canceling parallel query
elog(FATAL) would end up calling PortalCleanup(), which would call executor shutdown code, which could fail and crash, especially under parallel query. This was introduced by 8561e4840c81f7e345be2df170839846814fa004, which did not want to mark an active portal as failed by a normal transaction abort anymore. But we do need to do that for an elog(FATAL) exit. Introduce a variable shmem_exit_inprogress similar to the existing proc_exit_inprogress, so we can tell whether we are in the FATAL exit scenario. Reported-by: Andres Freund <andres@anarazel.de>
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/ipc.c7
-rw-r--r--src/backend/utils/mmgr/portalmem.c8
-rw-r--r--src/include/storage/ipc.h1
3 files changed, 16 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c
index 2de35efbd4f..726db7b7f1b 100644
--- a/src/backend/storage/ipc/ipc.c
+++ b/src/backend/storage/ipc/ipc.c
@@ -40,6 +40,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 f3f0add1d6d..75a6dde32b3 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"
@@ -758,6 +759,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.
*/
if (portal->createSubid == InvalidSubTransactionId)
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index e934a83a1c9..6a05a89349c 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);