Skip to content

Commit 06d9025

Browse files
authored
Merge pull request #80 from postgrespro/nested_query_ids
Add option for tracking subqueries' wait events
2 parents c7507a0 + 7ebbf8a commit 06d9025

File tree

3 files changed

+91
-16
lines changed

3 files changed

+91
-16
lines changed

Diff for: README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,16 @@ GUCs.
139139
| pg_wait_sampling.history_period | int4 | Period for history sampling in milliseconds | 10 |
140140
| pg_wait_sampling.profile_period | int4 | Period for profile sampling in milliseconds | 10 |
141141
| pg_wait_sampling.profile_pid | bool | Whether profile should be per pid | true |
142-
| pg_wait_sampling.profile_queries | bool | Whether profile should be per query | true |
142+
| pg_wait_sampling.profile_queries | enum | Whether profile should be per query | top |
143143
| pg_wait_sampling.sample_cpu | bool | Whether on CPU backends should be sampled | true |
144144

145145
If `pg_wait_sampling.profile_pid` is set to false, sampling profile wouldn't be
146146
collected in per-process manner. In this case the value of pid could would
147147
be always zero and corresponding row contain samples among all the processes.
148148

149-
While `pg_wait_sampling.profile_queries` is set to false `queryid` field in
150-
views will be zero.
149+
If `pg_wait_sampling.profile_queries` is set to `none`, `queryid` field in
150+
views will be zero. If it is set to `top`, queryIds only of top level statements
151+
are recorded. If it is set to `all`, queryIds of nested statements are recorded.
151152

152153
If `pg_wait_sampling.sample_cpu` is set to true then processes that are not
153154
waiting on anything are also sampled. The wait event columns for such processes

Diff for: pg_wait_sampling.c

+86-12
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,35 @@ static void pgws_ProcessUtility(PlannedStmt *pstmt,
9595
#endif
9696
);
9797

98+
/*---- GUC variables ----*/
99+
100+
typedef enum
101+
{
102+
PGWS_PROFILE_QUERIES_NONE, /* profile no statements */
103+
PGWS_PROFILE_QUERIES_TOP, /* only top level statements */
104+
PGWS_PROFILE_QUERIES_ALL /* all statements, including nested ones */
105+
} PGWSTrackLevel;
106+
107+
static const struct config_enum_entry pgws_profile_queries_options[] =
108+
{
109+
{"none", PGWS_PROFILE_QUERIES_NONE, false},
110+
{"off", PGWS_PROFILE_QUERIES_NONE, false},
111+
{"no", PGWS_PROFILE_QUERIES_NONE, false},
112+
{"false", PGWS_PROFILE_QUERIES_NONE, false},
113+
{"0", PGWS_PROFILE_QUERIES_NONE, false},
114+
{"top", PGWS_PROFILE_QUERIES_TOP, false},
115+
{"on", PGWS_PROFILE_QUERIES_TOP, false},
116+
{"yes", PGWS_PROFILE_QUERIES_TOP, false},
117+
{"true", PGWS_PROFILE_QUERIES_TOP, false},
118+
{"1", PGWS_PROFILE_QUERIES_TOP, false},
119+
{"all", PGWS_PROFILE_QUERIES_ALL, false},
120+
{NULL, 0, false}
121+
};
122+
123+
#define pgws_enabled(level) \
124+
((pgws_collector_hdr->profileQueries == PGWS_PROFILE_QUERIES_ALL) || \
125+
(pgws_collector_hdr->profileQueries == PGWS_PROFILE_QUERIES_TOP && (level) == 0))
126+
98127
/*
99128
* Calculate max processes count.
100129
*
@@ -185,6 +214,14 @@ shmem_int_guc_check_hook(int *newval, void **extra, GucSource source)
185214
return true;
186215
}
187216

217+
static bool
218+
shmem_enum_guc_check_hook(int *newval, void **extra, GucSource source)
219+
{
220+
if (UsedShmemSegAddr == NULL)
221+
return false;
222+
return true;
223+
}
224+
188225
static bool
189226
shmem_bool_guc_check_hook(bool *newval, void **extra, GucSource source)
190227
{
@@ -260,8 +297,8 @@ setup_gucs()
260297
else if (!strcmp(name, "pg_wait_sampling.profile_queries"))
261298
{
262299
profile_queries_found = true;
263-
var->_bool.variable = &pgws_collector_hdr->profileQueries;
264-
pgws_collector_hdr->profileQueries = true;
300+
var->_enum.variable = &pgws_collector_hdr->profileQueries;
301+
pgws_collector_hdr->profileQueries = PGWS_PROFILE_QUERIES_TOP;
265302
}
266303
else if (!strcmp(name, "pg_wait_sampling.sample_cpu"))
267304
{
@@ -296,10 +333,10 @@ setup_gucs()
296333
PGC_SUSET, 0, shmem_bool_guc_check_hook, NULL, NULL);
297334

298335
if (!profile_queries_found)
299-
DefineCustomBoolVariable("pg_wait_sampling.profile_queries",
336+
DefineCustomEnumVariable("pg_wait_sampling.profile_queries",
300337
"Sets whether profile should be collected per query.", NULL,
301-
&pgws_collector_hdr->profileQueries, true,
302-
PGC_SUSET, 0, shmem_bool_guc_check_hook, NULL, NULL);
338+
&pgws_collector_hdr->profileQueries, PGWS_PROFILE_QUERIES_TOP, pgws_profile_queries_options,
339+
PGC_SUSET, 0, shmem_enum_guc_check_hook, NULL, NULL);
303340

304341
if (!sample_cpu_found)
305342
DefineCustomBoolVariable("pg_wait_sampling.sample_cpu",
@@ -354,6 +391,8 @@ pgws_shmem_startup(void)
354391

355392
pgws_collector_hdr = shm_toc_allocate(toc, sizeof(CollectorShmqHeader));
356393
shm_toc_insert(toc, 0, pgws_collector_hdr);
394+
/* needed to please check_GUC_init */
395+
pgws_collector_hdr->profileQueries = PGWS_PROFILE_QUERIES_TOP;
357396
pgws_collector_mq = shm_toc_allocate(toc, COLLECTOR_QUEUE_SIZE);
358397
shm_toc_insert(toc, 1, pgws_collector_mq);
359398
pgws_proc_queryids = shm_toc_allocate(toc,
@@ -933,10 +972,15 @@ pgws_planner_hook(Query *parse,
933972
int cursorOptions,
934973
ParamListInfo boundParams)
935974
{
936-
PlannedStmt *result;
937-
int i = MyProc - ProcGlobal->allProcs;
938-
if (nesting_level == 0)
975+
PlannedStmt *result;
976+
int i = MyProc - ProcGlobal->allProcs;
977+
uint64 save_queryId = 0;
978+
979+
if (pgws_enabled(nesting_level))
980+
{
981+
save_queryId = pgws_proc_queryids[i];
939982
pgws_proc_queryids[i] = parse->queryId;
983+
}
940984

941985
nesting_level++;
942986
PG_TRY();
@@ -957,12 +1001,16 @@ pgws_planner_hook(Query *parse,
9571001
nesting_level--;
9581002
if (nesting_level == 0)
9591003
pgws_proc_queryids[i] = UINT64CONST(0);
1004+
else if (pgws_enabled(nesting_level))
1005+
pgws_proc_queryids[i] = save_queryId;
9601006
}
9611007
PG_CATCH();
9621008
{
9631009
nesting_level--;
9641010
if (nesting_level == 0)
9651011
pgws_proc_queryids[i] = UINT64CONST(0);
1012+
else if (pgws_enabled(nesting_level))
1013+
pgws_proc_queryids[i] = save_queryId;
9661014
PG_RE_THROW();
9671015
}
9681016
PG_END_TRY();
@@ -977,9 +1025,8 @@ static void
9771025
pgws_ExecutorStart(QueryDesc *queryDesc, int eflags)
9781026
{
9791027
int i = MyProc - ProcGlobal->allProcs;
980-
if (nesting_level == 0)
1028+
if (pgws_enabled(nesting_level))
9811029
pgws_proc_queryids[i] = queryDesc->plannedstmt->queryId;
982-
9831030
if (prev_ExecutorStart)
9841031
prev_ExecutorStart(queryDesc, eflags);
9851032
else
@@ -991,6 +1038,9 @@ pgws_ExecutorRun(QueryDesc *queryDesc,
9911038
ScanDirection direction,
9921039
uint64 count, bool execute_once)
9931040
{
1041+
int i = MyProc - ProcGlobal->allProcs;
1042+
uint64 save_queryId = pgws_proc_queryids[i];
1043+
9941044
nesting_level++;
9951045
PG_TRY();
9961046
{
@@ -999,10 +1049,18 @@ pgws_ExecutorRun(QueryDesc *queryDesc,
9991049
else
10001050
standard_ExecutorRun(queryDesc, direction, count, execute_once);
10011051
nesting_level--;
1052+
if (nesting_level == 0)
1053+
pgws_proc_queryids[i] = UINT64CONST(0);
1054+
else
1055+
pgws_proc_queryids[i] = save_queryId;
10021056
}
10031057
PG_CATCH();
10041058
{
10051059
nesting_level--;
1060+
if (nesting_level == 0)
1061+
pgws_proc_queryids[i] = UINT64CONST(0);
1062+
else
1063+
pgws_proc_queryids[i] = save_queryId;
10061064
PG_RE_THROW();
10071065
}
10081066
PG_END_TRY();
@@ -1011,6 +1069,9 @@ pgws_ExecutorRun(QueryDesc *queryDesc,
10111069
static void
10121070
pgws_ExecutorFinish(QueryDesc *queryDesc)
10131071
{
1072+
int i = MyProc - ProcGlobal->allProcs;
1073+
uint64 save_queryId = pgws_proc_queryids[i];
1074+
10141075
nesting_level++;
10151076
PG_TRY();
10161077
{
@@ -1019,10 +1080,15 @@ pgws_ExecutorFinish(QueryDesc *queryDesc)
10191080
else
10201081
standard_ExecutorFinish(queryDesc);
10211082
nesting_level--;
1083+
if (nesting_level == 0)
1084+
pgws_proc_queryids[i] = UINT64CONST(0);
1085+
else
1086+
pgws_proc_queryids[i] = save_queryId;
10221087
}
10231088
PG_CATCH();
10241089
{
10251090
nesting_level--;
1091+
pgws_proc_queryids[i] = save_queryId;
10261092
PG_RE_THROW();
10271093
}
10281094
PG_END_TRY();
@@ -1061,10 +1127,14 @@ pgws_ProcessUtility(PlannedStmt *pstmt,
10611127
#endif
10621128
)
10631129
{
1064-
int i = MyProc - ProcGlobal->allProcs;
1130+
int i = MyProc - ProcGlobal->allProcs;
1131+
uint64 save_queryId = 0;
10651132

1066-
if (nesting_level == 0)
1133+
if (pgws_enabled(nesting_level))
1134+
{
1135+
save_queryId = pgws_proc_queryids[i];
10671136
pgws_proc_queryids[i] = pstmt->queryId;
1137+
}
10681138

10691139
nesting_level++;
10701140
PG_TRY();
@@ -1098,12 +1168,16 @@ pgws_ProcessUtility(PlannedStmt *pstmt,
10981168
nesting_level--;
10991169
if (nesting_level == 0)
11001170
pgws_proc_queryids[i] = UINT64CONST(0);
1171+
else if (pgws_enabled(nesting_level))
1172+
pgws_proc_queryids[i] = save_queryId;
11011173
}
11021174
PG_CATCH();
11031175
{
11041176
nesting_level--;
11051177
if (nesting_level == 0)
11061178
pgws_proc_queryids[i] = UINT64CONST(0);
1179+
else if (pgws_enabled(nesting_level))
1180+
pgws_proc_queryids[i] = save_queryId;
11071181
PG_RE_THROW();
11081182
}
11091183
PG_END_TRY();

Diff for: pg_wait_sampling.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ typedef struct
6262
int historyPeriod;
6363
int profilePeriod;
6464
bool profilePid;
65-
bool profileQueries;
65+
int profileQueries;
6666
bool sampleCpu;
6767
} CollectorShmqHeader;
6868

0 commit comments

Comments
 (0)