Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)