Skip to content

Commit adc5607

Browse files
authored
Merge pull request #122 from postgrespro/fix_collector_hangs
Fix collector hangs if requesting backend is gone Also remove PG-13 support and update copyright
2 parents 4e674bc + 2c22a04 commit adc5607

2 files changed

Lines changed: 34 additions & 69 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ PostgreSQL installation. It is available from
5151
[github](https://github.com/postgrespro/pg_wait_sampling)
5252
under the same license as
5353
[PostgreSQL](http://www.postgresql.org/about/licence/)
54-
and supports PostgreSQL 13+.
54+
and supports PostgreSQL 14+.
5555

5656
Installation
5757
------------
@@ -62,10 +62,10 @@ repository: https://download.postgresql.org/pub/repos/
6262
Manual build
6363
------------
6464

65-
`pg_wait_sampling` is PostgreSQL extension which requires PostgreSQL 13 or
65+
`pg_wait_sampling` is PostgreSQL extension which requires PostgreSQL 14 or
6666
higher. Before build and install you should ensure following:
6767

68-
* PostgreSQL version is 13 or higher.
68+
* PostgreSQL version is 14 or higher.
6969
* You have development package of PostgreSQL installed or you built
7070
PostgreSQL from source.
7171
* Your PATH variable is configured so that `pg_config` command available, or

pg_wait_sampling.c

Lines changed: 31 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* pg_wait_sampling.c
33
* Track information about wait events.
44
*
5-
* Copyright (c) 2015-2025, Postgres Professional
5+
* Copyright (c) 2015-2026, Postgres Professional
66
*
77
* IDENTIFICATION
88
* contrib/pg_wait_sampling/pg_wait_sampling.c
@@ -75,9 +75,7 @@ static shmem_request_hook_type prev_shmem_request_hook = NULL;
7575
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
7676
static PGPROC *search_proc(int backendPid);
7777
static PlannedStmt *pgws_planner_hook(Query *parse,
78-
#if PG_VERSION_NUM >= 130000
7978
const char *query_string,
80-
#endif
8179
int cursorOptions, ParamListInfo boundParams
8280
#if PG_VERSION_NUM >= 190000
8381
, ExplainState *es
@@ -87,26 +85,20 @@ static void pgws_ExecutorStart(QueryDesc *queryDesc, int eflags);
8785
static void pgws_ExecutorRun(QueryDesc *queryDesc,
8886
ScanDirection direction,
8987
uint64 count
90-
#if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
88+
#if PG_VERSION_NUM < 180000
9189
,bool execute_once
9290
#endif
9391
);
9492
static void pgws_ExecutorFinish(QueryDesc *queryDesc);
9593
static void pgws_ExecutorEnd(QueryDesc *queryDesc);
9694
static void pgws_ProcessUtility(PlannedStmt *pstmt,
9795
const char *queryString,
98-
#if PG_VERSION_NUM >= 140000
9996
bool readOnlyTree,
100-
#endif
10197
ProcessUtilityContext context,
10298
ParamListInfo params,
10399
QueryEnvironment *queryEnv,
104100
DestReceiver *dest,
105-
#if PG_VERSION_NUM >= 130000
106101
QueryCompletion *qc
107-
#else
108-
char *completionTag
109-
#endif
110102
);
111103

112104
/*---- GUC variables ----*/
@@ -654,6 +646,16 @@ receive_array(SHMRequest request, Size item_size, Size *count)
654646
char *ptr;
655647
MemoryContext oldctx;
656648

649+
/* Check that the collector was started to avoid NULL pointer dereference */
650+
if (!pgws_collector_hdr->latch)
651+
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
652+
errmsg("pg_wait_sampling collector wasn't started")));
653+
654+
/* Check that the collector exists to avoid getting stuck in shm_mq_receive */
655+
if (pgws_collector_hdr->latch->owner_pid == 0)
656+
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
657+
errmsg("pg_wait_sampling collector doesn't exist")));
658+
657659
/* Ensure nobody else trying to send request to queue */
658660
pgws_init_lock_tag(&queueTag, PGWS_QUEUE_LOCK);
659661
LockAcquire(&queueTag, ExclusiveLock, false, false);
@@ -664,19 +666,6 @@ receive_array(SHMRequest request, Size item_size, Size *count)
664666
pgws_collector_hdr->request = request;
665667
LockRelease(&collectorTag, ExclusiveLock, false);
666668

667-
/*
668-
* Check that the collector was started to avoid NULL
669-
* pointer dereference.
670-
*/
671-
if (!pgws_collector_hdr->latch)
672-
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
673-
errmsg("pg_wait_sampling collector wasn't started")));
674-
675-
/* Check that the collector exists to avoid getting stuck in shm_mq_receive */
676-
if (pgws_collector_hdr->latch->owner_pid == 0)
677-
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
678-
errmsg("pg_wait_sampling collector doesn't exist")));
679-
680669
SetLatch(pgws_collector_hdr->latch);
681670

682671
shm_mq_set_receiver(recv_mq, MyProc);
@@ -837,6 +826,16 @@ pg_wait_sampling_reset_profile(PG_FUNCTION_ARGS)
837826

838827
check_shmem();
839828

829+
/* Check that the collector was started to avoid NULL pointer dereference */
830+
if (!pgws_collector_hdr->latch)
831+
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
832+
errmsg("pg_wait_sampling collector wasn't started")));
833+
834+
/* Check that the collector exists to avoid setting pgws_collector_hdr->request */
835+
if (pgws_collector_hdr->latch->owner_pid == 0)
836+
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
837+
errmsg("pg_wait_sampling collector doesn't exist")));
838+
840839
pgws_init_lock_tag(&queueTag, PGWS_QUEUE_LOCK);
841840

842841
LockAcquire(&queueTag, ExclusiveLock, false, false);
@@ -846,14 +845,6 @@ pg_wait_sampling_reset_profile(PG_FUNCTION_ARGS)
846845
pgws_collector_hdr->request = PROFILE_RESET;
847846
LockRelease(&collectorTag, ExclusiveLock, false);
848847

849-
/*
850-
* Check that the collector was started to avoid NULL
851-
* pointer dereference.
852-
*/
853-
if (!pgws_collector_hdr->latch)
854-
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
855-
errmsg("pg_wait_sampling collector wasn't started")));
856-
857848
SetLatch(pgws_collector_hdr->latch);
858849

859850
LockRelease(&queueTag, ExclusiveLock, false);
@@ -959,9 +950,7 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
959950
*/
960951
static PlannedStmt *
961952
pgws_planner_hook(Query *parse,
962-
#if PG_VERSION_NUM >= 130000
963953
const char *query_string,
964-
#endif
965954
int cursorOptions,
966955
ParamListInfo boundParams
967956
#if PG_VERSION_NUM >= 190000
@@ -985,19 +974,15 @@ pgws_planner_hook(Query *parse,
985974
/* Invoke original hook if needed */
986975
if (planner_hook_next)
987976
result = planner_hook_next(parse,
988-
#if PG_VERSION_NUM >= 130000
989977
query_string,
990-
#endif
991978
cursorOptions, boundParams
992979
#if PG_VERSION_NUM >= 190000
993980
, es
994981
#endif
995982
);
996983
else
997984
result = standard_planner(parse,
998-
#if PG_VERSION_NUM >= 130000
999985
query_string,
1000-
#endif
1001986
cursorOptions, boundParams
1002987
#if PG_VERSION_NUM >= 190000
1003988
, es
@@ -1043,7 +1028,7 @@ static void
10431028
pgws_ExecutorRun(QueryDesc *queryDesc,
10441029
ScanDirection direction,
10451030
uint64 count
1046-
#if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1031+
#if PG_VERSION_NUM < 180000
10471032
,bool execute_once
10481033
#endif
10491034
)
@@ -1055,16 +1040,16 @@ pgws_ExecutorRun(QueryDesc *queryDesc,
10551040
PG_TRY();
10561041
{
10571042
if (prev_ExecutorRun)
1058-
#if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1059-
prev_ExecutorRun(queryDesc, direction, count, execute_once);
1060-
#else
1043+
#if PG_VERSION_NUM >= 180000
10611044
prev_ExecutorRun(queryDesc, direction, count);
1045+
#else
1046+
prev_ExecutorRun(queryDesc, direction, count, execute_once);
10621047
#endif
10631048
else
1064-
#if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1065-
standard_ExecutorRun(queryDesc, direction, count, execute_once);
1066-
#else
1049+
#if PG_VERSION_NUM >= 180000
10671050
standard_ExecutorRun(queryDesc, direction, count);
1051+
#else
1052+
standard_ExecutorRun(queryDesc, direction, count, execute_once);
10681053
#endif
10691054
nesting_level--;
10701055
if (nesting_level == 0)
@@ -1132,18 +1117,12 @@ pgws_ExecutorEnd(QueryDesc *queryDesc)
11321117
static void
11331118
pgws_ProcessUtility(PlannedStmt *pstmt,
11341119
const char *queryString,
1135-
#if PG_VERSION_NUM >= 140000
11361120
bool readOnlyTree,
1137-
#endif
11381121
ProcessUtilityContext context,
11391122
ParamListInfo params,
11401123
QueryEnvironment *queryEnv,
11411124
DestReceiver *dest,
1142-
#if PG_VERSION_NUM >= 130000
11431125
QueryCompletion *qc
1144-
#else
1145-
char *completionTag
1146-
#endif
11471126
)
11481127
{
11491128
int i = MyProc - ProcGlobal->allProcs;
@@ -1160,30 +1139,16 @@ pgws_ProcessUtility(PlannedStmt *pstmt,
11601139
{
11611140
if (prev_ProcessUtility)
11621141
prev_ProcessUtility(pstmt, queryString,
1163-
#if PG_VERSION_NUM >= 140000
11641142
readOnlyTree,
1165-
#endif
11661143
context, params, queryEnv,
11671144
dest,
1168-
#if PG_VERSION_NUM >= 130000
1169-
qc
1170-
#else
1171-
completionTag
1172-
#endif
1173-
);
1145+
qc);
11741146
else
11751147
standard_ProcessUtility(pstmt, queryString,
1176-
#if PG_VERSION_NUM >= 140000
11771148
readOnlyTree,
1178-
#endif
11791149
context, params, queryEnv,
11801150
dest,
1181-
#if PG_VERSION_NUM >= 130000
1182-
qc
1183-
#else
1184-
completionTag
1185-
#endif
1186-
);
1151+
qc);
11871152
nesting_level--;
11881153
if (nesting_level == 0)
11891154
pgws_proc_queryids[i] = UINT64CONST(0);

0 commit comments

Comments
 (0)