]> granicus.if.org Git - postgresql/commitdiff
Extend framework from commit 53be0b1ad to report latch waits.
authorRobert Haas <rhaas@postgresql.org>
Tue, 4 Oct 2016 14:50:13 +0000 (10:50 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 4 Oct 2016 15:01:42 +0000 (11:01 -0400)
WaitLatch, WaitLatchOrSocket, and WaitEventSetWait now taken an
additional wait_event_info parameter; legal values are defined in
pgstat.h.  This makes it possible to uniquely identify every point in
the core code where we are waiting for a latch; extensions can pass
WAIT_EXTENSION.

Because latches were the major wait primitive not previously covered
by this patch, it is now possible to see information in
pg_stat_activity on a large number of important wait events not
previously addressed, such as ClientRead, ClientWrite, and SyncRep.

Unfortunately, many of the wait events added by this patch will fail
to appear in pg_stat_activity because they're only used in background
processes which don't currently appear in pg_stat_activity.  We should
fix this either by creating a separate view for such information, or
else by deciding to include them in pg_stat_activity after all.

Michael Paquier and Robert Haas, reviewed by Alexander Korotkov and
Thomas Munro.

35 files changed:
contrib/postgres_fdw/connection.c
doc/src/sgml/monitoring.sgml
src/backend/access/transam/parallel.c
src/backend/access/transam/xlog.c
src/backend/executor/nodeGather.c
src/backend/libpq/be-secure-openssl.c
src/backend/libpq/be-secure.c
src/backend/libpq/pqmq.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/bgworker.c
src/backend/postmaster/bgwriter.c
src/backend/postmaster/checkpointer.c
src/backend/postmaster/pgarch.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/syslogger.c
src/backend/postmaster/walwriter.c
src/backend/replication/basebackup.c
src/backend/replication/syncrep.c
src/backend/replication/walreceiver.c
src/backend/replication/walsender.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/ipc/latch.c
src/backend/storage/ipc/shm_mq.c
src/backend/storage/ipc/standby.c
src/backend/storage/lmgr/lock.c
src/backend/storage/lmgr/lwlock.c
src/backend/storage/lmgr/predicate.c
src/backend/storage/lmgr/proc.c
src/backend/utils/adt/misc.c
src/include/pgstat.h
src/include/storage/latch.h
src/include/storage/lwlock.h
src/include/storage/proc.h
src/test/modules/test_shm_mq/setup.c
src/test/modules/test_shm_mq/test.c

index 8ca1c1c89869e52e8261b52ab5403ca5547b84fa..9badfe6a7dd9c5be60a123e15efecf84d3b05c9f 100644 (file)
@@ -17,6 +17,7 @@
 #include "access/xact.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/latch.h"
 #include "utils/hsearch.h"
 #include "utils/memutils.h"
@@ -496,7 +497,7 @@ pgfdw_get_result(PGconn *conn, const char *query)
                        wc = WaitLatchOrSocket(MyLatch,
                                                                   WL_LATCH_SET | WL_SOCKET_READABLE,
                                                                   PQsocket(conn),
-                                                                  -1L);
+                                                                  -1L, WAIT_EXTENSION);
                        ResetLatch(MyLatch);
 
                        CHECK_FOR_INTERRUPTS();
index f40078572181e21d79cb9d03466ddbd3bd8cdc8e..3de489e2f0dcce2b280223ce230989403d213d9c 100644 (file)
@@ -679,6 +679,42 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
           buffer in question.
          </para>
         </listitem>
+        <listitem>
+         <para>
+          <literal>Activity</>: The server process is idle.  This is used by
+          system processes waiting for activity in their main processing loop.
+          <literal>wait_event</> will identify the specific wait point.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          <literal>Extension</>: The server process is waiting for activity
+          in an extension module.  This category is useful for modules to
+          track custom waiting points.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          <literal>Client</>: The server process is waiting for some activity
+          on a socket from user applications, and that the server expects
+          something to happen that is independent from its internal processes.
+          <literal>wait_event</> will identify the specific wait point.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          <literal>IPC</>: The server process is waiting for some activity
+          from another process in the server.  <literal>wait_event</> will
+          identify the specific wait point.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          <literal>Timeout</>: The server process is waiting for a timeout
+          to expire.  <literal>wait_event</> will identify the specific wait
+          point.
+         </para>
+        </listitem>
        </itemizedlist>
       </entry>
      </row>
@@ -1085,6 +1121,139 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
          <entry><literal>BufferPin</></entry>
          <entry>Waiting to acquire a pin on a buffer.</entry>
         </row>
+        <row>
+         <entry morerows="11"><literal>Activity</></entry>
+         <entry><literal>ArchiverMain</></entry>
+         <entry>Waiting in main loop of the archiver process.</entry>
+        </row>
+        <row>
+         <entry><literal>AutoVacuumMain</></entry>
+         <entry>Waiting in main loop of autovacuum launcher process.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWriterHibernate</></entry>
+         <entry>Waiting in background writer process, hibernating.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWriterMain</></entry>
+         <entry>Waiting in main loop of background writer process background worker.</entry>
+        </row>
+        <row>
+         <entry><literal>CheckpointerMain</></entry>
+         <entry>Waiting in main loop of checkpointer process.</entry>
+        </row>
+        <row>
+         <entry><literal>PgStatMain</></entry>
+         <entry>Waiting in main loop of the statistics collector process.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryWalAll</></entry>
+         <entry>Waiting for WAL from any kind of source (local, archive or stream) at recovery.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryWalStream</></entry>
+         <entry>Waiting for WAL from a stream at recovery.</entry>
+        </row>
+        <row>
+         <entry><literal>SysLoggerMain</></entry>
+         <entry>Waiting in main loop of syslogger process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalReceiverMain</></entry>
+         <entry>Waiting in main loop of WAL receiver process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderMain</></entry>
+         <entry>Waiting in main loop of WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalWriterMain</></entry>
+         <entry>Waiting in main loop of WAL writer process.</entry>
+        </row>
+        <row>
+         <entry morerows="5"><literal>Client</></entry>
+         <entry><literal>ClientRead</></entry>
+         <entry>Waiting to read data from the client.</entry>
+        </row>
+        <row>
+         <entry><literal>ClientWrite</></entry>
+         <entry>Waiting to write data from the client.</entry>
+        </row>
+        <row>
+         <entry><literal>SSLOpenServer</></entry>
+         <entry>Waiting for SSL while attempting connection.</entry>
+        </row>
+        <row>
+         <entry><literal>WalReceiverWaitStart</></entry>
+         <entry>Waiting for startup process to send initial data for streaming replication.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderWaitForWAL</></entry>
+         <entry>Waiting for WAL to be flushed in WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderWriteData</></entry>
+         <entry>Waiting for any activity when processing replies from WAL receiver in WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>Extension</></entry>
+         <entry><literal>Extension</></entry>
+         <entry>Waiting in an extension.</entry>
+        </row>
+        <row>
+         <entry morerows="9"><literal>IPC</></entry>
+         <entry><literal>BgWorkerShutdown</></entry>
+         <entry>Waiting for background worker to shut down.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWorkerStartup</></entry>
+         <entry>Waiting for background worker to start up.</entry>
+        </row>
+        <row>
+         <entry><literal>ExecuteGather</></entry>
+         <entry>Waiting for activity from child process when executing <literal>Gather</> node.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueInternal</></entry>
+         <entry>Waiting for other process to be attached in shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueuePutMessage</></entry>
+         <entry>Waiting to write a protoocol message to a shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueReceive</></entry>
+         <entry>Waiting to receive bytes from a shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueSend</></entry>
+         <entry>Waiting to send bytes to a shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>ParallelFinish</></entry>
+         <entry>Waiting for parallel workers to finish computing.</entry>
+        </row>
+        <row>
+         <entry><literal>SafeSnapshot</></entry>
+         <entry>Waiting for a snapshot for a <literal>READ ONLY DEFERRABLE</> transaction.</entry>
+        </row>
+        <row>
+         <entry><literal>SyncRep</></entry>
+         <entry>Waiting for confirmation from remote server during synchronous replication.</entry>
+        </row>
+        <row>
+         <entry morerows="2"><literal>Timeout</></entry>
+         <entry><literal>BaseBackupThrottle</></entry>
+         <entry>Waiting during base backup when throttling activity.</entry>
+        </row>
+        <row>
+         <entry><literal>PgSleep</></entry>
+         <entry>Waiting in process that called <function>pg_sleep</>.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryApplyDelay</></entry>
+         <entry>Waiting to apply WAL at recovery because it is delayed.</entry>
+        </row>
       </tbody>
      </tgroup>
     </table>
index cde0ed300f7130c396640d8c496519ff191be432..59dc3949d8302135215f30eab9e31bfe8e52d4d3 100644 (file)
@@ -24,6 +24,7 @@
 #include "libpq/pqmq.h"
 #include "miscadmin.h"
 #include "optimizer/planmain.h"
+#include "pgstat.h"
 #include "storage/ipc.h"
 #include "storage/sinval.h"
 #include "storage/spin.h"
@@ -540,7 +541,8 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt)
                if (!anyone_alive)
                        break;
 
-               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, -1);
+               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, -1,
+                                 WAIT_EVENT_PARALLEL_FINISH);
                ResetLatch(&MyProc->procLatch);
        }
 
index c1b9a97147cfe04b0be04a36603fbd68a9c219bd..08c87f91be62190c06056625a294d15a19978122 100644 (file)
@@ -5827,7 +5827,8 @@ recoveryApplyDelay(XLogReaderState *record)
 
                WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                  WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                 secs * 1000L + microsecs / 1000);
+                                 secs * 1000L + microsecs / 1000,
+                                 WAIT_EVENT_RECOVERY_APPLY_DELAY);
        }
        return true;
 }
@@ -11387,7 +11388,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 
                                                WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                                         WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                                 wait_time);
+                                                                 wait_time, WAIT_EVENT_RECOVERY_WAL_STREAM);
                                                ResetLatch(&XLogCtl->recoveryWakeupLatch);
                                                now = GetCurrentTimestamp();
                                        }
@@ -11550,7 +11551,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
                                         */
                                        WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                                          WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                         5000L);
+                                                         5000L, WAIT_EVENT_RECOVERY_WAL_ALL);
                                        ResetLatch(&XLogCtl->recoveryWakeupLatch);
                                        break;
                                }
index 438d1b24fc2e4be8d1b56206a337269e23c0a8bf..880ca623974699ebf9ddb4777da0852dead18456 100644 (file)
@@ -38,6 +38,7 @@
 #include "executor/nodeSubplan.h"
 #include "executor/tqueue.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
 
@@ -387,7 +388,7 @@ gather_readnext(GatherState *gatherstate)
                                return NULL;
 
                        /* Nothing to do except wait for developments. */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_EXECUTE_GATHER);
                        ResetLatch(MyLatch);
                        nvisited = 0;
                }
index fedb02cd8209cedea4b7b038cc4e1d323f7e8fe5..668f217bba094e2d1aa43e07e617c982f8156ea2 100644 (file)
@@ -60,6 +60,7 @@
 
 #include "libpq/libpq.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/latch.h"
 #include "tcop/tcopprot.h"
 #include "utils/memutils.h"
@@ -419,7 +420,8 @@ aloop:
                                else
                                        waitfor = WL_SOCKET_WRITEABLE;
 
-                               WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0);
+                               WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
+                                                                 WAIT_EVENT_SSL_OPEN_SERVER);
                                goto aloop;
                        case SSL_ERROR_SYSCALL:
                                if (r < 0)
index cdd07d577b08e381d92225bbdfe9c033fb302b29..b267507de9a7bbe8e233d3a1ad93e59bdcef3fc3 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "libpq/libpq.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "tcop/tcopprot.h"
 #include "utils/memutils.h"
 #include "storage/ipc.h"
@@ -146,7 +147,8 @@ retry:
 
                ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
 
-               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
+               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
+                                                WAIT_EVENT_CLIENT_READ);
 
                /*
                 * If the postmaster has died, it's not safe to continue running,
@@ -247,7 +249,8 @@ retry:
 
                ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
 
-               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
+               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
+                                                WAIT_EVENT_CLIENT_WRITE);
 
                /* See comments in secure_read. */
                if (event.events & WL_POSTMASTER_DEATH)
index bfe66c6c44a50ea96bae5b5b1a0a0776a6abf860..f93ccae148b3f3911d36dbfe843abfe8d2f360f2 100644 (file)
@@ -17,6 +17,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/pqmq.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
 
@@ -171,7 +172,8 @@ mq_putmessage(char msgtype, const char *s, size_t len)
                if (result != SHM_MQ_WOULD_BLOCK)
                        break;
 
-               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
+               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0,
+                                 WAIT_EVENT_MQ_PUT_MESSAGE);
                ResetLatch(&MyProc->procLatch);
                CHECK_FOR_INTERRUPTS();
        }
index 1a92ca1deb7916273684828dcad4aafafcb2a1fd..e3a6911fbadfab09e20d2bf4e993938ae665dedd 100644 (file)
@@ -598,7 +598,8 @@ AutoVacLauncherMain(int argc, char *argv[])
                 */
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                          (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L));
+                                          (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L),
+                                          WAIT_EVENT_AUTOVACUUM_MAIN);
 
                ResetLatch(MyLatch);
 
index 699c934240394c2a3a4a075b8d3bcce293e67754..028a9eed2dee64edb3f8c311c333e5a17a0b0666 100644 (file)
@@ -18,6 +18,7 @@
 #include "libpq/pqsignal.h"
 #include "postmaster/bgworker_internals.h"
 #include "postmaster/postmaster.h"
+#include "pgstat.h"
 #include "storage/barrier.h"
 #include "storage/dsm.h"
 #include "storage/ipc.h"
@@ -969,7 +970,8 @@ WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp)
                        break;
 
                rc = WaitLatch(MyLatch,
-                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
+                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
+                                          WAIT_EVENT_BGWORKER_STARTUP);
 
                if (rc & WL_POSTMASTER_DEATH)
                {
@@ -1008,7 +1010,8 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
                        break;
 
                rc = WaitLatch(&MyProc->procLatch,
-                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
+                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
+                                          WAIT_EVENT_BGWORKER_SHUTDOWN);
 
                if (rc & WL_POSTMASTER_DEATH)
                {
index 10020349a2c0dccc3c183617d44b387c5a8cc8fb..c3f33561da225c6546148f71eb2487adcd671bd0 100644 (file)
@@ -345,7 +345,7 @@ BackgroundWriterMain(void)
                 */
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                          BgWriterDelay /* ms */ );
+                                          BgWriterDelay /* ms */, WAIT_EVENT_BGWRITER_MAIN);
 
                /*
                 * If no latch event and BgBufferSync says nothing's happening, extend
@@ -372,7 +372,8 @@ BackgroundWriterMain(void)
                        /* Sleep ... */
                        rc = WaitLatch(MyLatch,
                                                   WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                  BgWriterDelay * HIBERNATE_FACTOR);
+                                                  BgWriterDelay * HIBERNATE_FACTOR,
+                                                  WAIT_EVENT_BGWRITER_HIBERNATE);
                        /* Reset the notification request in case we timed out */
                        StrategyNotifyBgWriter(-1);
                }
index d702a4864d6b3ac2895cbf08c812ddf3c1a9014a..397267c6b74ef64afbf36508075f91613f425ab2 100644 (file)
@@ -556,7 +556,8 @@ CheckpointerMain(void)
 
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                          cur_timeout * 1000L /* convert to ms */ );
+                                          cur_timeout * 1000L /* convert to ms */,
+                                          WAIT_EVENT_CHECKPOINTER_MAIN);
 
                /*
                 * Emergency bailout if postmaster has died.  This is to avoid the
index 1aa6466d67f23a4752536527b450e038a7a1dca7..62783d9259d61304bd2c4aa68afc9b53816eb1f0 100644 (file)
@@ -390,7 +390,8 @@ pgarch_MainLoop(void)
 
                                rc = WaitLatch(MyLatch,
                                                         WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                          timeout * 1000L);
+                                                          timeout * 1000L,
+                                                          WAIT_EVENT_ARCHIVER_MAIN);
                                if (rc & WL_TIMEOUT)
                                        wakened = true;
                        }
index 96578dcedb5f6b1bb66a6435c26f40b2f0b1113f..8c9d06fdaad6a668af85de42ebaa45365d4d65e6 100644 (file)
@@ -276,6 +276,11 @@ static PgStat_TableStatus *get_tabstat_entry(Oid rel_id, bool isshared);
 
 static void pgstat_setup_memcxt(void);
 
+static const char *pgstat_get_wait_activity(WaitEventActivity w);
+static const char *pgstat_get_wait_client(WaitEventClient w);
+static const char *pgstat_get_wait_ipc(WaitEventIPC w);
+static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
+
 static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype);
 static void pgstat_send(void *msg, int len);
 
@@ -3131,15 +3136,14 @@ pgstat_read_current_status(void)
 const char *
 pgstat_get_wait_event_type(uint32 wait_event_info)
 {
-       uint          classId;
+       uint32          classId;
        const char *event_type;
 
        /* report process as not waiting. */
        if (wait_event_info == 0)
                return NULL;
 
-       wait_event_info = wait_event_info >> 24;
-       classId = wait_event_info & 0XFF;
+       classId = wait_event_info & 0xFF000000;
 
        switch (classId)
        {
@@ -3155,6 +3159,21 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
                case WAIT_BUFFER_PIN:
                        event_type = "BufferPin";
                        break;
+               case WAIT_ACTIVITY:
+                       event_type = "Activity";
+                       break;
+               case WAIT_CLIENT:
+                       event_type = "Client";
+                       break;
+               case WAIT_EXTENSION:
+                       event_type = "Extension";
+                       break;
+               case WAIT_IPC:
+                       event_type = "IPC";
+                       break;
+               case WAIT_TIMEOUT:
+                       event_type = "Timeout";
+                       break;
                default:
                        event_type = "???";
                        break;
@@ -3172,7 +3191,7 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
 const char *
 pgstat_get_wait_event(uint32 wait_event_info)
 {
-       uint          classId;
+       uint32          classId;
        uint16          eventId;
        const char *event_name;
 
@@ -3180,9 +3199,8 @@ pgstat_get_wait_event(uint32 wait_event_info)
        if (wait_event_info == 0)
                return NULL;
 
-       eventId = wait_event_info & ((1 << 24) - 1);
-       wait_event_info = wait_event_info >> 24;
-       classId = wait_event_info & 0XFF;
+       classId = wait_event_info & 0xFF000000;
+       eventId = wait_event_info & 0x0000FFFF;
 
        switch (classId)
        {
@@ -3196,6 +3214,37 @@ pgstat_get_wait_event(uint32 wait_event_info)
                case WAIT_BUFFER_PIN:
                        event_name = "BufferPin";
                        break;
+               case WAIT_ACTIVITY:
+                       {
+                               WaitEventActivity       w = (WaitEventActivity) wait_event_info;
+
+                               event_name = pgstat_get_wait_activity(w);
+                               break;
+                       }
+               case WAIT_CLIENT:
+                       {
+                               WaitEventClient w = (WaitEventClient) wait_event_info;
+
+                               event_name = pgstat_get_wait_client(w);
+                               break;
+                       }
+               case WAIT_EXTENSION:
+                       event_name = "Extension";
+                       break;
+               case WAIT_IPC:
+                       {
+                               WaitEventIPC    w = (WaitEventIPC) wait_event_info;
+
+                               event_name = pgstat_get_wait_ipc(w);
+                               break;
+                       }
+               case WAIT_TIMEOUT:
+                       {
+                               WaitEventTimeout        w = (WaitEventTimeout) wait_event_info;
+
+                               event_name = pgstat_get_wait_timeout(w);
+                               break;
+                       }
                default:
                        event_name = "unknown wait event";
                        break;
@@ -3204,6 +3253,175 @@ pgstat_get_wait_event(uint32 wait_event_info)
        return event_name;
 }
 
+/* ----------
+ * pgstat_get_wait_activity() -
+ *
+ * Convert WaitEventActivity to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_activity(WaitEventActivity w)
+{
+       const char *event_name = "unknown wait event";
+
+       switch (w)
+       {
+               case WAIT_EVENT_ARCHIVER_MAIN:
+                       event_name = "ArchiverMain";
+                       break;
+               case WAIT_EVENT_AUTOVACUUM_MAIN:
+                       event_name = "AutoVacuumMain";
+                       break;
+               case WAIT_EVENT_BGWRITER_HIBERNATE:
+                       event_name = "BgWriterHibernate";
+                       break;
+               case WAIT_EVENT_BGWRITER_MAIN:
+                       event_name = "BgWriterMain";
+                       break;
+               case WAIT_EVENT_CHECKPOINTER_MAIN:
+                       event_name = "CheckpointerMain";
+                       break;
+               case WAIT_EVENT_PGSTAT_MAIN:
+                       event_name = "PgStatMain";
+                       break;
+               case WAIT_EVENT_RECOVERY_WAL_ALL:
+                       event_name = "RecoveryWalAll";
+                       break;
+               case WAIT_EVENT_RECOVERY_WAL_STREAM:
+                       event_name = "RecoveryWalStream";
+                       break;
+               case WAIT_EVENT_SYSLOGGER_MAIN:
+                       event_name = "SysLoggerMain";
+                       break;
+               case WAIT_EVENT_WAL_RECEIVER_MAIN:
+                       event_name = "WalReceiverMain";
+                       break;
+               case WAIT_EVENT_WAL_SENDER_MAIN:
+                       event_name = "WalSenderMain";
+                       break;
+               case WAIT_EVENT_WAL_WRITER_MAIN:
+                       event_name = "WalWriterMain";
+                       break;
+               /* no default case, so that compiler will warn */
+       }
+
+       return event_name;
+}
+
+/* ----------
+ * pgstat_get_wait_client() -
+ *
+ * Convert WaitEventClient to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_client(WaitEventClient w)
+{
+       const char *event_name = "unknown wait event";
+
+       switch (w)
+       {
+               case WAIT_EVENT_CLIENT_READ:
+                       event_name = "ClientRead";
+                       break;
+               case WAIT_EVENT_CLIENT_WRITE:
+                       event_name = "ClientWrite";
+                       break;
+               case WAIT_EVENT_SSL_OPEN_SERVER:
+                       event_name = "SSLOpenServer";
+                       break;
+               case WAIT_EVENT_WAL_RECEIVER_WAIT_START:
+                       event_name = "WalReceiverWaitStart";
+                       break;
+               case WAIT_EVENT_WAL_SENDER_WAIT_WAL:
+                       event_name = "WalSenderWaitForWAL";
+                       break;
+               case WAIT_EVENT_WAL_SENDER_WRITE_DATA:
+                       event_name = "WalSenderWriteData";
+                       break;
+               /* no default case, so that compiler will warn */
+       }
+
+       return event_name;
+}
+
+/* ----------
+ * pgstat_get_wait_ipc() -
+ *
+ * Convert WaitEventIPC to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_ipc(WaitEventIPC w)
+{
+       const char *event_name = "unknown wait event";
+
+       switch (w)
+       {
+               case WAIT_EVENT_BGWORKER_SHUTDOWN:
+                       event_name = "BgWorkerShutdown";
+                       break;
+               case WAIT_EVENT_BGWORKER_STARTUP:
+                       event_name = "BgWorkerStartup";
+                       break;
+               case WAIT_EVENT_EXECUTE_GATHER:
+                       event_name = "ExecuteGather";
+                       break;
+               case WAIT_EVENT_MQ_INTERNAL:
+                       event_name = "MessageQueueInternal";
+                       break;
+               case WAIT_EVENT_MQ_PUT_MESSAGE:
+                       event_name = "MessageQueuePutMessage";
+                       break;
+               case WAIT_EVENT_MQ_RECEIVE:
+                       event_name = "MessageQueueReceive";
+                       break;
+               case WAIT_EVENT_MQ_SEND:
+                       event_name = "MessageQueueSend";
+                       break;
+               case WAIT_EVENT_PARALLEL_FINISH:
+                       event_name = "ParallelFinish";
+                       break;
+               case WAIT_EVENT_SAFE_SNAPSHOT:
+                       event_name = "SafeSnapshot";
+                       break;
+               case WAIT_EVENT_SYNC_REP:
+                       event_name = "SyncRep";
+                       break;
+               /* no default case, so that compiler will warn */
+       }
+
+       return event_name;
+}
+
+/* ----------
+ * pgstat_get_wait_timeout() -
+ *
+ * Convert WaitEventTimeout to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_timeout(WaitEventTimeout w)
+{
+       const char *event_name = "unknown wait event";
+
+       switch (w)
+       {
+               case WAIT_EVENT_BASE_BACKUP_THROTTLE:
+                       event_name = "BaseBackupThrottle";
+                       break;
+               case WAIT_EVENT_PG_SLEEP:
+                       event_name = "PgSleep";
+                       break;
+               case WAIT_EVENT_RECOVERY_APPLY_DELAY:
+                       event_name = "RecoveryApplyDelay";
+                       break;
+               /* no default case, so that compiler will warn */
+       }
+
+       return event_name;
+}
+
 /* ----------
  * pgstat_get_backend_current_activity() -
  *
@@ -3684,8 +3902,8 @@ PgstatCollectorMain(int argc, char *argv[])
 #ifndef WIN32
                wr = WaitLatchOrSocket(MyLatch,
                                         WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_SOCKET_READABLE,
-                                                          pgStatSock,
-                                                          -1L);
+                                                          pgStatSock, -1L,
+                                                          WAIT_EVENT_PGSTAT_MAIN);
 #else
 
                /*
index e7e488a23657e93f7b1817168057dbeece5d9bc9..af7136760a3fdcf799886156a11e9cf3f22a6400 100644 (file)
@@ -35,6 +35,7 @@
 #include "libpq/pqsignal.h"
 #include "miscadmin.h"
 #include "nodes/pg_list.h"
+#include "pgstat.h"
 #include "pgtime.h"
 #include "postmaster/fork_process.h"
 #include "postmaster/postmaster.h"
@@ -424,7 +425,8 @@ SysLoggerMain(int argc, char *argv[])
                rc = WaitLatchOrSocket(MyLatch,
                                                           WL_LATCH_SET | WL_SOCKET_READABLE | cur_flags,
                                                           syslogPipe[0],
-                                                          cur_timeout);
+                                                          cur_timeout,
+                                                          WAIT_EVENT_SYSLOGGER_MAIN);
 
                if (rc & WL_SOCKET_READABLE)
                {
index 11ec56aebbef9f85cb74f67b74341011fdd55491..67dcff63b1bdb5ea60b34b492b39fb47c0ff2677 100644 (file)
@@ -290,7 +290,8 @@ WalWriterMain(void)
 
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                          cur_timeout);
+                                          cur_timeout,
+                                          WAIT_EVENT_WAL_WRITER_MAIN);
 
                /*
                 * Emergency bailout if postmaster has died.  This is to avoid the
index 1eabaef492417d0320c85bd017f0309b6cef268b..fa75930c9f838082f3bdc4e0e2f9c58f2c609aed 100644 (file)
@@ -1364,7 +1364,8 @@ throttle(size_t increment)
                 */
                wait_result = WaitLatch(MyLatch,
                                                         WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                               (long) (sleep / 1000));
+                                                               (long) (sleep / 1000),
+                                                               WAIT_EVENT_BASE_BACKUP_THROTTLE);
 
                if (wait_result & WL_LATCH_SET)
                        CHECK_FOR_INTERRUPTS();
index b442d061ec0c341158f51d782749b9ccba718825..ac29f567c3bf37c578a9179c352e5107627c32d3 100644 (file)
@@ -61,6 +61,7 @@
 
 #include "access/xact.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "replication/syncrep.h"
 #include "replication/walsender.h"
 #include "replication/walsender_private.h"
@@ -258,7 +259,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
                 * Wait on latch.  Any condition that should wake us up will set the
                 * latch, so no need for timeout.
                 */
-               WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1);
+               WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
+                                 WAIT_EVENT_SYNC_REP);
        }
 
        /*
index 413ee3a5c18e756e2bc083b92d1593c97dc0bcb2..eed6effeeb30d57ff64d459088d8aa9a5f6cda1c 100644 (file)
@@ -55,6 +55,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/pqsignal.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "replication/walreceiver.h"
 #include "replication/walsender.h"
 #include "storage/ipc.h"
@@ -486,7 +487,8 @@ WalReceiverMain(void)
                                                                   WL_POSTMASTER_DEATH | WL_SOCKET_READABLE |
                                                                           WL_TIMEOUT | WL_LATCH_SET,
                                                                           wait_fd,
-                                                                          NAPTIME_PER_CYCLE);
+                                                                          NAPTIME_PER_CYCLE,
+                                                                          WAIT_EVENT_WAL_RECEIVER_MAIN);
                                if (rc & WL_LATCH_SET)
                                {
                                        ResetLatch(&walrcv->latch);
@@ -685,7 +687,8 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI)
                }
                SpinLockRelease(&walrcv->mutex);
 
-               WaitLatch(&walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
+               WaitLatch(&walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
+                                 WAIT_EVENT_WAL_RECEIVER_WAIT_START);
        }
 
        if (update_process_title)
index c7743da034ac332c69d5ade737c3d07516370056..0f3ced250cd2ad6077fd3e6c8e230722d24d38f4 100644 (file)
@@ -1146,7 +1146,8 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
 
                /* Sleep until something happens or we time out */
                WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                 MyProcPort->sock, sleeptime);
+                                                 MyProcPort->sock, sleeptime,
+                                                 WAIT_EVENT_WAL_SENDER_WRITE_DATA);
        }
 
        /* reactivate latch so WalSndLoop knows to continue */
@@ -1272,7 +1273,8 @@ WalSndWaitForWal(XLogRecPtr loc)
 
                /* Sleep until something happens or we time out */
                WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                 MyProcPort->sock, sleeptime);
+                                                 MyProcPort->sock, sleeptime,
+                                                 WAIT_EVENT_WAL_SENDER_WAIT_WAL);
        }
 
        /* reactivate latch so WalSndLoop knows to continue */
@@ -1924,7 +1926,8 @@ WalSndLoop(WalSndSendDataCallback send_data)
 
                        /* Sleep until something happens or we time out */
                        WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                         MyProcPort->sock, sleeptime);
+                                                         MyProcPort->sock, sleeptime,
+                                                         WAIT_EVENT_WAL_SENDER_MAIN);
                }
        }
        return;
index 90804a3c530a1e9916fdaed0d4ac9da17bc43f1b..91dc24c301918c132e87a835d0ae95d2fed983ea 100644 (file)
@@ -3635,9 +3635,6 @@ LockBufferForCleanup(Buffer buffer)
                UnlockBufHdr(bufHdr, buf_state);
                LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 
-               /* Report the wait */
-               pgstat_report_wait_start(WAIT_BUFFER_PIN, 0);
-
                /* Wait to be signaled by UnpinBuffer() */
                if (InHotStandby)
                {
@@ -3649,9 +3646,7 @@ LockBufferForCleanup(Buffer buffer)
                        SetStartupBufferPinWaitBufId(-1);
                }
                else
-                       ProcWaitForSignal();
-
-               pgstat_report_wait_end();
+                       ProcWaitForSignal(WAIT_BUFFER_PIN);
 
                /*
                 * Remove flag marking us as waiter. Normally this will not be set
index 9def8a12d3ddfd2e5b0af7cc7a473e29edd9d04e..8488f944de523e0d42afa8a34501af2ab579c477 100644 (file)
@@ -55,6 +55,7 @@
 #endif
 
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "portability/instr_time.h"
 #include "postmaster/postmaster.h"
 #include "storage/barrier.h"
@@ -297,9 +298,11 @@ DisownLatch(volatile Latch *latch)
  * we return all of them in one call, but we will return at least one.
  */
 int
-WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
+WaitLatch(volatile Latch *latch, int wakeEvents, long timeout,
+                 uint32 wait_event_info)
 {
-       return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout);
+       return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout,
+                                                        wait_event_info);
 }
 
 /*
@@ -316,7 +319,7 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
  */
 int
 WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
-                                 long timeout)
+                                 long timeout, uint32 wait_event_info)
 {
        int                     ret = 0;
        int                     rc;
@@ -344,7 +347,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
                AddWaitEventToSet(set, ev, sock, NULL, NULL);
        }
 
-       rc = WaitEventSetWait(set, timeout, &event, 1);
+       rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
 
        if (rc == 0)
                ret |= WL_TIMEOUT;
@@ -863,7 +866,8 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event)
  */
 int
 WaitEventSetWait(WaitEventSet *set, long timeout,
-                                WaitEvent *occurred_events, int nevents)
+                                WaitEvent *occurred_events, int nevents,
+                                uint32 wait_event_info)
 {
        int                     returned_events = 0;
        instr_time      start_time;
@@ -883,6 +887,8 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
                cur_timeout = timeout;
        }
 
+       pgstat_report_wait_start(wait_event_info);
+
 #ifndef WIN32
        waiting = true;
 #else
@@ -960,6 +966,8 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
        waiting = false;
 #endif
 
+       pgstat_report_wait_end();
+
        return returned_events;
 }
 
index 5b32782022b7265c7c2d3c5f840749e37ae95852..bfb67038ad9d4c81a4c93a040a864f103a272378 100644 (file)
@@ -19,6 +19,7 @@
 #include "postgres.h"
 
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/bgworker.h"
 #include "storage/procsignal.h"
 #include "storage/shm_mq.h"
@@ -894,7 +895,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
                         * at top of loop, because setting an already-set latch is much
                         * cheaper than setting one that has been reset.
                         */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_SEND);
 
                        /* Reset the latch so we don't spin. */
                        ResetLatch(MyLatch);
@@ -991,7 +992,7 @@ shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool nowait,
                 * loop, because setting an already-set latch is much cheaper than
                 * setting one that has been reset.
                 */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_RECEIVE);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
@@ -1090,7 +1091,7 @@ shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
                }
 
                /* Wait to be signalled. */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_INTERNAL);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
index 547f1a88fe26e0ba780b69d8c03f221f562d2a45..fb887b3230ab3bad53b725d3dc24ff47f54e889a 100644 (file)
@@ -22,6 +22,7 @@
 #include "access/xlog.h"
 #include "access/xloginsert.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/proc.h"
@@ -389,7 +390,7 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
        }
 
        /* Wait to be signaled by the release of the Relation Lock */
-       ProcWaitForSignal();
+       ProcWaitForSignal(WAIT_LOCK | locktag.locktag_type);
 
        /*
         * Clear any timeout requests established above.  We assume here that the
@@ -469,7 +470,7 @@ ResolveRecoveryConflictWithBufferPin(void)
        }
 
        /* Wait to be signaled by UnpinBuffer() */
-       ProcWaitForSignal();
+       ProcWaitForSignal(WAIT_BUFFER_PIN);
 
        /*
         * Clear any timeout requests established above.  We assume here that the
index dba3809e7406bfe4954766c71ccb636a415c03eb..71a4dd4736c19100c834ba38e1fd00b668220506 100644 (file)
@@ -1676,7 +1676,6 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
                set_ps_display(new_status, false);
                new_status[len] = '\0'; /* truncate off " waiting" */
        }
-       pgstat_report_wait_start(WAIT_LOCK, locallock->tag.lock.locktag_type);
 
        awaitedLock = locallock;
        awaitedOwner = owner;
@@ -1724,7 +1723,6 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
                /* In this path, awaitedLock remains set until LockErrorCleanup */
 
                /* Report change to non-waiting status */
-               pgstat_report_wait_end();
                if (update_process_title)
                {
                        set_ps_display(new_status, false);
@@ -1739,7 +1737,6 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
        awaitedLock = NULL;
 
        /* Report change to non-waiting status */
-       pgstat_report_wait_end();
        if (update_process_title)
        {
                set_ps_display(new_status, false);
index 9d08de75ae51769497a292b836825b7c4a72deec..a90b54ac860ec2032e43e687bfb4b85949f2a415 100644 (file)
@@ -732,9 +732,9 @@ LWLockReportWaitStart(LWLock *lock)
        int                     lockId = T_ID(lock);
 
        if (lock->tranche == 0)
-               pgstat_report_wait_start(WAIT_LWLOCK_NAMED, (uint16) lockId);
+               pgstat_report_wait_start(WAIT_LWLOCK_NAMED | (uint16) lockId);
        else
-               pgstat_report_wait_start(WAIT_LWLOCK_TRANCHE, lock->tranche);
+               pgstat_report_wait_start(WAIT_LWLOCK_TRANCHE | lock->tranche);
 }
 
 /*
@@ -750,7 +750,7 @@ LWLockReportWaitEnd(void)
  * Return an identifier for an LWLock based on the wait class and event.
  */
 const char *
-GetLWLockIdentifier(uint8 classId, uint16 eventId)
+GetLWLockIdentifier(uint32 classId, uint16 eventId)
 {
        if (classId == WAIT_LWLOCK_NAMED)
                return MainLWLockNames[eventId];
index 4064b2033ccb89c02d0e52a6683557bd0bba82d9..24ed21b487e0241114dfb15200f50eac7df374f2 100644 (file)
 #include "access/xact.h"
 #include "access/xlog.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "storage/predicate_internals.h"
@@ -1518,7 +1519,7 @@ GetSafeSnapshot(Snapshot origSnapshot)
                                 SxactIsROUnsafe(MySerializableXact)))
                {
                        LWLockRelease(SerializableXactHashLock);
-                       ProcWaitForSignal();
+                       ProcWaitForSignal(WAIT_EVENT_SAFE_SNAPSHOT);
                        LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
                }
                MySerializableXact->flags &= ~SXACT_FLAG_DEFERRABLE_WAITING;
index 33e7023656a6d6d675149061369870a7dc69efec..dd76094bcd35b1eb65269faff2b58abeb26a5033 100644 (file)
@@ -39,6 +39,7 @@
 #include "access/twophase.h"
 #include "access/xact.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "replication/slot.h"
 #include "replication/syncrep.h"
@@ -1212,7 +1213,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
                }
                else
                {
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0,
+                                         WAIT_LOCK | locallock->tag.lock.locktag_type);
                        ResetLatch(MyLatch);
                        /* check for deadlocks first, as that's probably log-worthy */
                        if (got_deadlock_timeout)
@@ -1722,9 +1724,9 @@ CheckDeadLockAlert(void)
  * wait again if not.
  */
 void
-ProcWaitForSignal(void)
+ProcWaitForSignal(uint32 wait_event_info)
 {
-       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+       WaitLatch(MyLatch, WL_LATCH_SET, 0, wait_event_info);
        ResetLatch(MyLatch);
        CHECK_FOR_INTERRUPTS();
 }
index 5e705e93084c05b6926e05c52a2a05e1bcdeb973..0da051a2f2055b19af14a265d184879a4516d0a5 100644 (file)
@@ -29,6 +29,7 @@
 #include "common/keywords.h"
 #include "funcapi.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "parser/scansup.h"
 #include "postmaster/syslogger.h"
 #include "rewrite/rewriteHandler.h"
@@ -560,7 +561,8 @@ pg_sleep(PG_FUNCTION_ARGS)
 
                (void) WaitLatch(MyLatch,
                                                 WL_LATCH_SET | WL_TIMEOUT,
-                                                delay_ms);
+                                                delay_ms,
+                                                WAIT_EVENT_PG_SLEEP);
                ResetLatch(MyLatch);
        }
 
index 0c98c59e72257bde24367df14f7377553ec3bb47..b530c0198477387b276e4e10f352f31771d840e6 100644 (file)
@@ -715,15 +715,91 @@ typedef enum BackendState
  * Wait Classes
  * ----------
  */
-typedef enum WaitClass
+#define WAIT_LWLOCK_NAMED                      0x01000000U
+#define WAIT_LWLOCK_TRANCHE                    0x02000000U
+#define WAIT_LOCK                                      0x03000000U
+#define WAIT_BUFFER_PIN                                0x04000000U
+#define WAIT_ACTIVITY                          0x05000000U
+#define WAIT_CLIENT                                    0x06000000U
+#define WAIT_EXTENSION                         0x07000000U
+#define WAIT_IPC                                       0x08000000U
+#define WAIT_TIMEOUT                           0x09000000U
+
+/* ----------
+ * Wait Events - Activity
+ *
+ * Use this category when a process is waiting because it has no work to do,
+ * unless the "Client" or "Timeout" category describes the situation better.
+ * Typically, this should only be used for background processes.
+ * ----------
+ */
+typedef enum
 {
-       WAIT_UNDEFINED,
-       WAIT_LWLOCK_NAMED,
-       WAIT_LWLOCK_TRANCHE,
-       WAIT_LOCK,
-       WAIT_BUFFER_PIN
-}      WaitClass;
+       WAIT_EVENT_ARCHIVER_MAIN = WAIT_ACTIVITY,
+       WAIT_EVENT_AUTOVACUUM_MAIN,
+       WAIT_EVENT_BGWRITER_HIBERNATE,
+       WAIT_EVENT_BGWRITER_MAIN,
+       WAIT_EVENT_CHECKPOINTER_MAIN,
+       WAIT_EVENT_PGSTAT_MAIN,
+       WAIT_EVENT_RECOVERY_WAL_ALL,
+       WAIT_EVENT_RECOVERY_WAL_STREAM,
+       WAIT_EVENT_SYSLOGGER_MAIN,
+       WAIT_EVENT_WAL_RECEIVER_MAIN,
+       WAIT_EVENT_WAL_SENDER_MAIN,
+       WAIT_EVENT_WAL_WRITER_MAIN,
+} WaitEventActivity;
 
+/* ----------
+ * Wait Events - Client
+ *
+ * Use this category when a process is waiting to send data to or receive data
+ * from the frontend process to which it is connected.  This is never used for
+ * a background process, which has no client connection.
+ * ----------
+ */
+typedef enum
+{
+       WAIT_EVENT_CLIENT_READ = WAIT_CLIENT,
+       WAIT_EVENT_CLIENT_WRITE,
+       WAIT_EVENT_SSL_OPEN_SERVER,
+       WAIT_EVENT_WAL_RECEIVER_WAIT_START,
+       WAIT_EVENT_WAL_SENDER_WAIT_WAL,
+       WAIT_EVENT_WAL_SENDER_WRITE_DATA,
+} WaitEventClient;
+
+/* ----------
+ * Wait Events - IPC
+ *
+ * Use this category when a process cannot complete the work it is doing because
+ * it is waiting for a notification from another process.
+ * ----------
+ */
+typedef enum
+{
+       WAIT_EVENT_BGWORKER_SHUTDOWN = WAIT_IPC,
+       WAIT_EVENT_BGWORKER_STARTUP,
+       WAIT_EVENT_EXECUTE_GATHER,
+       WAIT_EVENT_MQ_INTERNAL,
+       WAIT_EVENT_MQ_PUT_MESSAGE,
+       WAIT_EVENT_MQ_RECEIVE,
+       WAIT_EVENT_MQ_SEND,
+       WAIT_EVENT_PARALLEL_FINISH,
+       WAIT_EVENT_SAFE_SNAPSHOT,
+       WAIT_EVENT_SYNC_REP
+} WaitEventIPC;
+
+/* ----------
+ * Wait Events - Timeout
+ *
+ * Use this category when a process is waiting for a timeout to expire.
+ * ----------
+ */
+typedef enum
+{
+       WAIT_EVENT_BASE_BACKUP_THROTTLE = WAIT_TIMEOUT,
+       WAIT_EVENT_PG_SLEEP,
+       WAIT_EVENT_RECOVERY_APPLY_DELAY
+} WaitEventTimeout;
 
 /* ----------
  * Command type for progress reporting purposes
@@ -1018,23 +1094,18 @@ extern void pgstat_initstats(Relation rel);
  * ----------
  */
 static inline void
-pgstat_report_wait_start(uint8 classId, uint16 eventId)
+pgstat_report_wait_start(uint32 wait_event_info)
 {
        volatile PGPROC *proc = MyProc;
-       uint32          wait_event_val;
 
        if (!pgstat_track_activities || !proc)
                return;
 
-       wait_event_val = classId;
-       wait_event_val <<= 24;
-       wait_event_val |= eventId;
-
        /*
         * Since this is a four-byte field which is always read and written as
         * four-bytes, updates are atomic.
         */
-       proc->wait_event_info = wait_event_val;
+       proc->wait_event_info = wait_event_info;
 }
 
 /* ----------
index 5179ecc0dbda376801eacd565150781254ed1360..e96e88f2faa3221cf9533989b35f59694b8737dd 100644 (file)
@@ -155,10 +155,13 @@ extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd,
                                  Latch *latch, void *user_data);
 extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch);
 
-extern int     WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents);
-extern int     WaitLatch(volatile Latch *latch, int wakeEvents, long timeout);
+extern int WaitEventSetWait(WaitEventSet *set, long timeout,
+                                WaitEvent *occurred_events, int nevents,
+                                uint32 wait_event_info);
+extern int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout,
+                 uint32 wait_event_info);
 extern int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents,
-                                 pgsocket sock, long timeout);
+                                 pgsocket sock, long timeout, uint32 wait_event_info);
 
 /*
  * Unix implementation uses SIGUSR1 for inter-process signaling.
index 18931eb046943cccbf909c3e363fda8dc097860f..9a2d86975cad72971c07764bd786fc893a11b07a 100644 (file)
@@ -184,7 +184,7 @@ extern Size LWLockShmemSize(void);
 extern void CreateLWLocks(void);
 extern void InitLWLockAccess(void);
 
-extern const char *GetLWLockIdentifier(uint8 classId, uint16 eventId);
+extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId);
 
 /*
  * Extensions (or core code) can obtain an LWLocks by calling
index f576f052dfe6b71737e84e663f89e0302b7b126b..7dc8dac6d1e094fe19116147834b4e1b2e4a5659 100644 (file)
@@ -291,7 +291,7 @@ extern void CheckDeadLockAlert(void);
 extern bool IsWaitingForLock(void);
 extern void LockErrorCleanup(void);
 
-extern void ProcWaitForSignal(void);
+extern void ProcWaitForSignal(uint32 wait_event_info);
 extern void ProcSendSignal(int pid);
 
 extern void BecomeLockGroupLeader(void);
index 143df4eb651b521eb039d08e410c2656af552620..cb86f3c37d4d31c6d1a75e2b4d8ae9dee5ba0826 100644 (file)
@@ -16,6 +16,7 @@
 #include "postgres.h"
 
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/bgworker.h"
 #include "storage/procsignal.h"
 #include "storage/shm_toc.h"
@@ -279,7 +280,7 @@ wait_for_workers_to_become_ready(worker_state *wstate,
                }
 
                /* Wait to be signalled. */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EXTENSION);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
index dd34bc7e7f07ec19df121f520cbf36f1e5cdad61..bf11137a9630a6210596612444542d3b2513a6c0 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "fmgr.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 
 #include "test_shm_mq.h"
 
@@ -230,7 +231,7 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
                         * have read or written data and therefore there may now be work
                         * for us to do.
                         */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EXTENSION);
                        ResetLatch(MyLatch);
                        CHECK_FOR_INTERRUPTS();
                }