Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit12c0f7d

Browse files
authored
Track on CPU events too (#74)
To not count dead backends as still running on the CPU we need todetect that the backend is dead. Starting from PG17 proc->pid is resetin ProcKill, before this we can check if the process latch is disowned.Not nice to be poking around in latch internals like this, but allalternatives seem to involve scanning bestatus array and correlatingpids.Also makes sense to exclude ourselves as we will always be on CPU whilelooking at wait events.Add a GUC for controlling whether on CPU events are counted.
1 parent3fdca70 commit12c0f7d

File tree

4 files changed

+60
-20
lines changed

4 files changed

+60
-20
lines changed

‎README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,14 @@ in-memory hash table.
133133
The work of wait event statistics collector worker is controlled by following
134134
GUCs.
135135

136-
| Parameter name| Data type| Description| Default value|
137-
| -----------------------------------| ---------| -------------------------------------------| ------------:|
138-
| pg_wait_sampling.history_size| int4| Size of history in-memory ring buffer| 5000|
139-
| pg_wait_sampling.history_period| int4| Period for history sampling in milliseconds| 10|
140-
| pg_wait_sampling.profile_period| int4| Period for profile sampling in milliseconds| 10|
141-
| 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|
136+
| Parameter name| Data type| Description| Default value|
137+
|----------------------------------| ---------|---------------------------------------------|--------------:|
138+
| pg_wait_sampling.history_size| int4| Size of history in-memory ring buffer| 5000|
139+
| pg_wait_sampling.history_period| int4| Period for history sampling in milliseconds| 10|
140+
| pg_wait_sampling.profile_period| int4| Period for profile sampling in milliseconds| 10|
141+
| 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|
143+
| pg_wait_sampling.sample_cpu| bool| Whether on CPU backends should be sampled| true|
143144

144145
If`pg_wait_sampling.profile_pid` is set to false, sampling profile wouldn't be
145146
collected in per-process manner. In this case the value of pid could would
@@ -148,6 +149,10 @@ be always zero and corresponding row contain samples among all the processes.
148149
While`pg_wait_sampling.profile_queries` is set to false`queryid` field in
149150
views will be zero.
150151

152+
If`pg_wait_sampling.sample_cpu` is set to true then processes that are not
153+
waiting on anything are also sampled. The wait event columns for such processes
154+
will be NULL.
155+
151156
These GUCs are allowed to be changed by superuser. Also, they are placed into
152157
shared memory. Thus, they could be changed from any backend and affects worker
153158
runtime.

‎collector.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,7 @@ probe_waits(History *observations, HTAB *profile_hash,
163163
*observation;
164164
PGPROC*proc=&ProcGlobal->allProcs[i];
165165

166-
if (proc->pid==0)
167-
continue;
168-
169-
if (proc->wait_event_info==0)
166+
if (!pgws_should_sample_proc(proc))
170167
continue;
171168

172169
/* Collect next wait event sample */

‎pg_wait_sampling.c

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ setup_gucs()
203203
history_period_found= false,
204204
profile_period_found= false,
205205
profile_pid_found= false,
206-
profile_queries_found= false;
206+
profile_queries_found= false,
207+
sample_cpu_found= false;
207208

208209
get_guc_variables_compat(&guc_vars,&numOpts);
209210

@@ -245,6 +246,12 @@ setup_gucs()
245246
var->_bool.variable=&pgws_collector_hdr->profileQueries;
246247
pgws_collector_hdr->profileQueries= true;
247248
}
249+
elseif (!strcmp(name,"pg_wait_sampling.sample_cpu"))
250+
{
251+
sample_cpu_found= true;
252+
var->_bool.variable=&pgws_collector_hdr->sampleCpu;
253+
pgws_collector_hdr->sampleCpu= true;
254+
}
248255
}
249256

250257
if (!history_size_found)
@@ -277,11 +284,18 @@ setup_gucs()
277284
&pgws_collector_hdr->profileQueries, true,
278285
PGC_SUSET,0,shmem_bool_guc_check_hook,NULL,NULL);
279286

287+
if (!sample_cpu_found)
288+
DefineCustomBoolVariable("pg_wait_sampling.sample_cpu",
289+
"Sets whether not waiting backends should be sampled.",NULL,
290+
&pgws_collector_hdr->sampleCpu, true,
291+
PGC_SUSET,0,shmem_bool_guc_check_hook,NULL,NULL);
292+
280293
if (history_size_found
281294
||history_period_found
282295
||profile_period_found
283296
||profile_pid_found
284-
||profile_queries_found)
297+
||profile_queries_found
298+
||sample_cpu_found)
285299
{
286300
ProcessConfigFile(PGC_SIGHUP);
287301
}
@@ -438,6 +452,28 @@ search_proc(int pid)
438452
returnNULL;
439453
}
440454

455+
/*
456+
* Decide whether this PGPROC entry should be included in profiles and output
457+
* views.
458+
*/
459+
bool
460+
pgws_should_sample_proc(PGPROC*proc)
461+
{
462+
if (proc->wait_event_info==0&& !pgws_collector_hdr->sampleCpu)
463+
return false;
464+
465+
/*
466+
* On PostgreSQL versions < 17 the PGPROC->pid field is not reset on
467+
* process exit. This would lead to such processes getting counted for
468+
* null wait events. So instead we make use of DisownLatch() resetting
469+
* owner_pid during ProcKill().
470+
*/
471+
if (proc->pid==0||proc->procLatch.owner_pid==0||proc->pid==MyProcPid)
472+
return false;
473+
474+
return true;
475+
}
476+
441477
typedefstruct
442478
{
443479
HistoryItem*items;
@@ -503,13 +539,13 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
503539
{
504540
PGPROC*proc=&ProcGlobal->allProcs[i];
505541

506-
if (proc!=NULL&&proc->pid!=0&&proc->wait_event_info)
507-
{
508-
params->items[j].pid=proc->pid;
509-
params->items[j].wait_event_info=proc->wait_event_info;
510-
params->items[j].queryId=pgws_proc_queryids[i];
511-
j++;
512-
}
542+
if (!pgws_should_sample_proc(proc))
543+
continue;
544+
545+
params->items[j].pid=proc->pid;
546+
params->items[j].wait_event_info=proc->wait_event_info;
547+
params->items[j].queryId=pgws_proc_queryids[i];
548+
j++;
513549
}
514550
funcctx->max_calls=j;
515551
}

‎pg_wait_sampling.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ typedef struct
6363
intprofilePeriod;
6464
boolprofilePid;
6565
boolprofileQueries;
66+
boolsampleCpu;
6667
}CollectorShmqHeader;
6768

6869
/* pg_wait_sampling.c */
6970
externCollectorShmqHeader*pgws_collector_hdr;
7071
externshm_mq*pgws_collector_mq;
7172
externuint64*pgws_proc_queryids;
7273
externvoidpgws_init_lock_tag(LOCKTAG*tag,uint32lock);
74+
externboolpgws_should_sample_proc(PGPROC*proc);
7375

7476
/* collector.c */
7577
externvoidpgws_register_wait_collector(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp