Skip to content

Commit 2ad5c27

Browse files
committed
Don't send protocol messages to a shm_mq that no longer exists.
Commit 2bd9e41 introduced a mechanism for relaying protocol messages from a background worker to another backend via a shm_mq. However, there was no provision for shutting down the communication channel. Therefore, a protocol message sent late in the shutdown sequence, such as a DEBUG message resulting from cranking up log_min_messages, could crash the server. To fix, install an on_dsm_detach callback that disables sending messages to the shm_mq when the associated DSM is detached.
1 parent 3587cbc commit 2ad5c27

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/backend/access/transam/parallel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ ParallelWorkerMain(Datum main_arg)
867867
ParallelWorkerNumber * PARALLEL_ERROR_QUEUE_SIZE);
868868
shm_mq_set_sender(mq, MyProc);
869869
mqh = shm_mq_attach(mq, seg, NULL);
870-
pq_redirect_to_shm_mq(mq, mqh);
870+
pq_redirect_to_shm_mq(seg, mqh);
871871
pq_set_parallel_master(fps->parallel_master_pid,
872872
fps->parallel_master_backend_id);
873873

src/backend/libpq/pqmq.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static bool pq_mq_busy = false;
2626
static pid_t pq_mq_parallel_master_pid = 0;
2727
static pid_t pq_mq_parallel_master_backend_id = InvalidBackendId;
2828

29+
static void pq_cleanup_redirect_to_shm_mq(dsm_segment *seg, Datum arg);
2930
static void mq_comm_reset(void);
3031
static int mq_flush(void);
3132
static int mq_flush_if_writable(void);
@@ -51,13 +52,26 @@ static PQcommMethods PqCommMqMethods = {
5152
* message queue.
5253
*/
5354
void
54-
pq_redirect_to_shm_mq(shm_mq *mq, shm_mq_handle *mqh)
55+
pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh)
5556
{
5657
PqCommMethods = &PqCommMqMethods;
57-
pq_mq = mq;
58+
pq_mq = shm_mq_get_queue(mqh);
5859
pq_mq_handle = mqh;
5960
whereToSendOutput = DestRemote;
6061
FrontendProtocol = PG_PROTOCOL_LATEST;
62+
on_dsm_detach(seg, pq_cleanup_redirect_to_shm_mq, (Datum) 0);
63+
}
64+
65+
/*
66+
* When the DSM that contains our shm_mq goes away, we need to stop sending
67+
* messages to it.
68+
*/
69+
static void
70+
pq_cleanup_redirect_to_shm_mq(dsm_segment *seg, Datum arg)
71+
{
72+
pq_mq = NULL;
73+
pq_mq_handle = NULL;
74+
whereToSendOutput = DestNone;
6175
}
6276

6377
/*
@@ -123,9 +137,19 @@ mq_putmessage(char msgtype, const char *s, size_t len)
123137
if (pq_mq != NULL)
124138
shm_mq_detach(pq_mq);
125139
pq_mq = NULL;
140+
pq_mq_handle = NULL;
126141
return EOF;
127142
}
128143

144+
/*
145+
* If the message queue is already gone, just ignore the message. This
146+
* doesn't necessarily indicate a problem; for example, DEBUG messages
147+
* can be generated late in the shutdown sequence, after all DSMs have
148+
* already been detached.
149+
*/
150+
if (pq_mq == NULL)
151+
return 0;
152+
129153
pq_mq_busy = true;
130154

131155
iov[0].data = &msgtype;

src/include/libpq/pqmq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "lib/stringinfo.h"
1717
#include "storage/shm_mq.h"
1818

19-
extern void pq_redirect_to_shm_mq(shm_mq *, shm_mq_handle *);
19+
extern void pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh);
2020
extern void pq_set_parallel_master(pid_t pid, BackendId backend_id);
2121

2222
extern void pq_parse_errornotice(StringInfo str, ErrorData *edata);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy