diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 3e1b92df030..5dc9334c2a0 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -2236,6 +2236,8 @@ asyncQueueAdvanceTail(void) static void ProcessIncomingNotify(bool flush) { + MemoryContext oldcontext; + /* We *must* reset the flag */ notifyInterruptPending = false; @@ -2250,14 +2252,21 @@ ProcessIncomingNotify(bool flush) /* * We must run asyncQueueReadAllNotifications inside a transaction, else - * bad things happen if it gets an error. + * bad things happen if it gets an error. However, we need to preserve + * the caller's memory context (typically MessageContext). */ + oldcontext = CurrentMemoryContext; + StartTransactionCommand(); asyncQueueReadAllNotifications(); CommitTransactionCommand(); + /* Caller's context had better not have been transaction-local */ + Assert(MemoryContextIsValid(oldcontext)); + MemoryContextSwitchTo(oldcontext); + /* * If this isn't an end-of-command case, we must flush the notify messages * to ensure frontend gets them promptly. diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index 8a5c5265247..b6ae7316472 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -17,6 +17,7 @@ #include "access/xact.h" #include "commands/async.h" #include "miscadmin.h" +#include "nodes/memnodes.h" #include "storage/ipc.h" #include "storage/proc.h" #include "storage/sinvaladt.h" @@ -184,6 +185,7 @@ ProcessCatchupInterrupt(void) * can just call AcceptInvalidationMessages() to do this. If we * aren't, we start and immediately end a transaction; the call to * AcceptInvalidationMessages() happens down inside transaction start. + * Be sure to preserve caller's memory context when we do that. * * It is awfully tempting to just call AcceptInvalidationMessages() * without the rest of the xact start/stop overhead, and I think that @@ -197,9 +199,14 @@ ProcessCatchupInterrupt(void) } else { + MemoryContext oldcontext = CurrentMemoryContext; + elog(DEBUG4, "ProcessCatchupEvent outside transaction"); StartTransactionCommand(); CommitTransactionCommand(); + /* Caller's context had better not have been transaction-local */ + Assert(MemoryContextIsValid(oldcontext)); + MemoryContextSwitchTo(oldcontext); } } }