@@ -149,6 +149,111 @@ get_next_observation(History *observations)
149
149
return result ;
150
150
}
151
151
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
+
152
257
/*
153
258
* Read current waits from backends and write them to history array
154
259
* and/or profile hash.
@@ -176,92 +281,34 @@ probe_waits(History *observations, HTAB *profile_hash,
176
281
PGPROC * proc = & ProcGlobal -> allProcs [i ];
177
282
int pid ;
178
283
uint32 wait_event_info ;
284
+ SamplingDimensions common_dimensions ;
285
+ int dimensions_mask_common = pgws_history_dimensions |
286
+ pgws_profile_dimensions ;
179
287
180
288
/* Check if we need to sample this process */
181
289
if (!pgws_should_sample_proc (proc ,& pid ,& wait_event_info ))
182
290
continue ;
183
291
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
+ */
185
296
memset (& item_history ,0 ,sizeof (HistoryItem ));
186
297
memset (& item_profile ,0 ,sizeof (ProfileItem ));
298
+ memset (& common_dimensions ,0 ,sizeof (SamplingDimensions ));
187
299
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 ) ;
190
302
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 );
199
309
200
310
item_history .ts = ts ;
201
311
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
-
265
312
/* Write to the history if needed */
266
313
if (write_history )
267
314
{
@@ -276,9 +323,10 @@ probe_waits(History *observations, HTAB *profile_hash,
276
323
bool found ;
277
324
278
325
if (!profile_pid )
279
- item_profile .pid = 0 ;
326
+ item_profile .dimensions . pid = 0 ;
280
327
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 );
282
330
if (found )
283
331
profileItem -> count ++ ;
284
332
else
@@ -379,11 +427,11 @@ make_profile_hash()
379
427
HASHCTL hash_ctl ;
380
428
381
429
/*
382
- * Since adding additional dimensions weinclude everyting except count
383
- *into hashtable key. This is fine for cases when some fields are 0 since
430
+ * Since adding additional dimensions weuse SamplingDimensions as
431
+ * hashtable key. This is fine for cases when some fields are 0 since
384
432
* it doesn't impede our ability to search the hash table for entries
385
433
*/
386
- hash_ctl .keysize = offsetof( ProfileItem , count );
434
+ hash_ctl .keysize = sizeof ( SamplingDimensions );
387
435
388
436
hash_ctl .entrysize = sizeof (ProfileItem );
389
437
return hash_create ("Waits profile hash" ,1024 ,& hash_ctl ,