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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy