66#include "miscadmin.h"
77#include "postmaster/bgworker.h"
88#include "storage/ipc.h"
9+ #include "storage/pg_shmem.h"
910#include "storage/procarray.h"
1011#include "storage/procsignal.h"
1112#include "storage/s_lock.h"
@@ -27,10 +28,6 @@ shm_toc *toc;
2728shm_mq * mq ;
2829static volatile sig_atomic_t shutdown_requested = false;
2930
30- int historySize ;
31- int historyPeriod ;
32- bool historySkipLatch ;
33-
3431static void handle_sigterm (SIGNAL_ARGS );
3532static void collector_main (Datum main_arg );
3633
@@ -52,6 +49,22 @@ CollectorShmemSize(void)
5249 return size ;
5350}
5451
52+ static bool
53+ shmem_int_guc_check_hook (int * newval , void * * extra , GucSource source )
54+ {
55+ if (UsedShmemSegAddr == NULL )
56+ return false;
57+ return true;
58+ }
59+
60+ static bool
61+ shmem_bool_guc_check_hook (bool * newval , void * * extra , GucSource source )
62+ {
63+ if (UsedShmemSegAddr == NULL )
64+ return false;
65+ return true;
66+ }
67+
5568CollectorShmqHeader *
5669GetCollectorMem (bool init )
5770{
@@ -75,6 +88,21 @@ GetCollectorMem(bool init)
7588
7689 mq_mem = shm_toc_allocate (toc , COLLECTOR_QUEUE_SIZE );
7790 shm_toc_insert (toc , 1 , mq_mem );
91+
92+ DefineCustomIntVariable ("pg_stat_wait.history_size" ,
93+ "Sets size of waits history." , NULL ,
94+ & hdr -> historySize , 5000 , 100 , INT_MAX ,
95+ PGC_SUSET , 0 , shmem_int_guc_check_hook , NULL , NULL );
96+
97+ DefineCustomIntVariable ("pg_stat_wait.history_period" ,
98+ "Sets period of waits history sampling." , NULL ,
99+ & hdr -> historyPeriod , 10 , 1 , INT_MAX ,
100+ PGC_SUSET , 0 , shmem_int_guc_check_hook , NULL , NULL );
101+
102+ DefineCustomBoolVariable ("pg_stat_wait.history_skip_latch" ,
103+ "Skip latch events in waits history" , NULL ,
104+ & hdr -> historySkipLatch , false,
105+ PGC_SUSET , 0 , shmem_bool_guc_check_hook , NULL , NULL );
78106 }
79107 else
80108 {
@@ -110,6 +138,39 @@ AllocHistory(History *observations, int count)
110138 observations -> wraparound = false;
111139}
112140
141+ static void
142+ ReallocHistory (History * observations , int count )
143+ {
144+ HistoryItem * newitems ;
145+ int copyCount ;
146+ int i , j ;
147+
148+ newitems = (HistoryItem * ) palloc0 (sizeof (HistoryItem ) * count );
149+
150+ if (observations -> wraparound )
151+ copyCount = Min (observations -> count , count );
152+ else
153+ copyCount = observations -> index ;
154+
155+ i = 0 ;
156+ j = observations -> index ;
157+ while (i < copyCount )
158+ {
159+ j -- ;
160+ if (j < 0 )
161+ j = observations -> count - 1 ;
162+ memcpy (& newitems [i ], & observations -> items [j ], sizeof (HistoryItem ));
163+ i ++ ;
164+ }
165+
166+ pfree (observations -> items );
167+ observations -> items = newitems ;
168+
169+ observations -> index = copyCount ;
170+ observations -> count = count ;
171+ observations -> wraparound = false;
172+ }
173+
113174/* Read current wait information from proc, if readCurrent is true,
114175 * then it reads from currently going wait, and can be inconsistent
115176 */
@@ -167,7 +228,11 @@ get_next_observation(History *observations)
167228static void
168229write_waits_history (History * observations , TimestampTz current_ts )
169230{
170- int i ;
231+ int i , newSize ;
232+
233+ newSize = hdr -> historySize ;
234+ if (observations -> count != newSize )
235+ ReallocHistory (observations , newSize );
171236
172237 LWLockAcquire (ProcArrayLock , LW_SHARED );
173238 for (i = 0 ; i < ProcGlobal -> allProcCount ; ++ i )
@@ -181,7 +246,7 @@ write_waits_history(History *observations, TimestampTz current_ts)
181246
182247 if (stateOk )
183248 {
184- if (historySkipLatch && item .classId == WAIT_LATCH )
249+ if (hdr -> historySkipLatch && item .classId == WAIT_LATCH )
185250 continue ;
186251
187252 item .ts = current_ts ;
@@ -237,7 +302,7 @@ collector_main(Datum main_arg)
237302 ALLOCSET_DEFAULT_INITSIZE ,
238303 ALLOCSET_DEFAULT_MAXSIZE );
239304 old_context = MemoryContextSwitchTo (collector_context );
240- AllocHistory (& observations , historySize );
305+ AllocHistory (& observations , hdr -> historySize );
241306 MemoryContextSwitchTo (old_context );
242307
243308 while (1 )
@@ -254,7 +319,7 @@ collector_main(Datum main_arg)
254319
255320 rc = WaitLatch (& MyProc -> procLatch ,
256321 WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH ,
257- historyPeriod );
322+ hdr -> historyPeriod );
258323
259324 if (rc & WL_POSTMASTER_DEATH )
260325 exit (1 );
0 commit comments