3232
3333static volatile sig_atomic_t shutdown_requested = false;
3434
35+ int saved_profile_dimensions ;
36+ int saved_history_dimensions ;
37+
3538static void handle_sigterm (SIGNAL_ARGS );
3639
3740/*
@@ -61,7 +64,8 @@ pgws_register_wait_collector(void)
6164static void
6265alloc_history (History * observations , int count )
6366{
64- observations -> items = (HistoryItem * ) palloc0 (sizeof (HistoryItem ) * count );
67+ saved_history_dimensions = pgws_history_dimensions ;
68+ observations -> samples = (Sample * ) palloc0 (sizeof (Sample ) * count );
6569 observations -> index = 0 ;
6670 observations -> count = count ;
6771 observations -> wraparound = false;
@@ -73,13 +77,13 @@ alloc_history(History *observations, int count)
7377static void
7478realloc_history (History * observations , int count )
7579{
76- HistoryItem * newitems ;
80+ Sample * newitems ;
7781 int copyCount ,
7882 i ,
7983 j ;
8084
8185 /* Allocate new array for history */
82- newitems = (HistoryItem * ) palloc0 (sizeof (HistoryItem ) * count );
86+ newitems = (Sample * ) palloc0 (sizeof (Sample ) * count );
8387
8488 /* Copy entries from old array to the new */
8589 if (observations -> wraparound )
@@ -98,14 +102,14 @@ realloc_history(History *observations, int count)
98102 {
99103 if (j >= observations -> count )
100104 j = 0 ;
101- memcpy (& newitems [i ], & observations -> items [j ], sizeof (HistoryItem ));
105+ memcpy (& newitems [i ], & observations -> samples [j ], sizeof (Sample ));
102106 i ++ ;
103107 j ++ ;
104108 }
105109
106110 /* Switch to new history array */
107- pfree (observations -> items );
108- observations -> items = newitems ;
111+ pfree (observations -> samples );
112+ observations -> samples = newitems ;
109113 observations -> index = copyCount ;
110114 observations -> count = count ;
111115 observations -> wraparound = false;
@@ -125,22 +129,55 @@ handle_sigterm(SIGNAL_ARGS)
125129/*
126130 * Get next item of history with rotation.
127131 */
128- static HistoryItem *
132+ static Sample *
129133get_next_observation (History * observations )
130134{
131- HistoryItem * result ;
135+ Sample * result ;
132136
133137 /* Check for wraparound */
134138 if (observations -> index >= observations -> count )
135139 {
136140 observations -> index = 0 ;
137141 observations -> wraparound = true;
138142 }
139- result = & observations -> items [observations -> index ];
143+ result = & observations -> samples [observations -> index ];
140144 observations -> index ++ ;
141145 return result ;
142146}
143147
148+ void
149+ fill_sample (Sample * sample , PGPROC * proc , int pid , uint32 wait_event_info ,
150+ uint64 queryId , int dimensions_mask )
151+ {
152+ Oid role_id = proc -> roleId ;
153+ Oid database_id = proc -> databaseId ;
154+ PGPROC * lockGroupLeader = proc -> lockGroupLeader ;
155+ #if PG_VERSION_NUM >= 180000
156+ bool is_regular_backend = proc -> isRegularBackend ;
157+ #else
158+ bool is_regular_backend = !proc -> isBackgroundWorker ;
159+ #endif
160+
161+ if (dimensions_mask & PGWS_DIMENSIONS_PID )
162+ sample -> pid = pid ;
163+ if (dimensions_mask & PGWS_DIMENSIONS_WAIT_EVENT )
164+ sample -> wait_event_info = wait_event_info ;
165+ if (pgws_profileQueries || (dimensions_mask & PGWD_DIMENSIONS_QUERY_ID ))
166+ sample -> queryId = queryId ;
167+ /* Copy everything else we need from PGPROC */
168+ if (dimensions_mask & PGWS_DIMENSIONS_ROLE_ID )
169+ sample -> role_id = role_id ;
170+ if (dimensions_mask & PGWS_DIMENSIONS_DB_ID )
171+ sample -> database_id = database_id ;
172+ if (dimensions_mask & PGWS_DIMENSIONS_PARALLEL_LEADER_PID )
173+ sample -> parallel_leader_pid = (lockGroupLeader &&
174+ lockGroupLeader -> pid != pid ?
175+ lockGroupLeader -> pid :
176+ 0 );
177+ if (dimensions_mask & PGWS_DIMENSIONS_IS_REGULAR_BE )
178+ sample -> is_regular_backend = is_regular_backend ;
179+ }
180+
144181/*
145182 * Read current waits from backends and write them to history array
146183 * and/or profile hash.
@@ -162,37 +199,38 @@ probe_waits(History *observations, HTAB *profile_hash,
162199 LWLockAcquire (ProcArrayLock , LW_SHARED );
163200 for (i = 0 ; i < ProcGlobal -> allProcCount ; i ++ )
164201 {
165- HistoryItem item ,
166- * observation ;
167- PGPROC * proc = & ProcGlobal -> allProcs [i ];
202+ /* We do not copy PGPROC since it is very big */
203+ PGPROC * proc = & ProcGlobal -> allProcs [i ];
204+ int pid ;
205+ uint32 wait_event_info ;
168206
169- if (!pgws_should_sample_proc (proc , & item . pid , & item . wait_event_info ))
207+ if (!pgws_should_sample_proc (proc , & pid , & wait_event_info ))
170208 continue ;
171209
172- if (pgws_profileQueries )
173- item .queryId = pgws_proc_queryids [i ];
174- else
175- item .queryId = 0 ;
176-
177- item .ts = ts ;
178-
179210 /* Write to the history if needed */
180211 if (write_history )
181212 {
182- observation = get_next_observation (observations );
183- * observation = item ;
213+ Sample * observation = get_next_observation (observations );
214+ memset (observation , 0 , sizeof (Sample ));
215+ fill_sample (observation , proc , pid , wait_event_info ,
216+ pgws_proc_queryids [i ], saved_history_dimensions );
217+ observation -> ts = ts ;
184218 }
185219
186220 /* Write to the profile if needed */
187221 if (write_profile )
188222 {
189- ProfileItem * profileItem ;
190- bool found ;
223+ Sample * profileItem ;
224+ Sample key ;
225+ bool found ;
191226
227+ memset (& key , 0 , sizeof (Sample ));
228+ fill_sample (& key , proc , pid , wait_event_info ,
229+ pgws_proc_queryids [i ], saved_profile_dimensions );
192230 if (!profile_pid )
193- item .pid = 0 ;
231+ key .pid = 0 ;
194232
195- profileItem = (ProfileItem * ) hash_search (profile_hash , & item , HASH_ENTER , & found );
233+ profileItem = (Sample * ) hash_search (profile_hash , & key , HASH_ENTER , & found );
196234 if (found )
197235 profileItem -> count ++ ;
198236 else
@@ -229,8 +267,8 @@ send_history(History *observations, shm_mq_handle *mqh)
229267 for (i = 0 ; i < count ; i ++ )
230268 {
231269 mq_result = shm_mq_send_compat (mqh ,
232- sizeof (HistoryItem ),
233- & observations -> items [i ],
270+ sizeof (Sample ),
271+ & observations -> samples [i ],
234272 false,
235273 true);
236274 if (mq_result == SHM_MQ_DETACHED )
@@ -249,10 +287,10 @@ send_history(History *observations, shm_mq_handle *mqh)
249287static void
250288send_profile (HTAB * profile_hash , shm_mq_handle * mqh )
251289{
252- HASH_SEQ_STATUS scan_status ;
253- ProfileItem * item ;
254- Size count = hash_get_num_entries (profile_hash );
255- shm_mq_result mq_result ;
290+ HASH_SEQ_STATUS scan_status ;
291+ Sample * sample ;
292+ Size count = hash_get_num_entries (profile_hash );
293+ shm_mq_result mq_result ;
256294
257295 /* Send array size first since receive_array expects this */
258296 mq_result = shm_mq_send_compat (mqh , sizeof (count ), & count , false, true);
@@ -264,9 +302,9 @@ send_profile(HTAB *profile_hash, shm_mq_handle *mqh)
264302 return ;
265303 }
266304 hash_seq_init (& scan_status , profile_hash );
267- while ((item = (ProfileItem * ) hash_seq_search (& scan_status )) != NULL )
305+ while ((sample = (Sample * ) hash_seq_search (& scan_status )) != NULL )
268306 {
269- mq_result = shm_mq_send_compat (mqh , sizeof (ProfileItem ), item , false,
307+ mq_result = shm_mq_send_compat (mqh , sizeof (Sample ), sample , false,
270308 true);
271309 if (mq_result == SHM_MQ_DETACHED )
272310 {
@@ -287,12 +325,10 @@ make_profile_hash()
287325{
288326 HASHCTL hash_ctl ;
289327
290- if (pgws_profileQueries )
291- hash_ctl .keysize = offsetof(ProfileItem , count );
292- else
293- hash_ctl .keysize = offsetof(ProfileItem , queryId );
294-
295- hash_ctl .entrysize = sizeof (ProfileItem );
328+ saved_profile_dimensions = pgws_profile_dimensions ;
329+ /* Fields that are not in dimensions mask are zero and are included in key */
330+ hash_ctl .keysize = offsetof(Sample , count );
331+ hash_ctl .entrysize = sizeof (Sample );
296332 return hash_create ("Waits profile hash" , 1024 , & hash_ctl ,
297333 HASH_ELEM | HASH_BLOBS );
298334}
@@ -377,6 +413,18 @@ pgws_collector_main(Datum main_arg)
377413 {
378414 ConfigReloadPending = false;
379415 ProcessConfigFile (PGC_SIGHUP );
416+
417+ /* Reset profile and history if needed */
418+ if (pgws_history_dimensions != saved_history_dimensions )
419+ {
420+ pfree (observations .samples );
421+ alloc_history (& observations , pgws_historySize );
422+ }
423+ if (pgws_profile_dimensions != saved_profile_dimensions )
424+ {
425+ hash_destroy (profile_hash );
426+ profile_hash = make_profile_hash ();
427+ }
380428 }
381429
382430 /* Calculate time to next sample for history or profile */
0 commit comments