PostgreSQL Source Code  git master
wait_event.c
Go to the documentation of this file.
1 /* ----------
2  * wait_event.c
3  * Wait event reporting infrastructure.
4  *
5  * Copyright (c) 2001-2021, PostgreSQL Global Development Group
6  *
7  *
8  * IDENTIFICATION
9  * src/backend/postmaster/wait_event.c
10  *
11  * NOTES
12  *
13  * To make pgstat_report_wait_start() and pgstat_report_wait_end() as
14  * lightweight as possible, they do not check if shared memory (MyProc
15  * specifically, where the wait event is stored) is already available. Instead
16  * we initially set my_wait_event_info to a process local variable, which then
17  * is redirected to shared memory using pgstat_set_wait_event_storage(). For
18  * the same reason pgstat_track_activities is not checked - the check adds
19  * more work than it saves.
20  *
21  * ----------
22  */
23 #include "postgres.h"
24 
25 #include "storage/lmgr.h" /* for GetLockNameFromTagType */
26 #include "storage/lwlock.h" /* for GetLWLockIdentifier */
27 #include "utils/wait_event.h"
28 
29 
30 static const char *pgstat_get_wait_activity(WaitEventActivity w);
31 static const char *pgstat_get_wait_client(WaitEventClient w);
32 static const char *pgstat_get_wait_ipc(WaitEventIPC w);
33 static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
34 static const char *pgstat_get_wait_io(WaitEventIO w);
35 
36 
39 
40 
41 /*
42  * Configure wait event reporting to report wait events to *wait_event_info.
43  * *wait_event_info needs to be valid until pgstat_reset_wait_event_storage()
44  * is called.
45  *
46  * Expected to be called during backend startup, to point my_wait_event_info
47  * into shared memory.
48  */
49 void
51 {
52  my_wait_event_info = wait_event_info;
53 }
54 
55 /*
56  * Reset wait event storage location.
57  *
58  * Expected to be called during backend shutdown, before the location set up
59  * pgstat_set_wait_event_storage() becomes invalid.
60  */
61 void
63 {
65 }
66 
67 /* ----------
68  * pgstat_get_wait_event_type() -
69  *
70  * Return a string representing the current wait event type, backend is
71  * waiting on.
72  */
73 const char *
75 {
76  uint32 classId;
77  const char *event_type;
78 
79  /* report process as not waiting. */
80  if (wait_event_info == 0)
81  return NULL;
82 
83  classId = wait_event_info & 0xFF000000;
84 
85  switch (classId)
86  {
87  case PG_WAIT_LWLOCK:
88  event_type = "LWLock";
89  break;
90  case PG_WAIT_LOCK:
91  event_type = "Lock";
92  break;
93  case PG_WAIT_BUFFER_PIN:
94  event_type = "BufferPin";
95  break;
96  case PG_WAIT_ACTIVITY:
97  event_type = "Activity";
98  break;
99  case PG_WAIT_CLIENT:
100  event_type = "Client";
101  break;
102  case PG_WAIT_EXTENSION:
103  event_type = "Extension";
104  break;
105  case PG_WAIT_IPC:
106  event_type = "IPC";
107  break;
108  case PG_WAIT_TIMEOUT:
109  event_type = "Timeout";
110  break;
111  case PG_WAIT_IO:
112  event_type = "IO";
113  break;
114  default:
115  event_type = "???";
116  break;
117  }
118 
119  return event_type;
120 }
121 
122 /* ----------
123  * pgstat_get_wait_event() -
124  *
125  * Return a string representing the current wait event, backend is
126  * waiting on.
127  */
128 const char *
130 {
131  uint32 classId;
132  uint16 eventId;
133  const char *event_name;
134 
135  /* report process as not waiting. */
136  if (wait_event_info == 0)
137  return NULL;
138 
139  classId = wait_event_info & 0xFF000000;
140  eventId = wait_event_info & 0x0000FFFF;
141 
142  switch (classId)
143  {
144  case PG_WAIT_LWLOCK:
145  event_name = GetLWLockIdentifier(classId, eventId);
146  break;
147  case PG_WAIT_LOCK:
148  event_name = GetLockNameFromTagType(eventId);
149  break;
150  case PG_WAIT_BUFFER_PIN:
151  event_name = "BufferPin";
152  break;
153  case PG_WAIT_ACTIVITY:
154  {
155  WaitEventActivity w = (WaitEventActivity) wait_event_info;
156 
157  event_name = pgstat_get_wait_activity(w);
158  break;
159  }
160  case PG_WAIT_CLIENT:
161  {
162  WaitEventClient w = (WaitEventClient) wait_event_info;
163 
164  event_name = pgstat_get_wait_client(w);
165  break;
166  }
167  case PG_WAIT_EXTENSION:
168  event_name = "Extension";
169  break;
170  case PG_WAIT_IPC:
171  {
172  WaitEventIPC w = (WaitEventIPC) wait_event_info;
173 
174  event_name = pgstat_get_wait_ipc(w);
175  break;
176  }
177  case PG_WAIT_TIMEOUT:
178  {
179  WaitEventTimeout w = (WaitEventTimeout) wait_event_info;
180 
181  event_name = pgstat_get_wait_timeout(w);
182  break;
183  }
184  case PG_WAIT_IO:
185  {
186  WaitEventIO w = (WaitEventIO) wait_event_info;
187 
188  event_name = pgstat_get_wait_io(w);
189  break;
190  }
191  default:
192  event_name = "unknown wait event";
193  break;
194  }
195 
196  return event_name;
197 }
198 
199 /* ----------
200  * pgstat_get_wait_activity() -
201  *
202  * Convert WaitEventActivity to string.
203  * ----------
204  */
205 static const char *
207 {
208  const char *event_name = "unknown wait event";
209 
210  switch (w)
211  {
213  event_name = "ArchiverMain";
214  break;
216  event_name = "AutoVacuumMain";
217  break;
219  event_name = "BgWriterHibernate";
220  break;
222  event_name = "BgWriterMain";
223  break;
225  event_name = "CheckpointerMain";
226  break;
228  event_name = "LogicalApplyMain";
229  break;
231  event_name = "LogicalLauncherMain";
232  break;
234  event_name = "PgStatMain";
235  break;
237  event_name = "RecoveryWalStream";
238  break;
240  event_name = "SysLoggerMain";
241  break;
243  event_name = "WalReceiverMain";
244  break;
246  event_name = "WalSenderMain";
247  break;
249  event_name = "WalWriterMain";
250  break;
251  /* no default case, so that compiler will warn */
252  }
253 
254  return event_name;
255 }
256 
257 /* ----------
258  * pgstat_get_wait_client() -
259  *
260  * Convert WaitEventClient to string.
261  * ----------
262  */
263 static const char *
265 {
266  const char *event_name = "unknown wait event";
267 
268  switch (w)
269  {
271  event_name = "ClientRead";
272  break;
274  event_name = "ClientWrite";
275  break;
277  event_name = "GSSOpenServer";
278  break;
280  event_name = "LibPQWalReceiverConnect";
281  break;
283  event_name = "LibPQWalReceiverReceive";
284  break;
286  event_name = "SSLOpenServer";
287  break;
289  event_name = "WalSenderWaitForWAL";
290  break;
292  event_name = "WalSenderWriteData";
293  break;
294  /* no default case, so that compiler will warn */
295  }
296 
297  return event_name;
298 }
299 
300 /* ----------
301  * pgstat_get_wait_ipc() -
302  *
303  * Convert WaitEventIPC to string.
304  * ----------
305  */
306 static const char *
308 {
309  const char *event_name = "unknown wait event";
310 
311  switch (w)
312  {
314  event_name = "AppendReady";
315  break;
317  event_name = "BackendTermination";
318  break;
320  event_name = "BackupWaitWalArchive";
321  break;
323  event_name = "BgWorkerShutdown";
324  break;
326  event_name = "BgWorkerStartup";
327  break;
329  event_name = "BtreePage";
330  break;
332  event_name = "BufferIO";
333  break;
335  event_name = "CheckpointDone";
336  break;
338  event_name = "CheckpointStart";
339  break;
341  event_name = "ExecuteGather";
342  break;
344  event_name = "HashBatchAllocate";
345  break;
347  event_name = "HashBatchElect";
348  break;
350  event_name = "HashBatchLoad";
351  break;
353  event_name = "HashBuildAllocate";
354  break;
356  event_name = "HashBuildElect";
357  break;
359  event_name = "HashBuildHashInner";
360  break;
362  event_name = "HashBuildHashOuter";
363  break;
365  event_name = "HashGrowBatchesAllocate";
366  break;
368  event_name = "HashGrowBatchesDecide";
369  break;
371  event_name = "HashGrowBatchesElect";
372  break;
374  event_name = "HashGrowBatchesFinish";
375  break;
377  event_name = "HashGrowBatchesRepartition";
378  break;
380  event_name = "HashGrowBucketsAllocate";
381  break;
383  event_name = "HashGrowBucketsElect";
384  break;
386  event_name = "HashGrowBucketsReinsert";
387  break;
389  event_name = "LogicalSyncData";
390  break;
392  event_name = "LogicalSyncStateChange";
393  break;
395  event_name = "MessageQueueInternal";
396  break;
398  event_name = "MessageQueuePutMessage";
399  break;
401  event_name = "MessageQueueReceive";
402  break;
403  case WAIT_EVENT_MQ_SEND:
404  event_name = "MessageQueueSend";
405  break;
407  event_name = "ParallelBitmapScan";
408  break;
410  event_name = "ParallelCreateIndexScan";
411  break;
413  event_name = "ParallelFinish";
414  break;
416  event_name = "ProcArrayGroupUpdate";
417  break;
419  event_name = "ProcSignalBarrier";
420  break;
421  case WAIT_EVENT_PROMOTE:
422  event_name = "Promote";
423  break;
425  event_name = "RecoveryConflictSnapshot";
426  break;
428  event_name = "RecoveryConflictTablespace";
429  break;
431  event_name = "RecoveryPause";
432  break;
434  event_name = "ReplicationOriginDrop";
435  break;
437  event_name = "ReplicationSlotDrop";
438  break;
440  event_name = "SafeSnapshot";
441  break;
442  case WAIT_EVENT_SYNC_REP:
443  event_name = "SyncRep";
444  break;
446  event_name = "WalReceiverExit";
447  break;
449  event_name = "WalReceiverWaitStart";
450  break;
452  event_name = "XactGroupUpdate";
453  break;
454  /* no default case, so that compiler will warn */
455  }
456 
457  return event_name;
458 }
459 
460 /* ----------
461  * pgstat_get_wait_timeout() -
462  *
463  * Convert WaitEventTimeout to string.
464  * ----------
465  */
466 static const char *
468 {
469  const char *event_name = "unknown wait event";
470 
471  switch (w)
472  {
474  event_name = "BaseBackupThrottle";
475  break;
476  case WAIT_EVENT_PG_SLEEP:
477  event_name = "PgSleep";
478  break;
480  event_name = "RecoveryApplyDelay";
481  break;
483  event_name = "RecoveryRetrieveRetryInterval";
484  break;
486  event_name = "VacuumDelay";
487  break;
489  event_name = "VacuumTruncate";
490  break;
491  /* no default case, so that compiler will warn */
492  }
493 
494  return event_name;
495 }
496 
497 /* ----------
498  * pgstat_get_wait_io() -
499  *
500  * Convert WaitEventIO to string.
501  * ----------
502  */
503 static const char *
505 {
506  const char *event_name = "unknown wait event";
507 
508  switch (w)
509  {
511  event_name = "BaseBackupRead";
512  break;
514  event_name = "BufFileRead";
515  break;
517  event_name = "BufFileWrite";
518  break;
520  event_name = "BufFileTruncate";
521  break;
523  event_name = "ControlFileRead";
524  break;
526  event_name = "ControlFileSync";
527  break;
529  event_name = "ControlFileSyncUpdate";
530  break;
532  event_name = "ControlFileWrite";
533  break;
535  event_name = "ControlFileWriteUpdate";
536  break;
538  event_name = "CopyFileRead";
539  break;
541  event_name = "CopyFileWrite";
542  break;
544  event_name = "DataFileExtend";
545  break;
547  event_name = "DataFileFlush";
548  break;
550  event_name = "DataFileImmediateSync";
551  break;
553  event_name = "DataFilePrefetch";
554  break;
556  event_name = "DataFileRead";
557  break;
559  event_name = "DataFileSync";
560  break;
562  event_name = "DataFileTruncate";
563  break;
565  event_name = "DataFileWrite";
566  break;
568  event_name = "DSMFillZeroWrite";
569  break;
571  event_name = "LockFileAddToDataDirRead";
572  break;
574  event_name = "LockFileAddToDataDirSync";
575  break;
577  event_name = "LockFileAddToDataDirWrite";
578  break;
580  event_name = "LockFileCreateRead";
581  break;
583  event_name = "LockFileCreateSync";
584  break;
586  event_name = "LockFileCreateWrite";
587  break;
589  event_name = "LockFileReCheckDataDirRead";
590  break;
592  event_name = "LogicalRewriteCheckpointSync";
593  break;
595  event_name = "LogicalRewriteMappingSync";
596  break;
598  event_name = "LogicalRewriteMappingWrite";
599  break;
601  event_name = "LogicalRewriteSync";
602  break;
604  event_name = "LogicalRewriteTruncate";
605  break;
607  event_name = "LogicalRewriteWrite";
608  break;
610  event_name = "RelationMapRead";
611  break;
613  event_name = "RelationMapSync";
614  break;
616  event_name = "RelationMapWrite";
617  break;
619  event_name = "ReorderBufferRead";
620  break;
622  event_name = "ReorderBufferWrite";
623  break;
625  event_name = "ReorderLogicalMappingRead";
626  break;
628  event_name = "ReplicationSlotRead";
629  break;
631  event_name = "ReplicationSlotRestoreSync";
632  break;
634  event_name = "ReplicationSlotSync";
635  break;
637  event_name = "ReplicationSlotWrite";
638  break;
640  event_name = "SLRUFlushSync";
641  break;
643  event_name = "SLRURead";
644  break;
646  event_name = "SLRUSync";
647  break;
649  event_name = "SLRUWrite";
650  break;
652  event_name = "SnapbuildRead";
653  break;
655  event_name = "SnapbuildSync";
656  break;
658  event_name = "SnapbuildWrite";
659  break;
661  event_name = "TimelineHistoryFileSync";
662  break;
664  event_name = "TimelineHistoryFileWrite";
665  break;
667  event_name = "TimelineHistoryRead";
668  break;
670  event_name = "TimelineHistorySync";
671  break;
673  event_name = "TimelineHistoryWrite";
674  break;
676  event_name = "TwophaseFileRead";
677  break;
679  event_name = "TwophaseFileSync";
680  break;
682  event_name = "TwophaseFileWrite";
683  break;
685  event_name = "WALSenderTimelineHistoryRead";
686  break;
688  event_name = "WALBootstrapSync";
689  break;
691  event_name = "WALBootstrapWrite";
692  break;
694  event_name = "WALCopyRead";
695  break;
697  event_name = "WALCopySync";
698  break;
700  event_name = "WALCopyWrite";
701  break;
703  event_name = "WALInitSync";
704  break;
706  event_name = "WALInitWrite";
707  break;
708  case WAIT_EVENT_WAL_READ:
709  event_name = "WALRead";
710  break;
711  case WAIT_EVENT_WAL_SYNC:
712  event_name = "WALSync";
713  break;
715  event_name = "WALSyncMethodAssign";
716  break;
718  event_name = "WALWrite";
719  break;
721  event_name = "LogicalChangesRead";
722  break;
724  event_name = "LogicalChangesWrite";
725  break;
727  event_name = "LogicalSubxactRead";
728  break;
730  event_name = "LogicalSubxactWrite";
731  break;
732 
733  /* no default case, so that compiler will warn */
734  }
735 
736  return event_name;
737 }
#define PG_WAIT_IO
Definition: wait_event.h:26
WaitEventIPC
Definition: wait_event.h:80
#define PG_WAIT_EXTENSION
Definition: wait_event.h:23
#define PG_WAIT_IPC
Definition: wait_event.h:24
static uint32 local_my_wait_event_info
Definition: wait_event.c:37
#define PG_WAIT_LOCK
Definition: wait_event.h:19
#define PG_WAIT_TIMEOUT
Definition: wait_event.h:25
WaitEventTimeout
Definition: wait_event.h:137
#define PG_WAIT_CLIENT
Definition: wait_event.h:22
unsigned short uint16
Definition: c.h:440
static const char * pgstat_get_wait_activity(WaitEventActivity w)
Definition: wait_event.c:206
static const char * pgstat_get_wait_ipc(WaitEventIPC w)
Definition: wait_event.c:307
static const char * pgstat_get_wait_timeout(WaitEventTimeout w)
Definition: wait_event.c:467
#define PG_WAIT_BUFFER_PIN
Definition: wait_event.h:20
#define PG_WAIT_LWLOCK
Definition: wait_event.h:18
unsigned int uint32
Definition: c.h:441
uint32 * my_wait_event_info
Definition: wait_event.c:38
void pgstat_set_wait_event_storage(uint32 *wait_event_info)
Definition: wait_event.c:50
WaitEventClient
Definition: wait_event.h:61
WaitEventIO
Definition: wait_event.h:153
const char * pgstat_get_wait_event(uint32 wait_event_info)
Definition: wait_event.c:129
const char * pgstat_get_wait_event_type(uint32 wait_event_info)
Definition: wait_event.c:74
const char * GetLockNameFromTagType(uint16 locktag_type)
Definition: lmgr.c:1190
WaitEventActivity
Definition: wait_event.h:36
const char * GetLWLockIdentifier(uint32 classId, uint16 eventId)
Definition: lwlock.c:800
void pgstat_reset_wait_event_storage(void)
Definition: wait_event.c:62
#define PG_WAIT_ACTIVITY
Definition: wait_event.h:21
static const char * pgstat_get_wait_client(WaitEventClient w)
Definition: wait_event.c:264
static const char * pgstat_get_wait_io(WaitEventIO w)
Definition: wait_event.c:504