Skip to content

Commit f0ee939

Browse files
committed
Fixes after review
1 parent 9208eb2 commit f0ee939

File tree

4 files changed

+322
-254
lines changed

4 files changed

+322
-254
lines changed

collector.c

Lines changed: 127 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,111 @@ get_next_observation(History *observations)
149149
return result;
150150
}
151151

152+
static void
153+
fill_dimensions(SamplingDimensions *dimensions, PGPROC *proc,
154+
int pid, uint32 wait_event_info, uint64 queryId,
155+
int dimensions_mask)
156+
{
157+
Oid role_id = proc->roleId;
158+
Oid database_id = proc->databaseId;
159+
PGPROC *lockGroupLeader = proc->lockGroupLeader;
160+
bool is_regular_backend = proc->isRegularBackend;
161+
162+
dimensions->pid = pid;
163+
164+
dimensions->wait_event_info = wait_event_info;
165+
166+
if (pgws_profileQueries)
167+
dimensions->queryId = queryId;
168+
169+
/* Copy everything we need from PGPROC */
170+
if (dimensions_mask & PGWS_DIMENSIONS_ROLE_ID)
171+
dimensions->role_id = role_id;
172+
173+
if (dimensions_mask & PGWS_DIMENSIONS_DB_ID)
174+
dimensions->database_id = database_id;
175+
176+
if (dimensions_mask & PGWS_DIMENSIONS_PARALLEL_LEADER_PID)
177+
dimensions->parallel_leader_pid = (lockGroupLeader ?
178+
lockGroupLeader->pid :
179+
0);
180+
181+
if (dimensions_mask & PGWS_DIMENSIONS_IS_REGULAR_BE)
182+
dimensions->is_regular_backend = is_regular_backend;
183+
184+
/* Look into BackendStatus only if necessary */
185+
if (check_bestatus_dimensions(dimensions_mask))
186+
{
187+
#if PG_VERSION_NUM >= 170000
188+
PgBackendStatus *bestatus = pgstat_get_beentry_by_proc_number(GetNumberFromPGProc(proc));
189+
#else
190+
PgBackendStatus *bestatus = get_beentry_by_procpid(proc->pid);
191+
#endif
192+
/* Copy everything we need from BackendStatus */
193+
if (bestatus)
194+
{
195+
if (dimensions_mask & PGWS_DIMENSIONS_BE_TYPE)
196+
dimensions->backend_type = bestatus->st_backendType;
197+
198+
if (dimensions_mask & PGWS_DIMENSIONS_BE_STATE)
199+
dimensions->backend_state = bestatus->st_state;
200+
201+
if (dimensions_mask & PGWS_DIMENSIONS_BE_START_TIME)
202+
dimensions->proc_start = bestatus->st_proc_start_timestamp;
203+
204+
if (dimensions_mask & PGWS_DIMENSIONS_CLIENT_ADDR)
205+
dimensions->client_addr = bestatus->st_clientaddr;
206+
207+
if (dimensions_mask & PGWS_DIMENSIONS_CLIENT_HOSTNAME)
208+
strcpy(dimensions->client_hostname, bestatus->st_clienthostname);
209+
210+
if (dimensions_mask & PGWS_DIMENSIONS_APPNAME)
211+
strcpy(dimensions->appname, bestatus->st_appname);
212+
}
213+
}
214+
}
215+
216+
static void
217+
copy_dimensions (SamplingDimensions *dst, SamplingDimensions *src,
218+
int dst_dimensions_mask)
219+
{
220+
dst->pid = src->pid;
221+
222+
dst->wait_event_info = src->wait_event_info;
223+
224+
dst->queryId = src->queryId;
225+
226+
if (dst_dimensions_mask & PGWS_DIMENSIONS_ROLE_ID)
227+
dst->role_id = src->role_id;
228+
229+
if (dst_dimensions_mask & PGWS_DIMENSIONS_DB_ID)
230+
dst->database_id = src->database_id;
231+
232+
if (dst_dimensions_mask & PGWS_DIMENSIONS_PARALLEL_LEADER_PID)
233+
dst->parallel_leader_pid = src->parallel_leader_pid;
234+
235+
if (dst_dimensions_mask & PGWS_DIMENSIONS_IS_REGULAR_BE)
236+
dst->is_regular_backend = src->is_regular_backend;
237+
238+
if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_TYPE)
239+
dst->backend_type = src->backend_type;
240+
241+
if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_STATE)
242+
dst->backend_state = src->backend_state;
243+
244+
if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_START_TIME)
245+
dst->proc_start = src->proc_start;
246+
247+
if (dst_dimensions_mask & PGWS_DIMENSIONS_CLIENT_ADDR)
248+
dst->client_addr = src->client_addr;
249+
250+
if (dst_dimensions_mask & PGWS_DIMENSIONS_CLIENT_HOSTNAME)
251+
strcpy(dst->client_hostname, src->client_hostname);
252+
253+
if (dst_dimensions_mask & PGWS_DIMENSIONS_APPNAME)
254+
strcpy(dst->appname, src->appname);
255+
}
256+
152257
/*
153258
* Read current waits from backends and write them to history array
154259
* and/or profile hash.
@@ -176,92 +281,34 @@ probe_waits(History *observations, HTAB *profile_hash,
176281
PGPROC *proc = &ProcGlobal->allProcs[i];
177282
int pid;
178283
uint32 wait_event_info;
284+
SamplingDimensions common_dimensions;
285+
int dimensions_mask_common = pgws_history_dimensions |
286+
pgws_profile_dimensions;
179287

180288
/* Check if we need to sample this process */
181289
if (!pgws_should_sample_proc(proc, &pid, &wait_event_info))
182290
continue;
183291

184-
/* We zero whole HistoryItem to avoid doing it field-by-field */
292+
/*
293+
* We zero items and dimensions with memset
294+
* to avoid doing it field-by-field
295+
*/
185296
memset(&item_history, 0, sizeof(HistoryItem));
186297
memset(&item_profile, 0, sizeof(ProfileItem));
298+
memset(&common_dimensions, 0, sizeof(SamplingDimensions));
187299

188-
item_history.pid = pid;
189-
item_profile.pid = pid;
300+
fill_dimensions(&common_dimensions, proc, pid, wait_event_info,
301+
pgws_proc_queryids[i], dimensions_mask_common);
190302

191-
item_history.wait_event_info = wait_event_info;
192-
item_profile.wait_event_info = wait_event_info;
193-
194-
if (pgws_profileQueries)
195-
{
196-
item_history.queryId = pgws_proc_queryids[i];
197-
item_profile.queryId = pgws_proc_queryids[i];
198-
}
303+
copy_dimensions(&item_history.dimensions,
304+
&common_dimensions,
305+
pgws_history_dimensions);
306+
copy_dimensions(&item_history.dimensions,
307+
&common_dimensions,
308+
pgws_profile_dimensions);
199309

200310
item_history.ts = ts;
201311

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-
#if PG_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-
}
264-
265312
/* Write to the history if needed */
266313
if (write_history)
267314
{
@@ -276,9 +323,10 @@ probe_waits(History *observations, HTAB *profile_hash,
276323
bool found;
277324

278325
if (!profile_pid)
279-
item_profile.pid = 0;
326+
item_profile.dimensions.pid = 0;
280327

281-
profileItem = (ProfileItem *) hash_search(profile_hash, &item_profile, HASH_ENTER, &found);
328+
profileItem = (ProfileItem *) hash_search(profile_hash, &item_profile,
329+
HASH_ENTER, &found);
282330
if (found)
283331
profileItem->count++;
284332
else
@@ -379,11 +427,11 @@ make_profile_hash()
379427
HASHCTL hash_ctl;
380428

381429
/*
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
430+
* Since adding additional dimensions we use SamplingDimensions as
431+
* hashtable key. This is fine for cases when some fields are 0 since
384432
* it doesn't impede our ability to search the hash table for entries
385433
*/
386-
hash_ctl.keysize = offsetof(ProfileItem, count);
434+
hash_ctl.keysize = sizeof(SamplingDimensions);
387435

388436
hash_ctl.entrysize = sizeof(ProfileItem);
389437
return hash_create("Waits profile hash", 1024, &hash_ctl,

pg_wait_sampling--1.1--1.2.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
44
\echo Use "ALTER EXTENSION pg_wait_sampling UPDATE TO 1.2" to load this file. \quit
55

6+
DROP FUNCTION pg_wait_sampling_get_profile (
7+
OUT pid int4,
8+
OUT event_type text,
9+
OUT event text,
10+
OUT count bigint
11+
) CASCADE;
12+
613
CREATE FUNCTION pg_wait_sampling_get_current_extended (
714
pid int4,
815
OUT pid int4,
@@ -12,6 +19,7 @@ CREATE FUNCTION pg_wait_sampling_get_current_extended (
1219
OUT role_id int8,
1320
OUT database_id int8,
1421
OUT parallel_leader_pid int4,
22+
OUT is_regular_backend bool,
1523
OUT backend_type text,
1624
OUT backend_state text,
1725
OUT proc_start timestamptz,
@@ -37,6 +45,7 @@ CREATE FUNCTION pg_wait_sampling_get_history_extended (
3745
OUT role_id int8,
3846
OUT database_id int8,
3947
OUT parallel_leader_pid int4,
48+
OUT is_regular_backend bool,
4049
OUT backend_type text,
4150
OUT backend_state text,
4251
OUT proc_start timestamptz,
@@ -61,6 +70,7 @@ CREATE FUNCTION pg_wait_sampling_get_profile_extended (
6170
OUT role_id int8,
6271
OUT database_id int8,
6372
OUT parallel_leader_pid int4,
73+
OUT is_regular_backend bool,
6474
OUT backend_type text,
6575
OUT backend_state text,
6676
OUT proc_start timestamptz,
@@ -77,3 +87,10 @@ CREATE VIEW pg_wait_sampling_profile_extended AS
7787
SELECT * FROM pg_wait_sampling_get_profile_extended();
7888

7989
GRANT SELECT ON pg_wait_sampling_profile_extended TO PUBLIC;
90+
91+
CREATE VIEW pg_wait_sampling_profile AS
92+
SELECT pid, event_type, event, queryid, SUM(count) FROM pg_wait_sampling_profile_extended
93+
GROUP BY pid, event_type, event, queryid;
94+
95+
GRANT SELECT ON pg_wait_sampling_profile TO PUBLIC;
96+

0 commit comments

Comments
 (0)