6
6
#include "miscadmin.h"
7
7
#include "postmaster/bgworker.h"
8
8
#include "storage/ipc.h"
9
+ #include "storage/pg_shmem.h"
9
10
#include "storage/procarray.h"
10
11
#include "storage/procsignal.h"
11
12
#include "storage/s_lock.h"
@@ -27,10 +28,6 @@ shm_toc *toc;
27
28
shm_mq * mq ;
28
29
static volatile sig_atomic_t shutdown_requested = false;
29
30
30
- int historySize ;
31
- int historyPeriod ;
32
- bool historySkipLatch ;
33
-
34
31
static void handle_sigterm (SIGNAL_ARGS );
35
32
static void collector_main (Datum main_arg );
36
33
@@ -52,6 +49,22 @@ CollectorShmemSize(void)
52
49
return size ;
53
50
}
54
51
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
+
55
68
CollectorShmqHeader *
56
69
GetCollectorMem (bool init )
57
70
{
@@ -75,6 +88,21 @@ GetCollectorMem(bool init)
75
88
76
89
mq_mem = shm_toc_allocate (toc , COLLECTOR_QUEUE_SIZE );
77
90
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 );
78
106
}
79
107
else
80
108
{
@@ -110,6 +138,39 @@ AllocHistory(History *observations, int count)
110
138
observations -> wraparound = false;
111
139
}
112
140
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
+
113
174
/* Read current wait information from proc, if readCurrent is true,
114
175
* then it reads from currently going wait, and can be inconsistent
115
176
*/
@@ -167,7 +228,11 @@ get_next_observation(History *observations)
167
228
static void
168
229
write_waits_history (History * observations , TimestampTz current_ts )
169
230
{
170
- int i ;
231
+ int i , newSize ;
232
+
233
+ newSize = hdr -> historySize ;
234
+ if (observations -> count != newSize )
235
+ ReallocHistory (observations , newSize );
171
236
172
237
LWLockAcquire (ProcArrayLock , LW_SHARED );
173
238
for (i = 0 ; i < ProcGlobal -> allProcCount ; ++ i )
@@ -181,7 +246,7 @@ write_waits_history(History *observations, TimestampTz current_ts)
181
246
182
247
if (stateOk )
183
248
{
184
- if (historySkipLatch && item .classId == WAIT_LATCH )
249
+ if (hdr -> historySkipLatch && item .classId == WAIT_LATCH )
185
250
continue ;
186
251
187
252
item .ts = current_ts ;
@@ -237,7 +302,7 @@ collector_main(Datum main_arg)
237
302
ALLOCSET_DEFAULT_INITSIZE ,
238
303
ALLOCSET_DEFAULT_MAXSIZE );
239
304
old_context = MemoryContextSwitchTo (collector_context );
240
- AllocHistory (& observations , historySize );
305
+ AllocHistory (& observations , hdr -> historySize );
241
306
MemoryContextSwitchTo (old_context );
242
307
243
308
while (1 )
@@ -254,7 +319,7 @@ collector_main(Datum main_arg)
254
319
255
320
rc = WaitLatch (& MyProc -> procLatch ,
256
321
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH ,
257
- historyPeriod );
322
+ hdr -> historyPeriod );
258
323
259
324
if (rc & WL_POSTMASTER_DEATH )
260
325
exit (1 );
0 commit comments