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

Commit6cd4efa

Browse files
Oleg TselebrovskiyMedvecrab
Oleg Tselebrovskiy
authored andcommitted
Add profile_extended and history_extended views with additional dimensions
Sometimes it can be useful to have additional info collected with wait_events,so we add two new views/functions that include more information. The structure ofthose views could be changed in new versions of pg_wait_sampling extension
1 parent8427f4a commit6cd4efa

File tree

9 files changed

+1067
-23
lines changed

9 files changed

+1067
-23
lines changed

‎Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ MODULE_big = pg_wait_sampling
44
OBJS = pg_wait_sampling.o collector.o
55

66
EXTENSION = pg_wait_sampling
7-
DATA = pg_wait_sampling--1.1.sql pg_wait_sampling--1.0--1.1.sql
7+
DATA = pg_wait_sampling--1.1.sql pg_wait_sampling--1.0--1.1.sql pg_wait_sampling--1.1--1.2.sql
88

99
REGRESS = load queries
1010

‎collector.c

Lines changed: 106 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include"postgres.h"
1111

1212
#include<signal.h>
13+
#include<time.h>
1314

1415
#include"compat.h"
1516
#include"miscadmin.h"
@@ -30,6 +31,13 @@
3031
#include"utils/resowner.h"
3132
#include"utils/timestamp.h"
3233

34+
#definecheck_bestatus_dimensions(dimensions) \
35+
(dimensions & (PGWS_DIMENSIONS_BE_TYPE |\
36+
PGWS_DIMENSIONS_BE_STATE |\
37+
PGWS_DIMENSIONS_BE_START_TIME |\
38+
PGWS_DIMENSIONS_CLIENT_ADDR |\
39+
PGWS_DIMENSIONS_CLIENT_HOSTNAME |\
40+
PGWS_DIMENSIONS_APPNAME))
3341
staticvolatilesig_atomic_tshutdown_requested= false;
3442

3543
staticvoidhandle_sigterm(SIGNAL_ARGS);
@@ -162,25 +170,103 @@ probe_waits(History *observations, HTAB *profile_hash,
162170
LWLockAcquire(ProcArrayLock,LW_SHARED);
163171
for (i=0;i<ProcGlobal->allProcCount;i++)
164172
{
165-
HistoryItemitem,
173+
HistoryItemitem_history,
166174
*observation;
175+
ProfileItemitem_profile;
167176
PGPROC*proc=&ProcGlobal->allProcs[i];
177+
intpid;
178+
uint32wait_event_info;
168179

169-
if (!pgws_should_sample_proc(proc,&item.pid,&item.wait_event_info))
180+
/* Check if we need to sample this process */
181+
if (!pgws_should_sample_proc(proc,&pid,&wait_event_info))
170182
continue;
171183

184+
/* We zero whole HistoryItem to avoid doing it field-by-field */
185+
memset(&item_history,0,sizeof(HistoryItem));
186+
memset(&item_profile,0,sizeof(ProfileItem));
187+
188+
item_history.pid=pid;
189+
item_profile.pid=pid;
190+
191+
item_history.wait_event_info=wait_event_info;
192+
item_profile.wait_event_info=wait_event_info;
193+
172194
if (pgws_profileQueries)
173-
item.queryId=pgws_proc_queryids[i];
174-
else
175-
item.queryId=0;
195+
{
196+
item_history.queryId=pgws_proc_queryids[i];
197+
item_profile.queryId=pgws_proc_queryids[i];
198+
}
176199

177-
item.ts=ts;
200+
item_history.ts=ts;
201+
202+
/* Copy everything we need from PGPROC */
203+
if (pgws_history_dimensions&PGWS_DIMENSIONS_ROLE_ID)
204+
item_history.role_id=proc->roleId;
205+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_ROLE_ID)
206+
item_profile.role_id=proc->roleId;
207+
208+
if (pgws_history_dimensions&PGWS_DIMENSIONS_DB_ID)
209+
item_history.database_id=proc->databaseId;
210+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_DB_ID)
211+
item_profile.database_id=proc->databaseId;
212+
213+
if (pgws_history_dimensions&PGWS_DIMENSIONS_PARALLEL_LEADER_PID)
214+
item_history.parallel_leader_pid= (proc->lockGroupLeader ?
215+
proc->lockGroupLeader->pid :
216+
0);
217+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_PARALLEL_LEADER_PID)
218+
item_profile.parallel_leader_pid= (proc->lockGroupLeader ?
219+
proc->lockGroupLeader->pid :
220+
0);
221+
/* Look into BackendStatus only if necessary */
222+
if (check_bestatus_dimensions(pgws_history_dimensions)||
223+
check_bestatus_dimensions(pgws_profile_dimensions))
224+
{
225+
#ifPG_VERSION_NUM >=170000
226+
PgBackendStatus*bestatus=pgstat_get_beentry_by_proc_number(GetNumberFromPGProc(proc));
227+
#else
228+
PgBackendStatus*bestatus=get_beentry_by_procpid(proc->pid);
229+
#endif
230+
/* Copy everything we need from BackendStatus */
231+
if (bestatus)
232+
{
233+
if (pgws_history_dimensions&PGWS_DIMENSIONS_BE_TYPE)
234+
item_history.backend_type=bestatus->st_backendType;
235+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_BE_TYPE)
236+
item_profile.backend_type=bestatus->st_backendType;
237+
238+
if (pgws_history_dimensions&PGWS_DIMENSIONS_BE_STATE)
239+
item_history.backend_state=bestatus->st_state;
240+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_BE_STATE)
241+
item_profile.backend_state=bestatus->st_state;
242+
243+
if (pgws_history_dimensions&PGWS_DIMENSIONS_BE_START_TIME)
244+
item_history.proc_start=bestatus->st_proc_start_timestamp;
245+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_BE_START_TIME)
246+
item_profile.proc_start=bestatus->st_proc_start_timestamp;
247+
248+
if (pgws_history_dimensions&PGWS_DIMENSIONS_CLIENT_ADDR)
249+
item_history.client_addr=bestatus->st_clientaddr;
250+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_CLIENT_ADDR)
251+
item_profile.client_addr=bestatus->st_clientaddr;
252+
253+
if (pgws_history_dimensions&PGWS_DIMENSIONS_CLIENT_HOSTNAME)
254+
strcpy(item_history.client_hostname,bestatus->st_clienthostname);
255+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_CLIENT_HOSTNAME)
256+
strcpy(item_profile.client_hostname,bestatus->st_clienthostname);
257+
258+
if (pgws_history_dimensions&PGWS_DIMENSIONS_APPNAME)
259+
strcpy(item_history.appname,bestatus->st_appname);
260+
if (pgws_profile_dimensions&PGWS_DIMENSIONS_APPNAME)
261+
strcpy(item_profile.appname,bestatus->st_appname);
262+
}
263+
}
178264

179265
/* Write to the history if needed */
180266
if (write_history)
181267
{
182268
observation=get_next_observation(observations);
183-
*observation=item;
269+
*observation=item_history;
184270
}
185271

186272
/* Write to the profile if needed */
@@ -190,16 +276,21 @@ probe_waits(History *observations, HTAB *profile_hash,
190276
boolfound;
191277

192278
if (!profile_pid)
193-
item.pid=0;
279+
item_profile.pid=0;
194280

195-
profileItem= (ProfileItem*)hash_search(profile_hash,&item,HASH_ENTER,&found);
281+
profileItem= (ProfileItem*)hash_search(profile_hash,&item_profile,HASH_ENTER,&found);
196282
if (found)
197283
profileItem->count++;
198284
else
199285
profileItem->count=1;
200286
}
201287
}
202288
LWLockRelease(ProcArrayLock);
289+
#ifPG_VERSION_NUM >=140000
290+
pgstat_clear_backend_activity_snapshot();
291+
#else
292+
pgstat_clear_snapshot();
293+
#endif
203294
}
204295

205296
/*
@@ -287,10 +378,12 @@ make_profile_hash()
287378
{
288379
HASHCTLhash_ctl;
289380

290-
if (pgws_profileQueries)
291-
hash_ctl.keysize= offsetof(ProfileItem,count);
292-
else
293-
hash_ctl.keysize= offsetof(ProfileItem,queryId);
381+
/*
382+
* Since adding additional dimensions we include everyting except count
383+
* into hashtable key. This is fine for cases when some fields are 0 since
384+
* it doesn't impede our ability to search the hash table for entries
385+
*/
386+
hash_ctl.keysize= offsetof(ProfileItem,count);
294387

295388
hash_ctl.entrysize=sizeof(ProfileItem);
296389
returnhash_create("Waits profile hash",1024,&hash_ctl,

‎expected/queries.out

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@ WITH t as (SELECT sum(0) FROM pg_wait_sampling_profile)
2020
0
2121
(1 row)
2222

23+
WITH t as (SELECT sum(0) FROM pg_wait_sampling_current_extended)
24+
SELECT sum(0) FROM generate_series(1, 2), t;
25+
sum
26+
-----
27+
0
28+
(1 row)
29+
30+
WITH t as (SELECT sum(0) FROM pg_wait_sampling_history_extended)
31+
SELECT sum(0) FROM generate_series(1, 2), t;
32+
sum
33+
-----
34+
0
35+
(1 row)
36+
37+
WITH t as (SELECT sum(0) FROM pg_wait_sampling_profile_extended)
38+
SELECT sum(0) FROM generate_series(1, 2), t;
39+
sum
40+
-----
41+
0
42+
(1 row)
43+
2344
-- Some dummy checks just to be sure that all our functions work and return something.
2445
SELECT count(*) = 1 as test FROM pg_wait_sampling_get_current(pg_backend_pid());
2546
test
@@ -45,4 +66,28 @@ SELECT pg_wait_sampling_reset_profile();
4566

4667
(1 row)
4768

69+
SELECT count(*) = 1 as test FROM pg_wait_sampling_get_current_extended(pg_backend_pid());
70+
test
71+
------
72+
t
73+
(1 row)
74+
75+
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_profile_extended();
76+
test
77+
------
78+
t
79+
(1 row)
80+
81+
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_history_extended();
82+
test
83+
------
84+
t
85+
(1 row)
86+
87+
SELECT pg_wait_sampling_reset_profile();
88+
pg_wait_sampling_reset_profile
89+
--------------------------------
90+
91+
(1 row)
92+
4893
DROP EXTENSION pg_wait_sampling;

‎meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ install_data(
2424
'pg_wait_sampling.control',
2525
'pg_wait_sampling--1.0--1.1.sql',
2626
'pg_wait_sampling--1.1.sql',
27+
'pg_wait_sampling--1.1--1.2.sql',
2728
kwargs: contrib_data_args,
2829
)
2930

‎pg_wait_sampling--1.1--1.2.sql

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/* contrib/pg_wait_sampling/pg_wait_sampling--1.1--1.2.sql*/
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use"ALTER EXTENSION pg_wait_sampling UPDATE TO 1.2" to load this file. \quit
5+
6+
CREATEFUNCTIONpg_wait_sampling_get_current_extended (
7+
pid int4,
8+
OUT pid int4,
9+
OUT event_typetext,
10+
OUT eventtext,
11+
OUT queryid int8,
12+
OUT role_id int8,
13+
OUT database_id int8,
14+
OUT parallel_leader_pid int4,
15+
OUT backend_typetext,
16+
OUT backend_statetext,
17+
OUT proc_starttimestamptz,
18+
OUT client_addrtext,
19+
OUT client_hostnametext,
20+
OUT appnametext
21+
)
22+
RETURNS SETOF record
23+
AS'MODULE_PATHNAME'
24+
LANGUAGE C VOLATILE CALLEDONNULL INPUT;
25+
26+
CREATEVIEWpg_wait_sampling_current_extendedAS
27+
SELECT*FROM pg_wait_sampling_get_current_extended(NULL::integer);
28+
29+
GRANTSELECTON pg_wait_sampling_current TO PUBLIC;
30+
31+
CREATEFUNCTIONpg_wait_sampling_get_history_extended (
32+
OUT pid int4,
33+
OUT tstimestamptz,
34+
OUT event_typetext,
35+
OUT eventtext,
36+
OUT queryid int8,
37+
OUT role_id int8,
38+
OUT database_id int8,
39+
OUT parallel_leader_pid int4,
40+
OUT backend_typetext,
41+
OUT backend_statetext,
42+
OUT proc_starttimestamptz,
43+
OUT client_addrtext,
44+
OUT client_hostnametext,
45+
OUT appnametext
46+
)
47+
RETURNS SETOF record
48+
AS'MODULE_PATHNAME'
49+
LANGUAGE C VOLATILE STRICT;
50+
51+
CREATEVIEWpg_wait_sampling_history_extendedAS
52+
SELECT*FROM pg_wait_sampling_get_history_extended();
53+
54+
GRANTSELECTON pg_wait_sampling_history_extended TO PUBLIC;
55+
56+
CREATEFUNCTIONpg_wait_sampling_get_profile_extended (
57+
OUT pid int4,
58+
OUT event_typetext,
59+
OUT eventtext,
60+
OUT queryid int8,
61+
OUT role_id int8,
62+
OUT database_id int8,
63+
OUT parallel_leader_pid int4,
64+
OUT backend_typetext,
65+
OUT backend_statetext,
66+
OUT proc_starttimestamptz,
67+
OUT client_addrtext,
68+
OUT client_hostnametext,
69+
OUT appnametext,
70+
OUT count int8
71+
)
72+
RETURNS SETOF record
73+
AS'MODULE_PATHNAME'
74+
LANGUAGE C VOLATILE STRICT;
75+
76+
CREATEVIEWpg_wait_sampling_profile_extendedAS
77+
SELECT*FROM pg_wait_sampling_get_profile_extended();
78+
79+
GRANTSELECTON pg_wait_sampling_profile_extended TO PUBLIC;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp