Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e17ab38

Browse files
committed
[refer #PGPRO-6599]: Avoid race conditions while processing PROFILE_REQUEST and
PROFILE_RESET requests. After initialization of "request" variable in collector.c main loop another client backend could change the value of "collector_hdr->request" variable. Changing this value from "PROFILE_RESET" to "PROFILE_REQUEST" could cause deadlock: "collector" processed "PROFILE_RESET" query while client backend waits data from the "collector_mq" shared memory message queue. Now we read and write "collector_hdr->request" variable only using "PGWS_COLLECTOR_LOCK" lock. Removed obsolete "read_current_wait()" function definition from pg_wait_sampling.h. tags: pg_wait_sampling
1 parent af53205 commit e17ab38

File tree

3 files changed

+10
-11
lines changed

3 files changed

+10
-11
lines changed

collector.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,12 @@ collector_main(Datum main_arg)
446446
if (collector_hdr->request != NO_REQUEST)
447447
{
448448
LOCKTAG tag;
449-
SHMRequest request = collector_hdr->request;
449+
SHMRequest request;
450450

451451
init_lock_tag(&tag, PGWS_COLLECTOR_LOCK);
452452

453453
LockAcquire(&tag, ExclusiveLock, false, false);
454+
request = collector_hdr->request;
454455
collector_hdr->request = NO_REQUEST;
455456

456457
if (request == HISTORY_REQUEST || request == PROFILE_REQUEST)

pg_wait_sampling.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -590,13 +590,12 @@ receive_array(SHMRequest request, Size item_size, Size *count)
590590
init_lock_tag(&queueTag, PGWS_QUEUE_LOCK);
591591
LockAcquire(&queueTag, ExclusiveLock, false, false);
592592

593-
/* Ensure collector has processed previous request */
593+
recv_mq = shm_mq_create(collector_mq, COLLECTOR_QUEUE_SIZE);
594+
594595
init_lock_tag(&collectorTag, PGWS_COLLECTOR_LOCK);
595596
LockAcquire(&collectorTag, ExclusiveLock, false, false);
596-
LockRelease(&collectorTag, ExclusiveLock, false);
597-
598-
recv_mq = shm_mq_create(collector_mq, COLLECTOR_QUEUE_SIZE);
599597
collector_hdr->request = request;
598+
LockRelease(&collectorTag, ExclusiveLock, false);
600599

601600
if (!collector_hdr->latch)
602601
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
@@ -756,19 +755,19 @@ Datum
756755
pg_wait_sampling_reset_profile(PG_FUNCTION_ARGS)
757756
{
758757
LOCKTAG tag;
759-
LOCKTAG tagCollector;
758+
LOCKTAG collectorTag;
760759

761760
check_shmem();
762761

763762
init_lock_tag(&tag, PGWS_QUEUE_LOCK);
764763

765764
LockAcquire(&tag, ExclusiveLock, false, false);
766765

767-
init_lock_tag(&tagCollector, PGWS_COLLECTOR_LOCK);
768-
LockAcquire(&tagCollector, ExclusiveLock, false, false);
769-
LockRelease(&tagCollector, ExclusiveLock, false);
770-
766+
init_lock_tag(&collectorTag, PGWS_COLLECTOR_LOCK);
767+
LockAcquire(&collectorTag, ExclusiveLock, false, false);
771768
collector_hdr->request = PROFILE_RESET;
769+
LockRelease(&collectorTag, ExclusiveLock, false);
770+
772771
SetLatch(collector_hdr->latch);
773772

774773
LockRelease(&tag, ExclusiveLock, false);

pg_wait_sampling.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ extern void check_shmem(void);
7575
extern CollectorShmqHeader *collector_hdr;
7676
extern shm_mq *collector_mq;
7777
extern uint64 *proc_queryids;
78-
extern void read_current_wait(PGPROC *proc, HistoryItem *item);
7978
extern void init_lock_tag(LOCKTAG *tag, uint32 lock);
8079

8180
/* collector.c */

0 commit comments

Comments
 (0)