Skip to content

Commit 175ff65

Browse files
committed
Fix possible crash reading pg_stat_activity.
With the old code, a backend that read pg_stat_activity without ever having executed a parallel query might see a backend in the midst of executing one waiting on a DSA LWLock, resulting in a crash. The solution is for backends to register the tranche at startup time, not the first time a parallel query is executed. Report by Andreas Seltenreich. Patch by me, reviewed by Thomas Munro.
1 parent 82f8107 commit 175ff65

File tree

4 files changed

+11
-25
lines changed

4 files changed

+11
-25
lines changed

src/backend/executor/execParallel.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,6 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, int nworkers)
486486
shm_toc_insert(pcxt->toc, PARALLEL_KEY_DSA, area_space);
487487
pei->area = dsa_create_in_place(area_space, dsa_minsize,
488488
LWTRANCHE_PARALLEL_QUERY_DSA,
489-
"parallel_query_dsa",
490489
pcxt->seg);
491490
}
492491

src/backend/storage/lmgr/lwlock.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ RegisterLWLockTranches(void)
508508
LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, "lock_manager");
509509
LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER,
510510
"predicate_lock_manager");
511+
LWLockRegisterTranche(LWTRANCHE_PARALLEL_QUERY_DSA,
512+
"parallel_query_dsa");
511513

512514
/* Register named tranches. */
513515
for (i = 0; i < NamedLWLockTrancheRequests; i++)

src/backend/utils/mmgr/dsa.c

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,6 @@ static char dsa_size_class_map[] = {
276276
*/
277277
#define DSA_FULLNESS_CLASSES 4
278278

279-
/*
280-
* Maximum length of a DSA name.
281-
*/
282-
#define DSA_MAXLEN 64
283-
284279
/*
285280
* A dsa_area_pool represents a set of objects of a given size class.
286281
*
@@ -326,7 +321,6 @@ typedef struct
326321
Size freed_segment_counter;
327322
/* The LWLock tranche ID. */
328323
int lwlock_tranche_id;
329-
char lwlock_tranche_name[DSA_MAXLEN];
330324
/* The general lock (protects everything except object pools). */
331325
LWLock lock;
332326
} dsa_area_control;
@@ -405,7 +399,7 @@ static void unlink_segment(dsa_area *area, dsa_segment_map *segment_map);
405399
static dsa_segment_map *get_best_segment(dsa_area *area, Size npages);
406400
static dsa_segment_map *make_new_segment(dsa_area *area, Size requested_pages);
407401
static dsa_area *create_internal(void *place, size_t size,
408-
int tranche_id, const char *tranche_name,
402+
int tranche_id,
409403
dsm_handle control_handle,
410404
dsm_segment *control_segment);
411405
static dsa_area *attach_internal(void *place, dsm_segment *segment,
@@ -419,12 +413,10 @@ static void check_for_freed_segments(dsa_area *area);
419413
* We can't allocate a LWLock tranche_id within this function, because tranche
420414
* IDs are a scarce resource; there are only 64k available, using low numbers
421415
* when possible matters, and we have no provision for recycling them. So,
422-
* we require the caller to provide one. The caller must also provide the
423-
* tranche name, so that we can distinguish LWLocks belonging to different
424-
* DSAs.
416+
* we require the caller to provide one.
425417
*/
426418
dsa_area *
427-
dsa_create(int tranche_id, const char *tranche_name)
419+
dsa_create(int tranche_id)
428420
{
429421
dsm_segment *segment;
430422
dsa_area *area;
@@ -446,7 +438,7 @@ dsa_create(int tranche_id, const char *tranche_name)
446438
/* Create a new DSA area with the control objet in this segment. */
447439
area = create_internal(dsm_segment_address(segment),
448440
DSA_INITIAL_SEGMENT_SIZE,
449-
tranche_id, tranche_name,
441+
tranche_id,
450442
dsm_segment_handle(segment), segment);
451443

452444
/* Clean up when the control segment detaches. */
@@ -474,12 +466,11 @@ dsa_create(int tranche_id, const char *tranche_name)
474466
*/
475467
dsa_area *
476468
dsa_create_in_place(void *place, size_t size,
477-
int tranche_id, const char *tranche_name,
478-
dsm_segment *segment)
469+
int tranche_id, dsm_segment *segment)
479470
{
480471
dsa_area *area;
481472

482-
area = create_internal(place, size, tranche_id, tranche_name,
473+
area = create_internal(place, size, tranche_id,
483474
DSM_HANDLE_INVALID, NULL);
484475

485476
/*
@@ -1139,7 +1130,7 @@ dsa_minimum_size(void)
11391130
*/
11401131
static dsa_area *
11411132
create_internal(void *place, size_t size,
1142-
int tranche_id, const char *tranche_name,
1133+
int tranche_id,
11431134
dsm_handle control_handle,
11441135
dsm_segment *control_segment)
11451136
{
@@ -1192,7 +1183,6 @@ create_internal(void *place, size_t size,
11921183
control->refcnt = 1;
11931184
control->freed_segment_counter = 0;
11941185
control->lwlock_tranche_id = tranche_id;
1195-
strlcpy(control->lwlock_tranche_name, tranche_name, DSA_MAXLEN);
11961186

11971187
/*
11981188
* Create the dsa_area object that this backend will use to access the
@@ -1204,8 +1194,6 @@ create_internal(void *place, size_t size,
12041194
area->mapping_pinned = false;
12051195
memset(area->segment_maps, 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
12061196
area->high_segment_index = 0;
1207-
LWLockRegisterTranche(control->lwlock_tranche_id,
1208-
control->lwlock_tranche_name);
12091197
LWLockInitialize(&control->lock, control->lwlock_tranche_id);
12101198
for (i = 0; i < DSA_NUM_SIZE_CLASSES; ++i)
12111199
LWLockInitialize(DSA_SCLASS_LOCK(area, i),
@@ -1262,8 +1250,6 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle)
12621250
memset(&area->segment_maps[0], 0,
12631251
sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
12641252
area->high_segment_index = 0;
1265-
LWLockRegisterTranche(control->lwlock_tranche_id,
1266-
control->lwlock_tranche_name);
12671253

12681254
/* Set up the segment map for this process's mapping. */
12691255
segment_map = &area->segment_maps[0];

src/include/utils/dsa.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,9 @@ typedef dsm_handle dsa_handle;
9090

9191
extern void dsa_startup(void);
9292

93-
extern dsa_area *dsa_create(int tranche_id, const char *tranche_name);
93+
extern dsa_area *dsa_create(int tranche_id);
9494
extern dsa_area *dsa_create_in_place(void *place, Size size,
95-
int tranche_id, const char *tranche_name,
96-
dsm_segment *segment);
95+
int tranche_id, dsm_segment *segment);
9796
extern dsa_area *dsa_attach(dsa_handle handle);
9897
extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment);
9998
extern void dsa_release_in_place(void *place);

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