On Fri, Apr 28, 2023 at 02:29:13PM +0200, Drouvot, Bertrand wrote:
> On 4/27/23 8:13 AM, Michael Paquier wrote:
>> Generating the contents of Lock would mean to gather in a single file
>> the data for the generation of LockTagType in lock.h, the list of
>> LockTagTypeNames in lockfuncs.c and the description of the docs.  This
>> data being spread across three files is not really appealing to make
>> that generated..  LWLocks would mean to either extend lwlocknames.txt
>> with the description from the docs if we were to centralize the whole
>> thing.
>> 
>> But do we need to merge more data than necessary?  We could do things
>> in the simplest fashion possible while making the docs and code
>> user-friendly in the ordering: just add a section for Lock and LWLocks
>> in waiteventnames.txt with an extra comment in their headers and/or
>> data files to tell that waiteventnames.txt also needs a refresh.
> 
> Agree that it would fix the doc ordering and that we could do that.

Not much a fan of the part where a full paragraph of the SGML docs is
added to the .txt, particularly with the new handling for "Notes".
I'd rather shape the perl script to be minimalistic and simpler, even
if it means moving this paragraph about LWLocks after all the tables
are generated.

Do we also need the comments in the generated header as well?  My
initial impression was to just move these as comments of the .txt file
because that's where the new events would be added, as the .txt is the
main point of reference.

> It's done that way in V6.
> 
> There is already comments about this in lockfuncs.c and lwlocknames.txt, so
> V6 updates those comments accordingly.
> 
> Right, done that way in V6.
> 
> Please note that it creates 2 new "wait events":
> WAIT_EVENT_EXTENSION and WAIT_EVENT_BUFFER_PIN.

Noted.  Makes sense here.

> Then, they replace PG_WAIT_EXTENSION and PG_WAIT_BUFFER_PIN (resp.) where 
> appropriate.

So, the change here..
+   # Exception here
+   if ($last =~ /^BufferPin/)
+   {
+      $last = "Buffer_Pin";
+   }

..  Implies the two following changes:
typedef enum
 {
-       WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFER_PIN
+       WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
 } WaitEventBufferPin;
[...]
 static const char *
-pgstat_get_wait_buffer_pin(WaitEventBufferPin w)
+pgstat_get_wait_bufferpin(WaitEventBufferPin w)

I would be OK to remove this exception in the script as it does not
change anything for the end user (the wait event string is still
reported as "BufferPin").  This way, we keep things simpler in the
script.  This has as extra consequence to require a change in
wait_event.h so as PG_WAIT_BUFFER_PIN is renamed to PG_WAIT_BUFFERPIN,
equally fine by me.  Logically, this rename should be done in a patch
of its own, for clarity.

@@ -185,6 +193,7 @@ distprep:
    $(MAKE) -C utils    distprep
    $(MAKE) -C utils/adt    jsonpath_gram.c jsonpath_gram.h jsonpath_scan.c
    $(MAKE) -C utils/misc   guc-file.c
+   $(MAKE) -C utils/actvity    wait_event_types.h pgstat_wait_event.c
Incorrect order, and incorrect name (s/actvity/activity/, lacking an
'i').

+printf $h $header_comment, 'wait_event_types.h';
+printf $h "#ifndef WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_H\n\n";
Inconsistency detected here.

It seems to me that we'd better have a .gitignore in utils/activity/
for the new files.

@@ -237,7 +237,7 @@ autoprewarm_main(Datum main_arg)
            (void) WaitLatch(MyLatch,
                             WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
                             -1L,
-                            PG_WAIT_EXTENSION);
+                            WAIT_EVENT_EXTENSION);

Perhaps this should also be part of a first, separate patch, with the
introduction of the new pgstat_get_wait_extension/bufferpin()
functions.  Okay, it is not a big deal because the main patch
generates the enum for extensions which would be used here, but for
the sake of history clarity I'd rather refactor and rename all that
first.

The choices of LWLOCK and LOCK for the internal names was a bit
surprising, while we can be consistent with the rest and use "LWLock"
and "Lock".

Attached is a v7 with the portions I have adjusted, which is mostly OK
by me at this point.  We are still away from the next CF, but I'll
look at that again when the v17 branch opens.
--
Michael
From d6a5c46411b5506588c77ebe52310a324e99033f Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Mon, 1 May 2023 08:51:05 +0900
Subject: [PATCH v7] Generating wait_event_types.h, pgstat_wait_event.c and
 waiteventnames.sgml

Purpose is to auto-generate those files based on the newly created waiteventnames.txt file.

Having auto generated files would help to avoid:

- wait event without description like observed in https://www.postgresql.org/message-id/CA%2BhUKGJixAHc860Ej9Qzd_z96Z6aoajAgJ18bYfV3Lfn6t9%3D%2BQ%40mail.gmail.com
- orphaned wait event like observed in https://www.postgresql.org/message-id/CA%2BhUKGK6tqm59KuF1z%2Bh5Y8fsWcu5v8%2B84kduSHwRzwjB2aa_A%40mail.gmail.com
---
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  216 +--
 src/backend/Makefile                          |   13 +-
 src/backend/storage/buffer/bufmgr.c           |    2 +-
 src/backend/storage/ipc/standby.c             |    2 +-
 src/backend/storage/lmgr/lwlocknames.txt      |    4 +-
 src/backend/utils/activity/.gitignore         |    3 +
 src/backend/utils/activity/Makefile           |   10 +
 .../utils/activity/generate-waiteventnames.pl |  213 +++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  589 +-------
 src/backend/utils/activity/waiteventnames.txt |  342 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/test/modules/test_shm_mq/setup.c          |    2 +-
 src/test/modules/test_shm_mq/test.c           |    2 +-
 src/test/modules/worker_spi/worker_spi.c      |    2 +-
 doc/src/sgml/.gitignore                       |    1 +
 doc/src/sgml/Makefile                         |    5 +-
 doc/src/sgml/filelist.sgml                    |    1 +
 doc/src/sgml/meson.build                      |   10 +
 doc/src/sgml/monitoring.sgml                  | 1271 +----------------
 contrib/dblink/dblink.c                       |    4 +-
 contrib/pg_prewarm/autoprewarm.c              |    4 +-
 contrib/postgres_fdw/connection.c             |    6 +-
 src/tools/msvc/Solution.pm                    |   18 +
 src/tools/msvc/clean.bat                      |    3 +
 src/tools/pgindent/typedefs.list              |    2 +
 29 files changed, 710 insertions(+), 2063 deletions(-)
 create mode 100644 src/backend/utils/activity/.gitignore
 create mode 100644 src/backend/utils/activity/generate-waiteventnames.pl
 create mode 100644 src/backend/utils/activity/waiteventnames.txt

diff --git a/src/include/Makefile b/src/include/Makefile
index 56576dcf5c..5d213187e2 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -72,7 +72,7 @@ uninstall:
 
 clean:
 	rm -f utils/fmgroids.h utils/fmgrprotos.h utils/errcodes.h utils/header-stamp
-	rm -f storage/lwlocknames.h utils/probes.h
+	rm -f storage/lwlocknames.h utils/probes.h utils/wait_event_types.h
 	rm -f catalog/schemapg.h catalog/system_fk_info.h
 	rm -f catalog/pg_*_d.h catalog/header-stamp
 	rm -f nodes/nodetags.h nodes/header-stamp
diff --git a/src/include/utils/.gitignore b/src/include/utils/.gitignore
index 05cfa7a8d6..c1b4c66213 100644
--- a/src/include/utils/.gitignore
+++ b/src/include/utils/.gitignore
@@ -3,3 +3,4 @@
 /probes.h
 /errcodes.h
 /header-stamp
+/wait_event_types.h
diff --git a/src/include/utils/meson.build b/src/include/utils/meson.build
index 2fed1e3f8e..a1d2d81404 100644
--- a/src/include/utils/meson.build
+++ b/src/include/utils/meson.build
@@ -1,5 +1,21 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
+waiteventnames = custom_target('waiteventnames',
+  input: files('../../backend/utils/activity/waiteventnames.txt'),
+  output: ['wait_event_types.h'],
+  command: [
+    perl, files('../../backend/utils/activity/generate-waiteventnames.pl'),
+    '-o', '@OUTDIR@',
+    '@INPUT@'
+  ],
+  build_by_default: true,
+  install: true,
+  install_dir: [dir_include_server / 'utils'],
+)
+
+wait_event_types_h = waiteventnames[0]
+generated_backend_headers += wait_event_types_h
+
 errcodes = custom_target('errcodes',
   input: files('../../backend/utils/errcodes.txt'),
   output: ['errcodes.h'],
@@ -57,3 +73,5 @@ generated_sources_ac += {
   'src/backend/utils': fmgrtab_output + ['errcodes.h', 'probes.h', 'fmgr-stamp'],
   'src/include/utils': ['header-stamp'],
 }
+
+generated_sources_ac += {'src/backend/utils/activity': ['wait_event_types.h']}
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..4517425f84 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -17,7 +17,7 @@
  */
 #define PG_WAIT_LWLOCK				0x01000000U
 #define PG_WAIT_LOCK				0x03000000U
-#define PG_WAIT_BUFFER_PIN			0x04000000U
+#define PG_WAIT_BUFFERPIN			0x04000000U
 #define PG_WAIT_ACTIVITY			0x05000000U
 #define PG_WAIT_CLIENT				0x06000000U
 #define PG_WAIT_EXTENSION			0x07000000U
@@ -25,218 +25,8 @@
 #define PG_WAIT_TIMEOUT				0x09000000U
 #define PG_WAIT_IO					0x0A000000U
 
-/* ----------
- * 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_EVENT_ARCHIVER_MAIN = PG_WAIT_ACTIVITY,
-	WAIT_EVENT_AUTOVACUUM_MAIN,
-	WAIT_EVENT_BGWRITER_HIBERNATE,
-	WAIT_EVENT_BGWRITER_MAIN,
-	WAIT_EVENT_CHECKPOINTER_MAIN,
-	WAIT_EVENT_LOGICAL_APPLY_MAIN,
-	WAIT_EVENT_LOGICAL_LAUNCHER_MAIN,
-	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN,
-	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 = PG_WAIT_CLIENT,
-	WAIT_EVENT_CLIENT_WRITE,
-	WAIT_EVENT_GSS_OPEN_SERVER,
-	WAIT_EVENT_LIBPQWALRECEIVER_CONNECT,
-	WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE,
-	WAIT_EVENT_SSL_OPEN_SERVER,
-	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_APPEND_READY = PG_WAIT_IPC,
-	WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND,
-	WAIT_EVENT_ARCHIVE_COMMAND,
-	WAIT_EVENT_BACKEND_TERMINATION,
-	WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE,
-	WAIT_EVENT_BGWORKER_SHUTDOWN,
-	WAIT_EVENT_BGWORKER_STARTUP,
-	WAIT_EVENT_BTREE_PAGE,
-	WAIT_EVENT_BUFFER_IO,
-	WAIT_EVENT_CHECKPOINT_DONE,
-	WAIT_EVENT_CHECKPOINT_START,
-	WAIT_EVENT_EXECUTE_GATHER,
-	WAIT_EVENT_HASH_BATCH_ALLOCATE,
-	WAIT_EVENT_HASH_BATCH_ELECT,
-	WAIT_EVENT_HASH_BATCH_LOAD,
-	WAIT_EVENT_HASH_BUILD_ALLOCATE,
-	WAIT_EVENT_HASH_BUILD_ELECT,
-	WAIT_EVENT_HASH_BUILD_HASH_INNER,
-	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
-	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
-	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
-	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
-	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
-	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
-	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
-	WAIT_EVENT_LOGICAL_APPLY_SEND_DATA,
-	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE,
-	WAIT_EVENT_LOGICAL_SYNC_DATA,
-	WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE,
-	WAIT_EVENT_MQ_INTERNAL,
-	WAIT_EVENT_MQ_PUT_MESSAGE,
-	WAIT_EVENT_MQ_RECEIVE,
-	WAIT_EVENT_MQ_SEND,
-	WAIT_EVENT_PARALLEL_BITMAP_SCAN,
-	WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN,
-	WAIT_EVENT_PARALLEL_FINISH,
-	WAIT_EVENT_PROCARRAY_GROUP_UPDATE,
-	WAIT_EVENT_PROC_SIGNAL_BARRIER,
-	WAIT_EVENT_PROMOTE,
-	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
-	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
-	WAIT_EVENT_RECOVERY_END_COMMAND,
-	WAIT_EVENT_RECOVERY_PAUSE,
-	WAIT_EVENT_REPLICATION_ORIGIN_DROP,
-	WAIT_EVENT_REPLICATION_SLOT_DROP,
-	WAIT_EVENT_RESTORE_COMMAND,
-	WAIT_EVENT_SAFE_SNAPSHOT,
-	WAIT_EVENT_SYNC_REP,
-	WAIT_EVENT_WAL_RECEIVER_EXIT,
-	WAIT_EVENT_WAL_RECEIVER_WAIT_START,
-	WAIT_EVENT_XACT_GROUP_UPDATE
-} WaitEventIPC;
-
-/* ----------
- * Wait Events - Timeout
- *
- * Use this category when a process is waiting for a timeout to expire.
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT,
-	WAIT_EVENT_CHECKPOINT_WRITE_DELAY,
-	WAIT_EVENT_PG_SLEEP,
-	WAIT_EVENT_RECOVERY_APPLY_DELAY,
-	WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL,
-	WAIT_EVENT_REGISTER_SYNC_REQUEST,
-	WAIT_EVENT_SPIN_DELAY,
-	WAIT_EVENT_VACUUM_DELAY,
-	WAIT_EVENT_VACUUM_TRUNCATE
-} WaitEventTimeout;
-
-/* ----------
- * Wait Events - IO
- *
- * Use this category when a process is waiting for a IO.
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BASEBACKUP_READ = PG_WAIT_IO,
-	WAIT_EVENT_BASEBACKUP_SYNC,
-	WAIT_EVENT_BASEBACKUP_WRITE,
-	WAIT_EVENT_BUFFILE_READ,
-	WAIT_EVENT_BUFFILE_WRITE,
-	WAIT_EVENT_BUFFILE_TRUNCATE,
-	WAIT_EVENT_CONTROL_FILE_READ,
-	WAIT_EVENT_CONTROL_FILE_SYNC,
-	WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE,
-	WAIT_EVENT_CONTROL_FILE_WRITE,
-	WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE,
-	WAIT_EVENT_COPY_FILE_READ,
-	WAIT_EVENT_COPY_FILE_WRITE,
-	WAIT_EVENT_DATA_FILE_EXTEND,
-	WAIT_EVENT_DATA_FILE_FLUSH,
-	WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC,
-	WAIT_EVENT_DATA_FILE_PREFETCH,
-	WAIT_EVENT_DATA_FILE_READ,
-	WAIT_EVENT_DATA_FILE_SYNC,
-	WAIT_EVENT_DATA_FILE_TRUNCATE,
-	WAIT_EVENT_DATA_FILE_WRITE,
-	WAIT_EVENT_DSM_ALLOCATE,
-	WAIT_EVENT_DSM_FILL_ZERO_WRITE,
-	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ,
-	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC,
-	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE,
-	WAIT_EVENT_LOCK_FILE_CREATE_READ,
-	WAIT_EVENT_LOCK_FILE_CREATE_SYNC,
-	WAIT_EVENT_LOCK_FILE_CREATE_WRITE,
-	WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ,
-	WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC,
-	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC,
-	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE,
-	WAIT_EVENT_LOGICAL_REWRITE_SYNC,
-	WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE,
-	WAIT_EVENT_LOGICAL_REWRITE_WRITE,
-	WAIT_EVENT_RELATION_MAP_READ,
-	WAIT_EVENT_RELATION_MAP_REPLACE,
-	WAIT_EVENT_RELATION_MAP_WRITE,
-	WAIT_EVENT_REORDER_BUFFER_READ,
-	WAIT_EVENT_REORDER_BUFFER_WRITE,
-	WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ,
-	WAIT_EVENT_REPLICATION_SLOT_READ,
-	WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC,
-	WAIT_EVENT_REPLICATION_SLOT_SYNC,
-	WAIT_EVENT_REPLICATION_SLOT_WRITE,
-	WAIT_EVENT_SLRU_FLUSH_SYNC,
-	WAIT_EVENT_SLRU_READ,
-	WAIT_EVENT_SLRU_SYNC,
-	WAIT_EVENT_SLRU_WRITE,
-	WAIT_EVENT_SNAPBUILD_READ,
-	WAIT_EVENT_SNAPBUILD_SYNC,
-	WAIT_EVENT_SNAPBUILD_WRITE,
-	WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC,
-	WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE,
-	WAIT_EVENT_TIMELINE_HISTORY_READ,
-	WAIT_EVENT_TIMELINE_HISTORY_SYNC,
-	WAIT_EVENT_TIMELINE_HISTORY_WRITE,
-	WAIT_EVENT_TWOPHASE_FILE_READ,
-	WAIT_EVENT_TWOPHASE_FILE_SYNC,
-	WAIT_EVENT_TWOPHASE_FILE_WRITE,
-	WAIT_EVENT_VERSION_FILE_WRITE,
-	WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ,
-	WAIT_EVENT_WAL_BOOTSTRAP_SYNC,
-	WAIT_EVENT_WAL_BOOTSTRAP_WRITE,
-	WAIT_EVENT_WAL_COPY_READ,
-	WAIT_EVENT_WAL_COPY_SYNC,
-	WAIT_EVENT_WAL_COPY_WRITE,
-	WAIT_EVENT_WAL_INIT_SYNC,
-	WAIT_EVENT_WAL_INIT_WRITE,
-	WAIT_EVENT_WAL_READ,
-	WAIT_EVENT_WAL_SYNC,
-	WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN,
-	WAIT_EVENT_WAL_WRITE
-} WaitEventIO;
-
+/* enums for wait events */
+#include "utils/wait_event_types.h"
 
 extern const char *pgstat_get_wait_event(uint32 wait_event_info);
 extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..f3087b922c 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -134,6 +134,9 @@ parser/gram.h: parser/gram.y
 storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl storage/lmgr/lwlocknames.txt
 	$(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c
 
+utils/activity/wait_event_types.h: utils/activity/generate-waiteventnames.pl utils/activity/waiteventnames.txt
+	$(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c
+
 # run this unconditionally to avoid needing to know its dependencies here:
 submake-catalog-headers:
 	$(MAKE) -C catalog distprep generated-header-symlinks
@@ -161,13 +164,18 @@ submake-utils-headers:
 
 .PHONY: generated-headers
 
-generated-headers: $(top_builddir)/src/include/storage/lwlocknames.h submake-catalog-headers submake-nodes-headers submake-utils-headers
+generated-headers: $(top_builddir)/src/include/storage/lwlocknames.h $(top_builddir)/src/include/utils/wait_event_types.h submake-catalog-headers submake-nodes-headers submake-utils-headers
 
 $(top_builddir)/src/include/storage/lwlocknames.h: storage/lmgr/lwlocknames.h
 	prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
 	  cd '$(dir $@)' && rm -f $(notdir $@) && \
 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
 
+$(top_builddir)/src/include/utils/wait_event_types.h: utils/activity/wait_event_types.h
+	prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
+	  cd '$(dir $@)' && rm -f $(notdir $@) && \
+	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+
 utils/probes.o: utils/probes.d $(SUBDIROBJS)
 	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
 
@@ -183,6 +191,7 @@ distprep:
 	$(MAKE) -C replication	repl_gram.c repl_gram.h repl_scanner.c syncrep_gram.c syncrep_gram.h syncrep_scanner.c
 	$(MAKE) -C storage/lmgr	lwlocknames.h lwlocknames.c
 	$(MAKE) -C utils	distprep
+	$(MAKE) -C utils/activity	wait_event_types.h pgstat_wait_event.c
 	$(MAKE) -C utils/adt	jsonpath_gram.c jsonpath_gram.h jsonpath_scan.c
 	$(MAKE) -C utils/misc	guc-file.c
 
@@ -302,6 +311,8 @@ maintainer-clean: distclean
 	      replication/syncrep_scanner.c \
 	      storage/lmgr/lwlocknames.c \
 	      storage/lmgr/lwlocknames.h \
+	      utils/activity/pgstat_wait_event.c \
+	      utils/activity/wait_event_types.h \
 	      utils/adt/jsonpath_gram.c \
 	      utils/adt/jsonpath_gram.h \
 	      utils/adt/jsonpath_scan.c \
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 1fa689052e..c7c1782461 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -4895,7 +4895,7 @@ LockBufferForCleanup(Buffer buffer)
 			SetStartupBufferPinWaitBufId(-1);
 		}
 		else
-			ProcWaitForSignal(PG_WAIT_BUFFER_PIN);
+			ProcWaitForSignal(WAIT_EVENT_BUFFER_PIN);
 
 		/*
 		 * Remove flag marking us as waiter. Normally this will not be set
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index ffe5e1563f..33188f829e 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -840,7 +840,7 @@ ResolveRecoveryConflictWithBufferPin(void)
 	 * SIGHUP signal handler, etc cannot do that because it uses the different
 	 * latch from that ProcWaitForSignal() waits on.
 	 */
-	ProcWaitForSignal(PG_WAIT_BUFFER_PIN);
+	ProcWaitForSignal(WAIT_EVENT_BUFFER_PIN);
 
 	if (got_standby_delay_timeout)
 		SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt
index 6c7cf6c295..adf7c4b2de 100644
--- a/src/backend/storage/lmgr/lwlocknames.txt
+++ b/src/backend/storage/lmgr/lwlocknames.txt
@@ -2,8 +2,8 @@
 # these are defined here.  If you add a lock, add it to the end to avoid
 # renumbering the existing locks; if you remove a lock, consider leaving a gap
 # in the numbering sequence for the benefit of DTrace and other external
-# debugging scripts.  Also, do not forget to update the list of wait events
-# in the user documentation.
+# debugging scripts.  Also, do not forget to update the section
+# WaitEventLWLock of src/backend/utils/activity/waiteventnames.txt.
 
 # 0 is available; was formerly BufFreelistLock
 ShmemIndexLock						1
diff --git a/src/backend/utils/activity/.gitignore b/src/backend/utils/activity/.gitignore
new file mode 100644
index 0000000000..0aed31dc9b
--- /dev/null
+++ b/src/backend/utils/activity/.gitignore
@@ -0,0 +1,3 @@
+/pgstat_wait_event.c
+/wait_event_types.h
+/waiteventnames.sgml
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..65487da7aa 100644
--- a/src/backend/utils/activity/Makefile
+++ b/src/backend/utils/activity/Makefile
@@ -33,3 +33,13 @@ OBJS = \
 	wait_event.o
 
 include $(top_srcdir)/src/backend/common.mk
+
+wait_event.o: pgstat_wait_event.c
+pgstat_wait_event.c: wait_event_types.h
+	touch $@
+
+wait_event_types.h: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt generate-waiteventnames.pl
+	$(PERL) $(srcdir)/generate-waiteventnames.pl $<
+
+maintainer-clean: clean
+	rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-waiteventnames.pl b/src/backend/utils/activity/generate-waiteventnames.pl
new file mode 100644
index 0000000000..741832038c
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,213 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - wait_event_types.h
+# - pgstat_wait_event.c
+# - waiteventnames.sgml
+#
+# Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/backend/utils/activity/generate-waiteventnames.pl
+#
+#----------------------------------------------------------------------
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+my $output_path = '.';
+
+my $continue = "\n";
+my %hashwe;
+my $waitclass;
+
+GetOptions('outdir:s' => \$output_path);
+
+open my $waiteventnames, '<', $ARGV[0] or die;
+
+# Include PID in suffix in case parallel make runs this multiple times.
+my $htmp = "$output_path/wait_event_types.h.tmp$$";
+my $ctmp = "$output_path/pgstat_wait_event.c.tmp$$";
+my $stmp = "$output_path/waiteventnames.s.tmp$$";
+open my $h, '>', $htmp or die "Could not open $htmp: $!";
+open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
+open my $s, '>', $stmp or die "Could not open $stmp: $!";
+
+my $header_comment =
+  '/*-------------------------------------------------------------------------
+ *
+ * %s
+ *    Generated wait events infrastructure code
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * NOTES
+ *  ******************************
+ *  *** DO NOT EDIT THIS FILE! ***
+ *  ******************************
+ *
+ *  It has been GENERATED by src/backend/utils/activity/generate-waiteventnames.pl
+ *
+ *-------------------------------------------------------------------------
+ */
+';
+
+printf $h $header_comment, 'wait_event_types.h';
+printf $h "#ifndef WAIT_EVENT_TYPES_H\n";
+printf $h "#define WAIT_EVENT_TYPES_H\n\n";
+printf $h "#include \"utils/wait_event.h\"\n\n";
+
+printf $c $header_comment, 'pgstat_wait_event.c';
+
+my @lines;
+my $line;
+my $section_name;
+my $note;
+my $note_name;
+
+# Remove comments and empty lines and add waitclassname based on the section
+while (<$waiteventnames>)
+{
+	chomp;
+
+	# Skip comments
+	next if /^#/;
+
+	# Skip empty lines
+	next if /^\s*$/;
+
+	# Get waitclassname based on the section
+	if (/^Section: ClassName(.*)/)
+	{
+		$section_name = $_;
+		$section_name =~ s/^.*- //;
+		next;
+	}
+
+	push(@lines, $section_name . "\t" . $_);
+}
+
+# Sort the lines based on the second column
+my @lines_sorted =
+  sort { (split(/\t/, $a))[1] cmp(split(/\t/, $b))[1] } @lines;
+
+# Read the sorted lines and populate the hash table
+foreach $line (@lines_sorted)
+{
+	die "unable to parse waiteventnames.txt"
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+
+	(   my $waitclassname,
+		my $waiteventenumname,
+		my $waiteventdescription,
+		my $waitevendocsentence) = split(/\t/, $line);
+
+	my @waiteventlist =
+	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
+	my $trimmedwaiteventname = $waiteventenumname;
+	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
+
+	# An exception is required for LWLock and Lock as these don't require
+	# any C and header files generated.
+	die "wait event names must start with 'WAIT_EVENT_'"
+	  if ($trimmedwaiteventname eq $waiteventenumname && $waiteventenumname !~ /^LWLock/ && $waiteventenumname !~ /^Lock/) ;
+	$continue = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the .c and .h files
+foreach $waitclass (sort keys %hashwe)
+{
+
+	# Don't generate .c and .h files for LWLock and Lock, these are
+	# handled independently.
+	next if ($waitclass =~ /^WaitEventLWLock$/ || $waitclass =~ /^WaitEventLock$/);
+
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastuc    = uc $last;
+	my $lastlc    = lc $last;
+	my $firstpass = 1;
+	my $pg_wait_class;
+
+	printf $c
+	  "static const char *\npgstat_get_wait_$lastlc($waitclass w)\n{\n";
+	printf $c "\tconst char *event_name = \"unknown wait event\";\n\n";
+	printf $c "\tswitch (w)\n\t{\n";
+
+	foreach my $wev (@{ $hashwe{$waitclass} })
+	{
+		if ($firstpass)
+		{
+			printf $h "typedef enum\n{\n";
+			$pg_wait_class = "PG_WAIT_" . $lastuc;
+			printf $h "\t%s = %s", $wev->[0], $pg_wait_class;
+			$continue = ",\n";
+		}
+		else
+		{
+			printf $h "%s\t%s", $continue, $wev->[0];
+			$continue = ",\n";
+		}
+		$firstpass = 0;
+
+		printf $c "\t\t case %s:\n",                          $wev->[0];
+		printf $c "\t\t\t event_name = %s;\n\t\t\t break;\n", $wev->[1];
+	}
+
+	printf $h "\n} $waitclass;\n\n";
+
+	printf $c "\t\t\t /* no default case, so that compiler will warn */\n";
+	printf $c "\t}\n\n";
+	printf $c "\treturn event_name;\n";
+	printf $c "}\n\n";
+}
+
+printf $h "#endif                          /* WAIT_EVENT_TYPES_H */";
+close $h;
+close $c;
+
+# Generate the .sgml file
+foreach $waitclass (sort keys %hashwe)
+{
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastlc    = lc $last;
+
+	printf $s "  <table id=\"wait-event-%s-table\">\n", $lastlc;
+	printf $s "   <title>Wait Events of Type <literal>%s</literal></title>\n",
+	  ucfirst($lastlc);
+	printf $s "   <tgroup cols=\"2\">\n";
+	printf $s "    <thead>\n";
+	printf $s "     <row>\n";
+	printf $s "      <entry><literal>$last</literal> Wait Event</entry>\n";
+	printf $s "      <entry>Description</entry>\n";
+	printf $s "     </row>\n";
+	printf $s "    </thead>\n\n";
+	printf $s "    <tbody>\n";
+
+	foreach my $wev (@{ $hashwe{$waitclass} })
+	{
+		printf $s "     <row>\n";
+		printf $s "      <entry><literal>%s</literal></entry>\n",
+		  substr $wev->[1], 1, -1;
+		printf $s "      <entry>%s</entry>\n", substr $wev->[2], 1, -1;
+		printf $s "     </row>\n";
+	}
+
+	printf $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n\n";
+}
+
+close $s;
+
+rename($htmp, "$output_path/wait_event_types.h")
+  || die "rename: $htmp to $output_path/wait_event_types.h: $!";
+rename($ctmp, "$output_path/pgstat_wait_event.c") || die "rename: $ctmp: $!";
+rename($stmp, "$output_path/waiteventnames.sgml") || die "rename: $ctmp: $!";
+
+close $waiteventnames;
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index 518ee3f798..83004c986a 100644
--- a/src/backend/utils/activity/meson.build
+++ b/src/backend/utils/activity/meson.build
@@ -1,5 +1,17 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
+waiteventnames = custom_target('waiteventnames',
+  input: files('./waiteventnames.txt'),
+  output: ['pgstat_wait_event.c'],
+  command: [
+    perl, files('./generate-waiteventnames.pl'),
+    '-o', '@OUTDIR@',
+    '@INPUT@'
+  ],
+  install: true,
+  install_dir: [false],
+)
+
 backend_sources += files(
   'backend_progress.c',
   'backend_status.c',
@@ -17,5 +29,17 @@ backend_sources += files(
   'pgstat_subscription.c',
   'pgstat_wal.c',
   'pgstat_xact.c',
+)
+
+# these include .c files generated in ../../../include/activity, seems nicer to not
+# add that as an include path for the whole backend
+waitevent_sources = files(
   'wait_event.c',
 )
+
+backend_link_with += static_library('waiteventnames',
+  waitevent_sources,
+  dependencies: [backend_code],
+  include_directories: include_directories('../../../include/utils'),
+  kwargs: internal_lib_args,
+)
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 7940d64639..4aad11c111 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -28,7 +28,9 @@
 
 
 static const char *pgstat_get_wait_activity(WaitEventActivity w);
+static const char *pgstat_get_wait_bufferpin(WaitEventBufferPin w);
 static const char *pgstat_get_wait_client(WaitEventClient w);
+static const char *pgstat_get_wait_extension(WaitEventExtension w);
 static const char *pgstat_get_wait_ipc(WaitEventIPC w);
 static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
 static const char *pgstat_get_wait_io(WaitEventIO w);
@@ -90,7 +92,7 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
 		case PG_WAIT_LOCK:
 			event_type = "Lock";
 			break;
-		case PG_WAIT_BUFFER_PIN:
+		case PG_WAIT_BUFFERPIN:
 			event_type = "BufferPin";
 			break;
 		case PG_WAIT_ACTIVITY:
@@ -147,9 +149,13 @@ pgstat_get_wait_event(uint32 wait_event_info)
 		case PG_WAIT_LOCK:
 			event_name = GetLockNameFromTagType(eventId);
 			break;
-		case PG_WAIT_BUFFER_PIN:
-			event_name = "BufferPin";
-			break;
+		case PG_WAIT_BUFFERPIN:
+			{
+				WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info;
+
+				event_name = pgstat_get_wait_bufferpin(w);
+				break;
+			}
 		case PG_WAIT_ACTIVITY:
 			{
 				WaitEventActivity w = (WaitEventActivity) wait_event_info;
@@ -165,8 +171,12 @@ pgstat_get_wait_event(uint32 wait_event_info)
 				break;
 			}
 		case PG_WAIT_EXTENSION:
-			event_name = "Extension";
-			break;
+			{
+				WaitEventExtension w = (WaitEventExtension) wait_event_info;
+
+				event_name = pgstat_get_wait_extension(w);
+				break;
+			}
 		case PG_WAIT_IPC:
 			{
 				WaitEventIPC w = (WaitEventIPC) wait_event_info;
@@ -196,569 +206,4 @@ 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_LOGICAL_APPLY_MAIN:
-			event_name = "LogicalApplyMain";
-			break;
-		case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN:
-			event_name = "LogicalLauncherMain";
-			break;
-		case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN:
-			event_name = "LogicalParallelApplyMain";
-			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_GSS_OPEN_SERVER:
-			event_name = "GSSOpenServer";
-			break;
-		case WAIT_EVENT_LIBPQWALRECEIVER_CONNECT:
-			event_name = "LibPQWalReceiverConnect";
-			break;
-		case WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE:
-			event_name = "LibPQWalReceiverReceive";
-			break;
-		case WAIT_EVENT_SSL_OPEN_SERVER:
-			event_name = "SSLOpenServer";
-			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_APPEND_READY:
-			event_name = "AppendReady";
-			break;
-		case WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND:
-			event_name = "ArchiveCleanupCommand";
-			break;
-		case WAIT_EVENT_ARCHIVE_COMMAND:
-			event_name = "ArchiveCommand";
-			break;
-		case WAIT_EVENT_BACKEND_TERMINATION:
-			event_name = "BackendTermination";
-			break;
-		case WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE:
-			event_name = "BackupWaitWalArchive";
-			break;
-		case WAIT_EVENT_BGWORKER_SHUTDOWN:
-			event_name = "BgWorkerShutdown";
-			break;
-		case WAIT_EVENT_BGWORKER_STARTUP:
-			event_name = "BgWorkerStartup";
-			break;
-		case WAIT_EVENT_BTREE_PAGE:
-			event_name = "BtreePage";
-			break;
-		case WAIT_EVENT_BUFFER_IO:
-			event_name = "BufferIO";
-			break;
-		case WAIT_EVENT_CHECKPOINT_DONE:
-			event_name = "CheckpointDone";
-			break;
-		case WAIT_EVENT_CHECKPOINT_START:
-			event_name = "CheckpointStart";
-			break;
-		case WAIT_EVENT_EXECUTE_GATHER:
-			event_name = "ExecuteGather";
-			break;
-		case WAIT_EVENT_HASH_BATCH_ALLOCATE:
-			event_name = "HashBatchAllocate";
-			break;
-		case WAIT_EVENT_HASH_BATCH_ELECT:
-			event_name = "HashBatchElect";
-			break;
-		case WAIT_EVENT_HASH_BATCH_LOAD:
-			event_name = "HashBatchLoad";
-			break;
-		case WAIT_EVENT_HASH_BUILD_ALLOCATE:
-			event_name = "HashBuildAllocate";
-			break;
-		case WAIT_EVENT_HASH_BUILD_ELECT:
-			event_name = "HashBuildElect";
-			break;
-		case WAIT_EVENT_HASH_BUILD_HASH_INNER:
-			event_name = "HashBuildHashInner";
-			break;
-		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
-			event_name = "HashBuildHashOuter";
-			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
-			event_name = "HashGrowBatchesDecide";
-			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ELECT:
-			event_name = "HashGrowBatchesElect";
-			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_FINISH:
-			event_name = "HashGrowBatchesFinish";
-			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
-			event_name = "HashGrowBatchesReallocate";
-			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
-			event_name = "HashGrowBatchesRepartition";
-			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
-			event_name = "HashGrowBucketsElect";
-			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
-			event_name = "HashGrowBucketsReallocate";
-			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT:
-			event_name = "HashGrowBucketsReinsert";
-			break;
-		case WAIT_EVENT_LOGICAL_APPLY_SEND_DATA:
-			event_name = "LogicalApplySendData";
-			break;
-		case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE:
-			event_name = "LogicalParallelApplyStateChange";
-			break;
-		case WAIT_EVENT_LOGICAL_SYNC_DATA:
-			event_name = "LogicalSyncData";
-			break;
-		case WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE:
-			event_name = "LogicalSyncStateChange";
-			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_BITMAP_SCAN:
-			event_name = "ParallelBitmapScan";
-			break;
-		case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN:
-			event_name = "ParallelCreateIndexScan";
-			break;
-		case WAIT_EVENT_PARALLEL_FINISH:
-			event_name = "ParallelFinish";
-			break;
-		case WAIT_EVENT_PROCARRAY_GROUP_UPDATE:
-			event_name = "ProcArrayGroupUpdate";
-			break;
-		case WAIT_EVENT_PROC_SIGNAL_BARRIER:
-			event_name = "ProcSignalBarrier";
-			break;
-		case WAIT_EVENT_PROMOTE:
-			event_name = "Promote";
-			break;
-		case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT:
-			event_name = "RecoveryConflictSnapshot";
-			break;
-		case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE:
-			event_name = "RecoveryConflictTablespace";
-			break;
-		case WAIT_EVENT_RECOVERY_END_COMMAND:
-			event_name = "RecoveryEndCommand";
-			break;
-		case WAIT_EVENT_RECOVERY_PAUSE:
-			event_name = "RecoveryPause";
-			break;
-		case WAIT_EVENT_REPLICATION_ORIGIN_DROP:
-			event_name = "ReplicationOriginDrop";
-			break;
-		case WAIT_EVENT_REPLICATION_SLOT_DROP:
-			event_name = "ReplicationSlotDrop";
-			break;
-		case WAIT_EVENT_RESTORE_COMMAND:
-			event_name = "RestoreCommand";
-			break;
-		case WAIT_EVENT_SAFE_SNAPSHOT:
-			event_name = "SafeSnapshot";
-			break;
-		case WAIT_EVENT_SYNC_REP:
-			event_name = "SyncRep";
-			break;
-		case WAIT_EVENT_WAL_RECEIVER_EXIT:
-			event_name = "WalReceiverExit";
-			break;
-		case WAIT_EVENT_WAL_RECEIVER_WAIT_START:
-			event_name = "WalReceiverWaitStart";
-			break;
-		case WAIT_EVENT_XACT_GROUP_UPDATE:
-			event_name = "XactGroupUpdate";
-			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_CHECKPOINT_WRITE_DELAY:
-			event_name = "CheckpointWriteDelay";
-			break;
-		case WAIT_EVENT_PG_SLEEP:
-			event_name = "PgSleep";
-			break;
-		case WAIT_EVENT_RECOVERY_APPLY_DELAY:
-			event_name = "RecoveryApplyDelay";
-			break;
-		case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL:
-			event_name = "RecoveryRetrieveRetryInterval";
-			break;
-		case WAIT_EVENT_REGISTER_SYNC_REQUEST:
-			event_name = "RegisterSyncRequest";
-			break;
-		case WAIT_EVENT_SPIN_DELAY:
-			event_name = "SpinDelay";
-			break;
-		case WAIT_EVENT_VACUUM_DELAY:
-			event_name = "VacuumDelay";
-			break;
-		case WAIT_EVENT_VACUUM_TRUNCATE:
-			event_name = "VacuumTruncate";
-			break;
-			/* no default case, so that compiler will warn */
-	}
-
-	return event_name;
-}
-
-/* ----------
- * pgstat_get_wait_io() -
- *
- * Convert WaitEventIO to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_io(WaitEventIO w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_BASEBACKUP_READ:
-			event_name = "BaseBackupRead";
-			break;
-		case WAIT_EVENT_BASEBACKUP_SYNC:
-			event_name = "BaseBackupSync";
-			break;
-		case WAIT_EVENT_BASEBACKUP_WRITE:
-			event_name = "BaseBackupWrite";
-			break;
-		case WAIT_EVENT_BUFFILE_READ:
-			event_name = "BufFileRead";
-			break;
-		case WAIT_EVENT_BUFFILE_WRITE:
-			event_name = "BufFileWrite";
-			break;
-		case WAIT_EVENT_BUFFILE_TRUNCATE:
-			event_name = "BufFileTruncate";
-			break;
-		case WAIT_EVENT_CONTROL_FILE_READ:
-			event_name = "ControlFileRead";
-			break;
-		case WAIT_EVENT_CONTROL_FILE_SYNC:
-			event_name = "ControlFileSync";
-			break;
-		case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE:
-			event_name = "ControlFileSyncUpdate";
-			break;
-		case WAIT_EVENT_CONTROL_FILE_WRITE:
-			event_name = "ControlFileWrite";
-			break;
-		case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE:
-			event_name = "ControlFileWriteUpdate";
-			break;
-		case WAIT_EVENT_COPY_FILE_READ:
-			event_name = "CopyFileRead";
-			break;
-		case WAIT_EVENT_COPY_FILE_WRITE:
-			event_name = "CopyFileWrite";
-			break;
-		case WAIT_EVENT_DATA_FILE_EXTEND:
-			event_name = "DataFileExtend";
-			break;
-		case WAIT_EVENT_DATA_FILE_FLUSH:
-			event_name = "DataFileFlush";
-			break;
-		case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC:
-			event_name = "DataFileImmediateSync";
-			break;
-		case WAIT_EVENT_DATA_FILE_PREFETCH:
-			event_name = "DataFilePrefetch";
-			break;
-		case WAIT_EVENT_DATA_FILE_READ:
-			event_name = "DataFileRead";
-			break;
-		case WAIT_EVENT_DATA_FILE_SYNC:
-			event_name = "DataFileSync";
-			break;
-		case WAIT_EVENT_DATA_FILE_TRUNCATE:
-			event_name = "DataFileTruncate";
-			break;
-		case WAIT_EVENT_DATA_FILE_WRITE:
-			event_name = "DataFileWrite";
-			break;
-		case WAIT_EVENT_DSM_ALLOCATE:
-			event_name = "DSMAllocate";
-			break;
-		case WAIT_EVENT_DSM_FILL_ZERO_WRITE:
-			event_name = "DSMFillZeroWrite";
-			break;
-		case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ:
-			event_name = "LockFileAddToDataDirRead";
-			break;
-		case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC:
-			event_name = "LockFileAddToDataDirSync";
-			break;
-		case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE:
-			event_name = "LockFileAddToDataDirWrite";
-			break;
-		case WAIT_EVENT_LOCK_FILE_CREATE_READ:
-			event_name = "LockFileCreateRead";
-			break;
-		case WAIT_EVENT_LOCK_FILE_CREATE_SYNC:
-			event_name = "LockFileCreateSync";
-			break;
-		case WAIT_EVENT_LOCK_FILE_CREATE_WRITE:
-			event_name = "LockFileCreateWrite";
-			break;
-		case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ:
-			event_name = "LockFileReCheckDataDirRead";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC:
-			event_name = "LogicalRewriteCheckpointSync";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC:
-			event_name = "LogicalRewriteMappingSync";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE:
-			event_name = "LogicalRewriteMappingWrite";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_SYNC:
-			event_name = "LogicalRewriteSync";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE:
-			event_name = "LogicalRewriteTruncate";
-			break;
-		case WAIT_EVENT_LOGICAL_REWRITE_WRITE:
-			event_name = "LogicalRewriteWrite";
-			break;
-		case WAIT_EVENT_RELATION_MAP_READ:
-			event_name = "RelationMapRead";
-			break;
-		case WAIT_EVENT_RELATION_MAP_REPLACE:
-			event_name = "RelationMapReplace";
-			break;
-		case WAIT_EVENT_RELATION_MAP_WRITE:
-			event_name = "RelationMapWrite";
-			break;
-		case WAIT_EVENT_REORDER_BUFFER_READ:
-			event_name = "ReorderBufferRead";
-			break;
-		case WAIT_EVENT_REORDER_BUFFER_WRITE:
-			event_name = "ReorderBufferWrite";
-			break;
-		case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ:
-			event_name = "ReorderLogicalMappingRead";
-			break;
-		case WAIT_EVENT_REPLICATION_SLOT_READ:
-			event_name = "ReplicationSlotRead";
-			break;
-		case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC:
-			event_name = "ReplicationSlotRestoreSync";
-			break;
-		case WAIT_EVENT_REPLICATION_SLOT_SYNC:
-			event_name = "ReplicationSlotSync";
-			break;
-		case WAIT_EVENT_REPLICATION_SLOT_WRITE:
-			event_name = "ReplicationSlotWrite";
-			break;
-		case WAIT_EVENT_SLRU_FLUSH_SYNC:
-			event_name = "SLRUFlushSync";
-			break;
-		case WAIT_EVENT_SLRU_READ:
-			event_name = "SLRURead";
-			break;
-		case WAIT_EVENT_SLRU_SYNC:
-			event_name = "SLRUSync";
-			break;
-		case WAIT_EVENT_SLRU_WRITE:
-			event_name = "SLRUWrite";
-			break;
-		case WAIT_EVENT_SNAPBUILD_READ:
-			event_name = "SnapbuildRead";
-			break;
-		case WAIT_EVENT_SNAPBUILD_SYNC:
-			event_name = "SnapbuildSync";
-			break;
-		case WAIT_EVENT_SNAPBUILD_WRITE:
-			event_name = "SnapbuildWrite";
-			break;
-		case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC:
-			event_name = "TimelineHistoryFileSync";
-			break;
-		case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE:
-			event_name = "TimelineHistoryFileWrite";
-			break;
-		case WAIT_EVENT_TIMELINE_HISTORY_READ:
-			event_name = "TimelineHistoryRead";
-			break;
-		case WAIT_EVENT_TIMELINE_HISTORY_SYNC:
-			event_name = "TimelineHistorySync";
-			break;
-		case WAIT_EVENT_TIMELINE_HISTORY_WRITE:
-			event_name = "TimelineHistoryWrite";
-			break;
-		case WAIT_EVENT_TWOPHASE_FILE_READ:
-			event_name = "TwophaseFileRead";
-			break;
-		case WAIT_EVENT_TWOPHASE_FILE_SYNC:
-			event_name = "TwophaseFileSync";
-			break;
-		case WAIT_EVENT_TWOPHASE_FILE_WRITE:
-			event_name = "TwophaseFileWrite";
-			break;
-		case WAIT_EVENT_VERSION_FILE_WRITE:
-			event_name = "VersionFileWrite";
-			break;
-		case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ:
-			event_name = "WALSenderTimelineHistoryRead";
-			break;
-		case WAIT_EVENT_WAL_BOOTSTRAP_SYNC:
-			event_name = "WALBootstrapSync";
-			break;
-		case WAIT_EVENT_WAL_BOOTSTRAP_WRITE:
-			event_name = "WALBootstrapWrite";
-			break;
-		case WAIT_EVENT_WAL_COPY_READ:
-			event_name = "WALCopyRead";
-			break;
-		case WAIT_EVENT_WAL_COPY_SYNC:
-			event_name = "WALCopySync";
-			break;
-		case WAIT_EVENT_WAL_COPY_WRITE:
-			event_name = "WALCopyWrite";
-			break;
-		case WAIT_EVENT_WAL_INIT_SYNC:
-			event_name = "WALInitSync";
-			break;
-		case WAIT_EVENT_WAL_INIT_WRITE:
-			event_name = "WALInitWrite";
-			break;
-		case WAIT_EVENT_WAL_READ:
-			event_name = "WALRead";
-			break;
-		case WAIT_EVENT_WAL_SYNC:
-			event_name = "WALSync";
-			break;
-		case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN:
-			event_name = "WALSyncMethodAssign";
-			break;
-		case WAIT_EVENT_WAL_WRITE:
-			event_name = "WALWrite";
-			break;
-
-			/* no default case, so that compiler will warn */
-	}
-
-	return event_name;
-}
+#include "pgstat_wait_event.c"
diff --git a/src/backend/utils/activity/waiteventnames.txt b/src/backend/utils/activity/waiteventnames.txt
new file mode 100644
index 0000000000..411970391c
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,342 @@
+#
+# waiteventnames.txt
+#      PostgreSQL wait events
+#
+# Copyright (c) 2023, PostgreSQL Global Development Group
+#
+# This list serves as the basis for generating source files related to wait
+# events.
+#
+# The files generated from this one are:
+#
+#   src/backend/utils/activity/wait_event_types.h
+#      typedef enum definitions for wait events.
+#
+#   src/backend/utils/activity/pgstat_wait_event.c
+#      C functions to get the wait event name based on the enum.
+#
+#   src/backend/utils/activity/waiteventnames.sgml
+#      SGML tables of wait events for inclusion in the documentation.
+#
+# The format of this file is one wait event per line, with the three following
+# tab-separated fields:
+#
+#      "C symbol in enums" "format in the system views" "description in the docs"
+#
+# When adding a new wait event, make sure it is placed in the appropriate
+# ClassName section.
+#
+# WaitEventLWLock and WaitEventLock have their own C code for their wait event
+# enums and function names.  Hence, for these, only the SGML documentation is
+# generated.
+#
+# This file is fed to src/backend/utils/activity/generate-waiteventnames.pl.
+#
+
+
+#
+# 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.
+#
+
+Section: ClassName - WaitEventActivity
+
+WAIT_EVENT_ARCHIVER_MAIN	"ArchiverMain"	"Waiting in main loop of archiver process."
+WAIT_EVENT_AUTOVACUUM_MAIN	"AutoVacuumMain"	"Waiting in main loop of autovacuum launcher process."
+WAIT_EVENT_BGWRITER_HIBERNATE	"BgWriterHibernate"	"Waiting in background writer process, hibernating."
+WAIT_EVENT_BGWRITER_MAIN	"BgWriterMain"	"Waiting in main loop of background writer process."
+WAIT_EVENT_CHECKPOINTER_MAIN	"CheckpointerMain"	"Waiting in main loop of checkpointer process."
+WAIT_EVENT_LOGICAL_APPLY_MAIN	"LogicalApplyMain"	"Waiting in main loop of logical replication apply process."
+WAIT_EVENT_LOGICAL_LAUNCHER_MAIN	"LogicalLauncherMain"	"Waiting in main loop of logical replication launcher process."
+WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN	"LogicalParallelApplyMain"	"Waiting in main loop of logical replication parallel apply process."
+WAIT_EVENT_RECOVERY_WAL_STREAM	"RecoveryWalStream"	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+WAIT_EVENT_SYSLOGGER_MAIN	"SysLoggerMain"	"Waiting in main loop of syslogger process."
+WAIT_EVENT_WAL_RECEIVER_MAIN	"WalReceiverMain"	"Waiting in main loop of WAL receiver process."
+WAIT_EVENT_WAL_SENDER_MAIN	"WalSenderMain"	"Waiting in main loop of WAL sender process."
+WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer process."
+
+
+#
+# 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.
+#
+
+Section: ClassName - WaitEventClient
+
+WAIT_EVENT_CLIENT_READ	"ClientRead"	"Waiting to read data from the client."
+WAIT_EVENT_CLIENT_WRITE	"ClientWrite"	"Waiting to write data to the client."
+WAIT_EVENT_GSS_OPEN_SERVER	"GSSOpenServer"	"Waiting to read data from the client while establishing a GSSAPI session."
+WAIT_EVENT_LIBPQWALRECEIVER_CONNECT	"LibPQWalReceiverConnect"	"Waiting in WAL receiver to establish connection to remote server."
+WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE	"LibPQWalReceiverReceive"	"Waiting in WAL receiver to receive data from remote server."
+WAIT_EVENT_SSL_OPEN_SERVER	"SSLOpenServer"	"Waiting for SSL while attempting connection."
+WAIT_EVENT_WAL_SENDER_WAIT_WAL	"WalSenderWaitForWAL"	"Waiting for WAL to be flushed in WAL sender process."
+WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
+
+
+#
+# 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.
+#
+
+Section: ClassName - WaitEventIPC
+
+WAIT_EVENT_APPEND_READY	"AppendReady"	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	"ArchiveCleanupCommand"	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+WAIT_EVENT_ARCHIVE_COMMAND	"ArchiveCommand"	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+WAIT_EVENT_BACKEND_TERMINATION	"BackendTermination"	"Waiting for the termination of another backend."
+WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE	"BackupWaitWalArchive"	"Waiting for WAL files required for a backup to be successfully archived."
+WAIT_EVENT_BGWORKER_SHUTDOWN	"BgWorkerShutdown"	"Waiting for background worker to shut down."
+WAIT_EVENT_BGWORKER_STARTUP	"BgWorkerStartup"	"Waiting for background worker to start up."
+WAIT_EVENT_BTREE_PAGE	"BtreePage"	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+WAIT_EVENT_BUFFER_IO	"BufferIO"	"Waiting for buffer I/O to complete."
+WAIT_EVENT_CHECKPOINT_DONE	"CheckpointDone"	"Waiting for a checkpoint to complete."
+WAIT_EVENT_CHECKPOINT_START	"CheckpointStart"	"Waiting for a checkpoint to start."
+WAIT_EVENT_EXECUTE_GATHER	"ExecuteGather"	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+WAIT_EVENT_HASH_BATCH_ALLOCATE	"HashBatchAllocate"	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+WAIT_EVENT_HASH_BATCH_ELECT	"HashBatchElect"	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+WAIT_EVENT_HASH_BATCH_LOAD	"HashBatchLoad"	"Waiting for other Parallel Hash participants to finish loading a hash table."
+WAIT_EVENT_HASH_BUILD_ALLOCATE	"HashBuildAllocate"	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+WAIT_EVENT_HASH_BUILD_ELECT	"HashBuildElect"	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+WAIT_EVENT_HASH_BUILD_HASH_INNER	"HashBuildHashInner"	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+WAIT_EVENT_HASH_BUILD_HASH_OUTER	"HashBuildHashOuter"	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+WAIT_EVENT_HASH_GROW_BATCHES_DECIDE	"HashGrowBatchesDecide"	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+WAIT_EVENT_HASH_GROW_BATCHES_ELECT	"HashGrowBatchesElect"	"Waiting to elect a Parallel Hash participant to allocate more batches."
+WAIT_EVENT_HASH_GROW_BATCHES_FINISH	"HashGrowBatchesFinish"	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE	"HashGrowBatchesReallocate"	"Waiting for an elected Parallel Hash participant to allocate more batches."
+WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION	"HashGrowBatchesRepartition"	"Waiting for other Parallel Hash participants to finish repartitioning."
+WAIT_EVENT_HASH_GROW_BUCKETS_ELECT	"HashGrowBucketsElect"	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE	"HashGrowBucketsReallocate"	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT	"HashGrowBucketsReinsert"	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	"LogicalApplySendData"	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"LogicalParallelApplyStateChange"	"Waiting for a logical replication parallel apply process to change state."
+WAIT_EVENT_LOGICAL_SYNC_DATA	"LogicalSyncData"	"Waiting for a logical replication remote server to send data for initial table synchronization."
+WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE	"LogicalSyncStateChange"	"Waiting for a logical replication remote server to change state."
+WAIT_EVENT_MQ_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MQ_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MQ_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MQ_SEND	"MessageQueueSend"	"Waiting to send bytes to a shared message queue."
+WAIT_EVENT_PARALLEL_BITMAP_SCAN	"ParallelBitmapScan"	"Waiting for parallel bitmap scan to become initialized."
+WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN	"ParallelCreateIndexScan"	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+WAIT_EVENT_PARALLEL_FINISH	"ParallelFinish"	"Waiting for parallel workers to finish computing."
+WAIT_EVENT_PROCARRAY_GROUP_UPDATE	"ProcArrayGroupUpdate"	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+WAIT_EVENT_PROC_SIGNAL_BARRIER	"ProcSignalBarrier"	"Waiting for a barrier event to be processed by all backends."
+WAIT_EVENT_PROMOTE	"Promote"	"Waiting for standby promotion."
+WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT	"RecoveryConflictSnapshot"	"Waiting for recovery conflict resolution for a vacuum cleanup."
+WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE	"RecoveryConflictTablespace"	"Waiting for recovery conflict resolution for dropping a tablespace."
+WAIT_EVENT_RECOVERY_END_COMMAND	"RecoveryEndCommand"	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+WAIT_EVENT_RECOVERY_PAUSE	"RecoveryPause"	"Waiting for recovery to be resumed."
+WAIT_EVENT_REPLICATION_ORIGIN_DROP	"ReplicationOriginDrop"	"Waiting for a replication origin to become inactive so it can be dropped."
+WAIT_EVENT_REPLICATION_SLOT_DROP	"ReplicationSlotDrop"	"Waiting for a replication slot to become inactive so it can be dropped."
+WAIT_EVENT_RESTORE_COMMAND	"RestoreCommand"	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+WAIT_EVENT_SAFE_SNAPSHOT	"SafeSnapshot"	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+WAIT_EVENT_SYNC_REP	"SyncRep"	"Waiting for confirmation from a remote server during synchronous replication. Waiting to read or update information about the state of synchronous replication."
+WAIT_EVENT_WAL_RECEIVER_EXIT	"WalReceiverExit"	"Waiting for the WAL receiver to exit."
+WAIT_EVENT_WAL_RECEIVER_WAIT_START	"WalReceiverWaitStart"	"Waiting for startup process to send initial data for streaming replication."
+WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to update transaction status at end of a parallel operation."
+
+
+#
+# Wait Events - Timeout
+#
+# Use this category when a process is waiting for a timeout to expire.
+#
+
+Section: ClassName - WaitEventTimeout
+
+WAIT_EVENT_BASE_BACKUP_THROTTLE	"BaseBackupThrottle"	"Waiting during base backup when throttling activity."
+WAIT_EVENT_CHECKPOINT_WRITE_DELAY	"CheckpointWriteDelay"	"Waiting between writes while performing a checkpoint."
+WAIT_EVENT_PG_SLEEP	"PgSleep"	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+WAIT_EVENT_RECOVERY_APPLY_DELAY	"RecoveryApplyDelay"	"Waiting to apply WAL during recovery because of a delay setting."
+WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL	"RecoveryRetrieveRetryInterval"	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+WAIT_EVENT_REGISTER_SYNC_REQUEST	"RegisterSyncRequest"	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+WAIT_EVENT_SPIN_DELAY	"SpinDelay"	"Waiting while acquiring a contended spinlock."
+WAIT_EVENT_VACUUM_DELAY	"VacuumDelay"	"Waiting in a cost-based vacuum delay point."
+WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
+
+
+#
+# Wait Events - IO
+#
+# Use this category when a process is waiting for a IO.
+#
+
+Section: ClassName - WaitEventIO
+
+WAIT_EVENT_BASEBACKUP_READ	"BaseBackupRead"	"Waiting for base backup to read from a file."
+WAIT_EVENT_BASEBACKUP_SYNC	"BaseBackupSync"	"Waiting for data written by a base backup to reach durable storage."
+WAIT_EVENT_BASEBACKUP_WRITE	"BaseBackupWrite"	"Waiting for base backup to write to a file."
+WAIT_EVENT_BUFFILE_READ	"BufFileRead"	"Waiting for a read from a buffered file."
+WAIT_EVENT_BUFFILE_WRITE	"BufFileWrite"	"Waiting for a write to a buffered file."
+WAIT_EVENT_BUFFILE_TRUNCATE	"BufFileTruncate"	"Waiting for a buffered file to be truncated."
+WAIT_EVENT_CONTROL_FILE_READ	"ControlFileRead"	"Waiting for a read from the <filename>pg_control</filename> file."
+WAIT_EVENT_CONTROL_FILE_SYNC	"ControlFileSync"	"Waiting for the <filename>pg_control</filename> file to reach durable storage. Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	"ControlFileSyncUpdate"	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+WAIT_EVENT_CONTROL_FILE_WRITE	"ControlFileWrite"	"Waiting for a write to the <filename>pg_control</filename> file. Waiting for a write to update the <filename>pg_control</filename> file."
+WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE	"ControlFileWriteUpdate"	"Waiting for a write to update the <filename>pg_control</filename> file."
+WAIT_EVENT_COPY_FILE_READ	"CopyFileRead"	"Waiting for a read during a file copy operation."
+WAIT_EVENT_COPY_FILE_WRITE	"CopyFileWrite"	"Waiting for a write during a file copy operation."
+WAIT_EVENT_DATA_FILE_EXTEND	"DataFileExtend"	"Waiting for a relation data file to be extended."
+WAIT_EVENT_DATA_FILE_FLUSH	"DataFileFlush"	"Waiting for a relation data file to reach durable storage."
+WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC	"DataFileImmediateSync"	"Waiting for an immediate synchronization of a relation data file to durable storage."
+WAIT_EVENT_DATA_FILE_PREFETCH	"DataFilePrefetch"	"Waiting for an asynchronous prefetch from a relation data file."
+WAIT_EVENT_DATA_FILE_READ	"DataFileRead"	"Waiting for a read from a relation data file."
+WAIT_EVENT_DATA_FILE_SYNC	"DataFileSync"	"Waiting for changes to a relation data file to reach durable storage."
+WAIT_EVENT_DATA_FILE_TRUNCATE	"DataFileTruncate"	"Waiting for a relation data file to be truncated."
+WAIT_EVENT_DATA_FILE_WRITE	"DataFileWrite"	"Waiting for a write to a relation data file."
+WAIT_EVENT_DSM_ALLOCATE	"DSMAllocate"	"Waiting for a dynamic shared memory segment to be allocated."
+WAIT_EVENT_DSM_FILL_ZERO_WRITE	"DSMFillZeroWrite"	"Waiting to fill a dynamic shared memory backing file with zeroes."
+WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ	"LockFileAddToDataDirRead"	"Waiting for a read while adding a line to the data directory lock file."
+WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC	"LockFileAddToDataDirSync"	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE	"LockFileAddToDataDirWrite"	"Waiting for a write while adding a line to the data directory lock file."
+WAIT_EVENT_LOCK_FILE_CREATE_READ	"LockFileCreateRead"	"Waiting to read while creating the data directory lock file."
+WAIT_EVENT_LOCK_FILE_CREATE_SYNC	"LockFileCreateSync"	"Waiting for data to reach durable storage while creating the data directory lock file."
+WAIT_EVENT_LOCK_FILE_CREATE_WRITE	"LockFileCreateWrite"	"Waiting for a write while creating the data directory lock file."
+WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ	"LockFileReCheckDataDirRead"	"Waiting for a read during recheck of the data directory lock file."
+WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC	"LogicalRewriteCheckpointSync"	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC	"LogicalRewriteMappingSync"	"Waiting for mapping data to reach durable storage during a logical rewrite."
+WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE	"LogicalRewriteMappingWrite"	"Waiting for a write of mapping data during a logical rewrite."
+WAIT_EVENT_LOGICAL_REWRITE_SYNC	"LogicalRewriteSync"	"Waiting for logical rewrite mappings to reach durable storage."
+WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE	"LogicalRewriteTruncate"	"Waiting for truncate of mapping data during a logical rewrite."
+WAIT_EVENT_LOGICAL_REWRITE_WRITE	"LogicalRewriteWrite"	"Waiting for a write of logical rewrite mappings."
+WAIT_EVENT_RELATION_MAP_READ	"RelationMapRead"	"Waiting for a read of the relation map file."
+WAIT_EVENT_RELATION_MAP_REPLACE	"RelationMapReplace"	"Waiting for durable replacement of a relation map file."
+WAIT_EVENT_RELATION_MAP_WRITE	"RelationMapWrite"	"Waiting for a write to the relation map file."
+WAIT_EVENT_REORDER_BUFFER_READ	"ReorderBufferRead"	"Waiting for a read during reorder buffer management."
+WAIT_EVENT_REORDER_BUFFER_WRITE	"ReorderBufferWrite"	"Waiting for a write during reorder buffer management."
+WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ	"ReorderLogicalMappingRead"	"Waiting for a read of a logical mapping during reorder buffer management."
+WAIT_EVENT_REPLICATION_SLOT_READ	"ReplicationSlotRead"	"Waiting for a read from a replication slot control file."
+WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC	"ReplicationSlotRestoreSync"	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+WAIT_EVENT_REPLICATION_SLOT_SYNC	"ReplicationSlotSync"	"Waiting for a replication slot control file to reach durable storage."
+WAIT_EVENT_REPLICATION_SLOT_WRITE	"ReplicationSlotWrite"	"Waiting for a write to a replication slot control file."
+WAIT_EVENT_SLRU_FLUSH_SYNC	"SLRUFlushSync"	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+WAIT_EVENT_SLRU_READ	"SLRURead"	"Waiting for a read of an SLRU page."
+WAIT_EVENT_SLRU_SYNC	"SLRUSync"	"Waiting for SLRU data to reach durable storage following a page write."
+WAIT_EVENT_SLRU_WRITE	"SLRUWrite"	"Waiting for a write of an SLRU page."
+WAIT_EVENT_SNAPBUILD_READ	"SnapbuildRead"	"Waiting for a read of a serialized historical catalog snapshot."
+WAIT_EVENT_SNAPBUILD_SYNC	"SnapbuildSync"	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+WAIT_EVENT_SNAPBUILD_WRITE	"SnapbuildWrite"	"Waiting for a write of a serialized historical catalog snapshot."
+WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC	"TimelineHistoryFileSync"	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE	"TimelineHistoryFileWrite"	"Waiting for a write of a timeline history file received via streaming replication."
+WAIT_EVENT_TIMELINE_HISTORY_READ	"TimelineHistoryRead"	"Waiting for a read of a timeline history file."
+WAIT_EVENT_TIMELINE_HISTORY_SYNC	"TimelineHistorySync"	"Waiting for a newly created timeline history file to reach durable storage."
+WAIT_EVENT_TIMELINE_HISTORY_WRITE	"TimelineHistoryWrite"	"Waiting for a write of a newly created timeline history file."
+WAIT_EVENT_TWOPHASE_FILE_READ	"TwophaseFileRead"	"Waiting for a read of a two phase state file."
+WAIT_EVENT_TWOPHASE_FILE_SYNC	"TwophaseFileSync"	"Waiting for a two phase state file to reach durable storage."
+WAIT_EVENT_TWOPHASE_FILE_WRITE	"TwophaseFileWrite"	"Waiting for a write of a two phase state file."
+WAIT_EVENT_VERSION_FILE_WRITE	"VersionFileWrite"	"Waiting for the version file to be written while creating a database."
+WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ	"WALSenderTimelineHistoryRead"	"Waiting for a read from a timeline history file during a walsender timeline command."
+WAIT_EVENT_WAL_BOOTSTRAP_SYNC	"WALBootstrapSync"	"Waiting for WAL to reach durable storage during bootstrapping."
+WAIT_EVENT_WAL_BOOTSTRAP_WRITE	"WALBootstrapWrite"	"Waiting for a write of a WAL page during bootstrapping."
+WAIT_EVENT_WAL_COPY_READ	"WALCopyRead"	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WAIT_EVENT_WAL_COPY_SYNC	"WALCopySync"	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WAIT_EVENT_WAL_COPY_WRITE	"WALCopyWrite"	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WAIT_EVENT_WAL_INIT_SYNC	"WALInitSync"	"Waiting for a newly initialized WAL file to reach durable storage."
+WAIT_EVENT_WAL_INIT_WRITE	"WALInitWrite"	"Waiting for a write while initializing a new WAL file."
+WAIT_EVENT_WAL_READ	"WALRead"	"Waiting for a read from a WAL file."
+WAIT_EVENT_WAL_SYNC	"WALSync"	"Waiting for a WAL file to reach durable storage. Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN	"WALSyncMethodAssign"	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAIT_EVENT_WAL_WRITE	"WALWrite"	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
+
+
+#
+# Wait events - Buffer Pin
+#
+
+Section: ClassName - WaitEventBufferPin
+
+WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buffer."
+
+
+#
+# Wait events - Extension
+#
+
+Section: ClassName - WaitEventExtension
+
+WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
+
+#
+# Wait events - LWLock
+#
+# This class of wait events has its own set of C structure, so these are
+# only used for the documentation.
+#
+
+Section: ClassName - WaitEventLWLock
+
+WAIT_EVENT_DOCONLY	"ShmemIndex"	"Waiting to find or allocate space in shared memory."
+WAIT_EVENT_DOCONLY	"OidGen"	"Waiting to allocate a new OID."
+WAIT_EVENT_DOCONLY	"XidGen"	"Waiting to allocate a new transaction ID."
+WAIT_EVENT_DOCONLY	"ProcArray"	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+WAIT_EVENT_DOCONLY	"SInvalRead"	"Waiting to retrieve messages from the shared catalog invalidation queue."
+WAIT_EVENT_DOCONLY	"SInvalWrite"	"Waiting to add a message to the shared catalog invalidation queue."
+WAIT_EVENT_DOCONLY	"WALBufMapping"	"Waiting to replace a page in WAL buffers."
+WAIT_EVENT_DOCONLY	"WALWrite"	"Waiting for WAL buffers to be written to disk."
+WAIT_EVENT_DOCONLY	"ControlFile"	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+WAIT_EVENT_DOCONLY	"XactSLRU"	"Waiting to access the transaction status SLRU cache."
+WAIT_EVENT_DOCONLY	"SubtransSLRU"	"Waiting to access the sub-transaction SLRU cache."
+WAIT_EVENT_DOCONLY	"MultiXactGen"	"Waiting to read or update shared multixact state."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetSLRU"	"Waiting to access the multixact offset SLRU cache."
+WAIT_EVENT_DOCONLY	"MultiXactMemberSLRU"	"Waiting to access the multixact member SLRU cache."
+WAIT_EVENT_DOCONLY	"RelCacheInit"	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+WAIT_EVENT_DOCONLY	"CheckpointerComm"	"Waiting to manage fsync requests."
+WAIT_EVENT_DOCONLY	"TwoPhaseState"	"Waiting to read or update the state of prepared transactions."
+WAIT_EVENT_DOCONLY	"TablespaceCreate"	"Waiting to create or drop a tablespace."
+WAIT_EVENT_DOCONLY	"BtreeVacuum"	"Waiting to read or update vacuum-related information for a B-tree index."
+WAIT_EVENT_DOCONLY	"AddinShmemInit"	"Waiting to manage an extension's space allocation in shared memory."
+WAIT_EVENT_DOCONLY	"Autovacuum"	"Waiting to read or update the current state of autovacuum workers."
+WAIT_EVENT_DOCONLY	"AutovacuumSchedule"	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+WAIT_EVENT_DOCONLY	"SyncScan"	"Waiting to select the starting location of a synchronized table scan."
+WAIT_EVENT_DOCONLY	"RelationMapping"	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+WAIT_EVENT_DOCONLY	"NotifySLRU"	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+WAIT_EVENT_DOCONLY	"NotifyQueue"	"Waiting to read or update <command>NOTIFY</command> messages."
+WAIT_EVENT_DOCONLY	"SerializableXactHash"	"Waiting to read or update information about serializable transactions."
+WAIT_EVENT_DOCONLY	"SerializableFinishedList"	"Waiting to access the list of finished serializable transactions."
+WAIT_EVENT_DOCONLY	"SerializablePredicateList"	"Waiting to access the list of predicate locks held by serializable transactions."
+WAIT_EVENT_DOCONLY	"SerialSLRU"	"Waiting to access the serializable transaction conflict SLRU cache."
+WAIT_EVENT_DOCONLY	"SyncRep"	"Waiting to read or update information about the state of synchronous replication."
+WAIT_EVENT_DOCONLY	"BackgroundWorker"	"Waiting to read or update background worker state."
+WAIT_EVENT_DOCONLY	"DynamicSharedMemoryControl"	"Waiting to read or update dynamic shared memory allocation information."
+WAIT_EVENT_DOCONLY	"AutoFile"	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+WAIT_EVENT_DOCONLY	"ReplicationSlotAllocation"	"Waiting to allocate or free a replication slot."
+WAIT_EVENT_DOCONLY	"ReplicationSlotControl"	"Waiting to read or update replication slot state."
+WAIT_EVENT_DOCONLY	"CommitTsSLRU"	"Waiting to access the commit timestamp SLRU cache."
+WAIT_EVENT_DOCONLY	"CommitTs"	"Waiting to read or update the last value set for a transaction commit timestamp."
+WAIT_EVENT_DOCONLY	"ReplicationOrigin"	"Waiting to create, drop or use a replication origin."
+WAIT_EVENT_DOCONLY	"MultiXactTruncation"	"Waiting to read or truncate multixact information."
+WAIT_EVENT_DOCONLY	"OldSnapshotTimeMap"	"Waiting to read or update old snapshot control information."
+WAIT_EVENT_DOCONLY	"LogicalRepWorker"	"Waiting to read or update the state of logical replication workers."
+WAIT_EVENT_DOCONLY	"XactTruncation"	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WAIT_EVENT_DOCONLY	"WrapLimitsVacuum"	"Waiting to update limits on transaction id and multixact consumption."
+WAIT_EVENT_DOCONLY	"NotifyQueueTail"	"Waiting to update limit on <command>NOTIFY</command> message storage."
+
+
+#
+# Wait even - Lock
+#
+# This class of wait events has its own set of C structure, so these are
+# only used for the documentation.
+#
+
+Section: ClassName - WaitEventLock
+
+WAIT_EVENT_DOCONLY	"relation"	"Waiting to acquire a lock on a relation."
+WAIT_EVENT_DOCONLY	"extend"	"Waiting to extend a relation."
+WAIT_EVENT_DOCONLY	"frozenid"	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+WAIT_EVENT_DOCONLY	"page"	"Waiting to acquire a lock on a page of a relation."
+WAIT_EVENT_DOCONLY	"tuple"	"Waiting to acquire a lock on a tuple."
+WAIT_EVENT_DOCONLY	"transactionid"	"Waiting for a transaction to finish."
+WAIT_EVENT_DOCONLY	"virtualxid"	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+WAIT_EVENT_DOCONLY	"spectoken"	"Waiting to acquire a speculative insertion lock."
+WAIT_EVENT_DOCONLY	"object"	"Waiting to acquire a lock on a non-relation database object."
+WAIT_EVENT_DOCONLY	"userlock"	"Waiting to acquire a user lock."
+WAIT_EVENT_DOCONLY	"advisory"	"Waiting to acquire an advisory user lock."
+WAIT_EVENT_DOCONLY	"applytransaction"	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index f9b9590997..aea253593f 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -24,7 +24,8 @@
 
 /*
  * This must match enum LockTagType!  Also, be sure to document any changes
- * in the docs for the pg_locks view and for wait event types.
+ * in the docs for the pg_locks view and update the WaitEventLOCK section in
+ * src/backend/utils/activity/waiteventnames.txt.
  */
 const char *const LockTagTypeNames[] = {
 	"relation",
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index bec5732e87..192e5cc2ab 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -280,7 +280,7 @@ wait_for_workers_to_become_ready(worker_state *wstate,
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 PG_WAIT_EXTENSION);
+						 WAIT_EVENT_EXTENSION);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/test/modules/test_shm_mq/test.c b/src/test/modules/test_shm_mq/test.c
index 906e943e2d..d9be703350 100644
--- a/src/test/modules/test_shm_mq/test.c
+++ b/src/test/modules/test_shm_mq/test.c
@@ -232,7 +232,7 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
 			 * for us to do.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 PG_WAIT_EXTENSION);
+							 WAIT_EVENT_EXTENSION);
 			ResetLatch(MyLatch);
 			CHECK_FOR_INTERRUPTS();
 		}
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index ad491d7722..7227cfaa45 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -199,7 +199,7 @@ worker_spi_main(Datum main_arg)
 		(void) WaitLatch(MyLatch,
 						 WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
 						 worker_spi_naptime * 1000L,
-						 PG_WAIT_EXTENSION);
+						 WAIT_EVENT_EXTENSION);
 		ResetLatch(MyLatch);
 
 		CHECK_FOR_INTERRUPTS();
diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..e8cbd687d5 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/waiteventnames.sgml
 # Assorted byproducts from building the above
 /postgres-full.xml
 /INSTALL.html
diff --git a/doc/src/sgml/Makefile b/doc/src/sgml/Makefile
index 71cbef230f..01a6aa8187 100644
--- a/doc/src/sgml/Makefile
+++ b/doc/src/sgml/Makefile
@@ -58,7 +58,7 @@ override XSLTPROCFLAGS += --stringparam pg.version '$(VERSION)'
 
 GENERATED_SGML = version.sgml \
 	features-supported.sgml features-unsupported.sgml errcodes-table.sgml \
-	keywords-table.sgml
+	keywords-table.sgml waiteventnames.sgml
 
 ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
 
@@ -111,6 +111,9 @@ errcodes-table.sgml: $(top_srcdir)/src/backend/utils/errcodes.txt generate-errco
 keywords-table.sgml: $(top_srcdir)/src/include/parser/kwlist.h $(wildcard $(srcdir)/keywords/sql*.txt) generate-keywords-table.pl
 	$(PERL) $(srcdir)/generate-keywords-table.pl $(srcdir) > $@
 
+waiteventnames.sgml: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt $(top_srcdir)/src/backend/utils/activity/generate-waiteventnames.pl
+	$(PERL) $(top_srcdir)/src/backend/utils/activity/generate-waiteventnames.pl $< > $@
+	rm pgstat_wait_event.c; rm wait_event_types.h
 
 ##
 ## Generation of some text files.
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 0d6be9a2fa..9ab235d36a 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -42,6 +42,7 @@
 <!ENTITY maintenance   SYSTEM "maintenance.sgml">
 <!ENTITY manage-ag     SYSTEM "manage-ag.sgml">
 <!ENTITY monitoring    SYSTEM "monitoring.sgml">
+<!ENTITY waiteventnames    SYSTEM "waiteventnames.sgml">
 <!ENTITY regress       SYSTEM "regress.sgml">
 <!ENTITY runtime       SYSTEM "runtime.sgml">
 <!ENTITY config        SYSTEM "config.sgml">
diff --git a/doc/src/sgml/meson.build b/doc/src/sgml/meson.build
index c6d77b5a15..53e4505b97 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -46,6 +46,16 @@ doc_generated += custom_target('errcodes-table.sgml',
   capture: true,
 )
 
+doc_generated += custom_target('waiteventnames.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/waiteventnames.txt'),
+  output: 'waiteventnames.sgml',
+  command: [perl, files('../../../src/backend/utils/activity/generate-waiteventnames.pl'), '@INPUT@'],
+  build_by_default: false,
+  install: false,
+  capture: true,
+)
+
 # FIXME: this actually has further inputs, adding depfile support to
 # generate-keywords-table.pl is probably the best way to address that
 # robustly.
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 99f7f95c39..5294cbfdd9 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,1266 +1100,7 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </tgroup>
   </table>
 
-  <table id="wait-event-activity-table">
-   <title>Wait Events of Type <literal>Activity</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Activity</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>ArchiverMain</literal></entry>
-      <entry>Waiting in main loop of archiver process.</entry>
-     </row>
-     <row>
-      <entry><literal>AutoVacuumMain</literal></entry>
-      <entry>Waiting in main loop of autovacuum launcher process.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWriterHibernate</literal></entry>
-      <entry>Waiting in background writer process, hibernating.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWriterMain</literal></entry>
-      <entry>Waiting in main loop of background writer process.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointerMain</literal></entry>
-      <entry>Waiting in main loop of checkpointer process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalApplyMain</literal></entry>
-      <entry>Waiting in main loop of logical replication apply process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalLauncherMain</literal></entry>
-      <entry>Waiting in main loop of logical replication launcher process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalParallelApplyMain</literal></entry>
-      <entry>Waiting in main loop of logical replication parallel apply
-       process.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryWalStream</literal></entry>
-      <entry>Waiting in main loop of startup process for WAL to arrive, during
-       streaming recovery.</entry>
-     </row>
-     <row>
-      <entry><literal>SysLoggerMain</literal></entry>
-      <entry>Waiting in main loop of syslogger process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverMain</literal></entry>
-      <entry>Waiting in main loop of WAL receiver process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderMain</literal></entry>
-      <entry>Waiting in main loop of WAL sender process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalWriterMain</literal></entry>
-      <entry>Waiting in main loop of WAL writer process.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-bufferpin-table">
-   <title>Wait Events of Type <literal>BufferPin</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>BufferPin</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>BufferPin</literal></entry>
-      <entry>Waiting to acquire an exclusive pin on a buffer.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-client-table">
-   <title>Wait Events of Type <literal>Client</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Client</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>ClientRead</literal></entry>
-      <entry>Waiting to read data from the client.</entry>
-     </row>
-     <row>
-      <entry><literal>ClientWrite</literal></entry>
-      <entry>Waiting to write data to the client.</entry>
-     </row>
-     <row>
-      <entry><literal>GSSOpenServer</literal></entry>
-      <entry>Waiting to read data from the client while establishing a GSSAPI
-       session.</entry>
-     </row>
-     <row>
-      <entry><literal>LibPQWalReceiverConnect</literal></entry>
-      <entry>Waiting in WAL receiver to establish connection to remote
-       server.</entry>
-     </row>
-     <row>
-      <entry><literal>LibPQWalReceiverReceive</literal></entry>
-      <entry>Waiting in WAL receiver to receive data from remote server.</entry>
-     </row>
-     <row>
-      <entry><literal>SSLOpenServer</literal></entry>
-      <entry>Waiting for SSL while attempting connection.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderWaitForWAL</literal></entry>
-      <entry>Waiting for WAL to be flushed in WAL sender process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderWriteData</literal></entry>
-      <entry>Waiting for any activity when processing replies from WAL
-       receiver in WAL sender process.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-extension-table">
-   <title>Wait Events of Type <literal>Extension</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Extension</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>Extension</literal></entry>
-      <entry>Waiting in an extension.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-io-table">
-   <title>Wait Events of Type <literal>IO</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>IO</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>BaseBackupRead</literal></entry>
-      <entry>Waiting for base backup to read from a file.</entry>
-     </row>
-     <row>
-      <entry><literal>BaseBackupSync</literal></entry>
-      <entry>Waiting for data written by a base backup to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>BaseBackupWrite</literal></entry>
-      <entry>Waiting for base backup to write to a file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileRead</literal></entry>
-      <entry>Waiting for a read from a buffered file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileRead</literal></entry>
-      <entry>Waiting for a read from the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileSync</literal></entry>
-      <entry>Waiting for the <filename>pg_control</filename> file to reach
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileSyncUpdate</literal></entry>
-      <entry>Waiting for an update to the <filename>pg_control</filename> file
-       to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileWrite</literal></entry>
-      <entry>Waiting for a write to the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileWriteUpdate</literal></entry>
-      <entry>Waiting for a write to update the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>CopyFileRead</literal></entry>
-      <entry>Waiting for a read during a file copy operation.</entry>
-     </row>
-     <row>
-      <entry><literal>CopyFileWrite</literal></entry>
-      <entry>Waiting for a write during a file copy operation.</entry>
-     </row>
-     <row>
-      <entry><literal>DSMAllocate</literal></entry>
-      <entry>Waiting for a dynamic shared memory segment to be
-       allocated.</entry>
-     </row>
-     <row>
-      <entry><literal>DSMFillZeroWrite</literal></entry>
-      <entry>Waiting to fill a dynamic shared memory backing file with
-       zeroes.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileExtend</literal></entry>
-      <entry>Waiting for a relation data file to be extended.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileFlush</literal></entry>
-      <entry>Waiting for a relation data file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileImmediateSync</literal></entry>
-      <entry>Waiting for an immediate synchronization of a relation data file to
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFilePrefetch</literal></entry>
-      <entry>Waiting for an asynchronous prefetch from a relation data
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileRead</literal></entry>
-      <entry>Waiting for a read from a relation data file.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileSync</literal></entry>
-      <entry>Waiting for changes to a relation data file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileTruncate</literal></entry>
-      <entry>Waiting for a relation data file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileWrite</literal></entry>
-      <entry>Waiting for a write to a relation data file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirRead</literal></entry>
-      <entry>Waiting for a read while adding a line to the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirSync</literal></entry>
-      <entry>Waiting for data to reach durable storage while adding a line to the
-       data directory lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirWrite</literal></entry>
-      <entry>Waiting for a write while adding a line to the data directory
-       lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateRead</literal></entry>
-      <entry>Waiting to read while creating the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateSync</literal></entry>
-      <entry>Waiting for data to reach durable storage while creating the data
-       directory lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateWrite</literal></entry>
-      <entry>Waiting for a write while creating the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileReCheckDataDirRead</literal></entry>
-      <entry>Waiting for a read during recheck of the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteCheckpointSync</literal></entry>
-      <entry>Waiting for logical rewrite mappings to reach durable storage
-       during a checkpoint.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteMappingSync</literal></entry>
-      <entry>Waiting for mapping data to reach durable storage during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteMappingWrite</literal></entry>
-      <entry>Waiting for a write of mapping data during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteSync</literal></entry>
-      <entry>Waiting for logical rewrite mappings to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteTruncate</literal></entry>
-      <entry>Waiting for truncate of mapping data during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteWrite</literal></entry>
-      <entry>Waiting for a write of logical rewrite mappings.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapRead</literal></entry>
-      <entry>Waiting for a read of the relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapReplace</literal></entry>
-      <entry>Waiting for durable replacement of a relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapWrite</literal></entry>
-      <entry>Waiting for a write to the relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderBufferRead</literal></entry>
-      <entry>Waiting for a read during reorder buffer management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderBufferWrite</literal></entry>
-      <entry>Waiting for a write during reorder buffer management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderLogicalMappingRead</literal></entry>
-      <entry>Waiting for a read of a logical mapping during reorder buffer
-       management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotRead</literal></entry>
-      <entry>Waiting for a read from a replication slot control file.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotRestoreSync</literal></entry>
-      <entry>Waiting for a replication slot control file to reach durable storage
-       while restoring it to memory.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotSync</literal></entry>
-      <entry>Waiting for a replication slot control file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotWrite</literal></entry>
-      <entry>Waiting for a write to a replication slot control file.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUFlushSync</literal></entry>
-      <entry>Waiting for SLRU data to reach durable storage during a checkpoint
-       or database shutdown.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRURead</literal></entry>
-      <entry>Waiting for a read of an SLRU page.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUSync</literal></entry>
-      <entry>Waiting for SLRU data to reach durable storage following a page
-       write.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUWrite</literal></entry>
-      <entry>Waiting for a write of an SLRU page.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildRead</literal></entry>
-      <entry>Waiting for a read of a serialized historical catalog
-       snapshot.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildSync</literal></entry>
-      <entry>Waiting for a serialized historical catalog snapshot to reach
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildWrite</literal></entry>
-      <entry>Waiting for a write of a serialized historical catalog
-       snapshot.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryFileSync</literal></entry>
-      <entry>Waiting for a timeline history file received via streaming
-       replication to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryFileWrite</literal></entry>
-      <entry>Waiting for a write of a timeline history file received via
-       streaming replication.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryRead</literal></entry>
-      <entry>Waiting for a read of a timeline history file.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistorySync</literal></entry>
-      <entry>Waiting for a newly created timeline history file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryWrite</literal></entry>
-      <entry>Waiting for a write of a newly created timeline history
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileRead</literal></entry>
-      <entry>Waiting for a read of a two phase state file.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileSync</literal></entry>
-      <entry>Waiting for a two phase state file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileWrite</literal></entry>
-      <entry>Waiting for a write of a two phase state file.</entry>
-     </row>
-     <row>
-      <entry><literal>VersionFileWrite</literal></entry>
-      <entry>Waiting for the version file to be written while creating a database.</entry>
-     </row>
-     <row>
-      <entry><literal>WALBootstrapSync</literal></entry>
-      <entry>Waiting for WAL to reach durable storage during
-       bootstrapping.</entry>
-     </row>
-     <row>
-      <entry><literal>WALBootstrapWrite</literal></entry>
-      <entry>Waiting for a write of a WAL page during bootstrapping.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopyRead</literal></entry>
-      <entry>Waiting for a read when creating a new WAL segment by copying an
-       existing one.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopySync</literal></entry>
-      <entry>Waiting for a new WAL segment created by copying an existing one to
-       reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopyWrite</literal></entry>
-      <entry>Waiting for a write when creating a new WAL segment by copying an
-       existing one.</entry>
-     </row>
-     <row>
-      <entry><literal>WALInitSync</literal></entry>
-      <entry>Waiting for a newly initialized WAL file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALInitWrite</literal></entry>
-      <entry>Waiting for a write while initializing a new WAL file.</entry>
-     </row>
-     <row>
-      <entry><literal>WALRead</literal></entry>
-      <entry>Waiting for a read from a WAL file.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSenderTimelineHistoryRead</literal></entry>
-      <entry>Waiting for a read from a timeline history file during a walsender
-       timeline command.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSync</literal></entry>
-      <entry>Waiting for a WAL file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSyncMethodAssign</literal></entry>
-      <entry>Waiting for data to reach durable storage while assigning a new
-       WAL sync method.</entry>
-     </row>
-     <row>
-      <entry><literal>WALWrite</literal></entry>
-      <entry>Waiting for a write to a WAL file.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-ipc-table">
-   <title>Wait Events of Type <literal>IPC</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>IPC</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>AppendReady</literal></entry>
-      <entry>Waiting for subplan nodes of an <literal>Append</literal> plan
-       node to be ready.</entry>
-     </row>
-     <row>
-      <entry><literal>ArchiveCleanupCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-archive-cleanup-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>ArchiveCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-archive-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>BackendTermination</literal></entry>
-      <entry>Waiting for the termination of another backend.</entry>
-     </row>
-     <row>
-      <entry><literal>BackupWaitWalArchive</literal></entry>
-      <entry>Waiting for WAL files required for a backup to be successfully
-       archived.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWorkerShutdown</literal></entry>
-      <entry>Waiting for background worker to shut down.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWorkerStartup</literal></entry>
-      <entry>Waiting for background worker to start up.</entry>
-     </row>
-     <row>
-      <entry><literal>BtreePage</literal></entry>
-      <entry>Waiting for the page number needed to continue a parallel B-tree
-       scan to become available.</entry>
-     </row>
-     <row>
-      <entry><literal>BufferIO</literal></entry>
-      <entry>Waiting for buffer I/O to complete.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointDone</literal></entry>
-      <entry>Waiting for a checkpoint to complete.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointStart</literal></entry>
-      <entry>Waiting for a checkpoint to start.</entry>
-     </row>
-     <row>
-      <entry><literal>ExecuteGather</literal></entry>
-      <entry>Waiting for activity from a child process while
-       executing a <literal>Gather</literal> plan node.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchAllocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate a hash
-       table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate a hash
-       table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchLoad</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish loading a
-       hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildAllocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate the
-       initial hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate the
-       initial hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildHashInner</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish hashing the
-       inner relation.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildHashOuter</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish partitioning
-       the outer relation.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesDecide</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to decide on future
-       batch growth.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate more
-       batches.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesFinish</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to decide on
-       future batch growth.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesReallocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate more
-       batches.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesRepartition</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish
-       repartitioning.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate more
-       buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsReallocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to finish
-       allocating more buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsReinsert</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish inserting
-       tuples into new buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalApplySendData</literal></entry>
-      <entry>Waiting for a logical replication leader apply process to send
-       data to a parallel apply process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalParallelApplyStateChange</literal></entry>
-      <entry>Waiting for a logical replication parallel apply process to change
-       state.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalSyncData</literal></entry>
-      <entry>Waiting for a logical replication remote server to send data for
-       initial table synchronization.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalSyncStateChange</literal></entry>
-      <entry>Waiting for a logical replication remote server to change
-       state.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueInternal</literal></entry>
-      <entry>Waiting for another process to be attached to a shared message
-       queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueuePutMessage</literal></entry>
-      <entry>Waiting to write a protocol message to a shared message queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueReceive</literal></entry>
-      <entry>Waiting to receive bytes from a shared message queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueSend</literal></entry>
-      <entry>Waiting to send bytes to a shared message queue.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelBitmapScan</literal></entry>
-      <entry>Waiting for parallel bitmap scan to become initialized.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelCreateIndexScan</literal></entry>
-      <entry>Waiting for parallel <command>CREATE INDEX</command> workers to
-       finish heap scan.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelFinish</literal></entry>
-      <entry>Waiting for parallel workers to finish computing.</entry>
-     </row>
-     <row>
-      <entry><literal>ProcArrayGroupUpdate</literal></entry>
-      <entry>Waiting for the group leader to clear the transaction ID at
-       end of a parallel operation.</entry>
-     </row>
-     <row>
-      <entry><literal>ProcSignalBarrier</literal></entry>
-      <entry>Waiting for a barrier event to be processed by all
-       backends.</entry>
-     </row>
-     <row>
-      <entry><literal>Promote</literal></entry>
-      <entry>Waiting for standby promotion.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryConflictSnapshot</literal></entry>
-      <entry>Waiting for recovery conflict resolution for a vacuum
-       cleanup.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryConflictTablespace</literal></entry>
-      <entry>Waiting for recovery conflict resolution for dropping a
-       tablespace.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryEndCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-recovery-end-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryPause</literal></entry>
-      <entry>Waiting for recovery to be resumed.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationOriginDrop</literal></entry>
-      <entry>Waiting for a replication origin to become inactive so it can be
-       dropped.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotDrop</literal></entry>
-      <entry>Waiting for a replication slot to become inactive so it can be
-       dropped.</entry>
-     </row>
-     <row>
-      <entry><literal>RestoreCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-restore-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>SafeSnapshot</literal></entry>
-      <entry>Waiting to obtain a valid snapshot for a <literal>READ ONLY
-       DEFERRABLE</literal> transaction.</entry>
-     </row>
-     <row>
-      <entry><literal>SyncRep</literal></entry>
-      <entry>Waiting for confirmation from a remote server during synchronous
-       replication.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverExit</literal></entry>
-      <entry>Waiting for the WAL receiver to exit.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverWaitStart</literal></entry>
-      <entry>Waiting for startup process to send initial data for streaming
-       replication.</entry>
-     </row>
-     <row>
-      <entry><literal>XactGroupUpdate</literal></entry>
-      <entry>Waiting for the group leader to update transaction status at
-       end of a parallel operation.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-lock-table">
-   <title>Wait Events of Type <literal>Lock</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Lock</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>advisory</literal></entry>
-      <entry>Waiting to acquire an advisory user lock.</entry>
-     </row>
-     <row>
-      <entry><literal>applytransaction</literal></entry>
-      <entry>Waiting to acquire a lock on a remote transaction being applied
-      by a logical replication subscriber.</entry>
-     </row>
-     <row>
-      <entry><literal>extend</literal></entry>
-      <entry>Waiting to extend a relation.</entry>
-     </row>
-     <row>
-      <entry><literal>frozenid</literal></entry>
-      <entry>Waiting to
-       update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield>
-       and <structname>pg_database</structname>.<structfield>datminmxid</structfield>.</entry>
-     </row>
-     <row>
-      <entry><literal>object</literal></entry>
-      <entry>Waiting to acquire a lock on a non-relation database object.</entry>
-     </row>
-     <row>
-      <entry><literal>page</literal></entry>
-      <entry>Waiting to acquire a lock on a page of a relation.</entry>
-     </row>
-     <row>
-      <entry><literal>relation</literal></entry>
-      <entry>Waiting to acquire a lock on a relation.</entry>
-     </row>
-     <row>
-      <entry><literal>spectoken</literal></entry>
-      <entry>Waiting to acquire a speculative insertion lock.</entry>
-     </row>
-     <row>
-      <entry><literal>transactionid</literal></entry>
-      <entry>Waiting for a transaction to finish.</entry>
-     </row>
-     <row>
-      <entry><literal>tuple</literal></entry>
-      <entry>Waiting to acquire a lock on a tuple.</entry>
-     </row>
-     <row>
-      <entry><literal>userlock</literal></entry>
-      <entry>Waiting to acquire a user lock.</entry>
-     </row>
-     <row>
-      <entry><literal>virtualxid</literal></entry>
-      <entry>Waiting to acquire a virtual transaction ID lock;  see
-      <xref linkend="transaction-id"/>.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-lwlock-table">
-   <title>Wait Events of Type <literal>LWLock</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>LWLock</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>AddinShmemInit</literal></entry>
-      <entry>Waiting to manage an extension's space allocation in shared
-       memory.</entry>
-     </row>
-     <row>
-      <entry><literal>AutoFile</literal></entry>
-      <entry>Waiting to update the <filename>postgresql.auto.conf</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>Autovacuum</literal></entry>
-      <entry>Waiting to read or update the current state of autovacuum
-       workers.</entry>
-     </row>
-     <row>
-      <entry><literal>AutovacuumSchedule</literal></entry>
-      <entry>Waiting to ensure that a table selected for autovacuum
-       still needs vacuuming.</entry>
-     </row>
-     <row>
-      <entry><literal>BackgroundWorker</literal></entry>
-      <entry>Waiting to read or update background worker state.</entry>
-     </row>
-     <row>
-      <entry><literal>BtreeVacuum</literal></entry>
-      <entry>Waiting to read or update vacuum-related information for a
-       B-tree index.</entry>
-     </row>
-     <row>
-      <entry><literal>BufferContent</literal></entry>
-      <entry>Waiting to access a data page in memory.</entry>
-     </row>
-     <row>
-      <entry><literal>BufferMapping</literal></entry>
-      <entry>Waiting to associate a data block with a buffer in the buffer
-       pool.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointerComm</literal></entry>
-      <entry>Waiting to manage fsync requests.</entry>
-     </row>
-     <row>
-      <entry><literal>CommitTs</literal></entry>
-      <entry>Waiting to read or update the last value set for a
-       transaction commit timestamp.</entry>
-     </row>
-     <row>
-      <entry><literal>CommitTsBuffer</literal></entry>
-      <entry>Waiting for I/O on a commit timestamp SLRU buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>CommitTsSLRU</literal></entry>
-      <entry>Waiting to access the commit timestamp SLRU cache.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFile</literal></entry>
-      <entry>Waiting to read or update the <filename>pg_control</filename>
-       file or create a new WAL file.</entry>
-     </row>
-     <row>
-      <entry><literal>DynamicSharedMemoryControl</literal></entry>
-      <entry>Waiting to read or update dynamic shared memory allocation
-       information.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFastPath</literal></entry>
-      <entry>Waiting to read or update a process' fast-path lock
-       information.</entry>
-     </row>
-     <row>
-      <entry><literal>LockManager</literal></entry>
-      <entry>Waiting to read or update information
-       about <quote>heavyweight</quote> locks.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRepLauncherDSA</literal></entry>
-      <entry>Waiting to access logical replication launcher's dynamic shared
-       memory allocator.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRepLauncherHash</literal></entry>
-      <entry>Waiting to access logical replication launcher's shared
-       hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRepWorker</literal></entry>
-      <entry>Waiting to read or update the state of logical replication
-       workers.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactGen</literal></entry>
-      <entry>Waiting to read or update shared multixact state.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactMemberBuffer</literal></entry>
-      <entry>Waiting for I/O on a multixact member SLRU buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactMemberSLRU</literal></entry>
-      <entry>Waiting to access the multixact member SLRU cache.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactOffsetBuffer</literal></entry>
-      <entry>Waiting for I/O on a multixact offset SLRU buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactOffsetSLRU</literal></entry>
-      <entry>Waiting to access the multixact offset SLRU cache.</entry>
-     </row>
-     <row>
-      <entry><literal>MultiXactTruncation</literal></entry>
-      <entry>Waiting to read or truncate multixact information.</entry>
-     </row>
-     <row>
-      <entry><literal>NotifyBuffer</literal></entry>
-      <entry>Waiting for I/O on a <command>NOTIFY</command> message SLRU
-       buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>NotifyQueue</literal></entry>
-      <entry>Waiting to read or update <command>NOTIFY</command> messages.</entry>
-     </row>
-     <row>
-      <entry><literal>NotifyQueueTail</literal></entry>
-      <entry>Waiting to update limit on <command>NOTIFY</command> message
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>NotifySLRU</literal></entry>
-      <entry>Waiting to access the <command>NOTIFY</command> message SLRU
-       cache.</entry>
-     </row>
-     <row>
-      <entry><literal>OidGen</literal></entry>
-      <entry>Waiting to allocate a new OID.</entry>
-     </row>
-     <row>
-      <entry><literal>OldSnapshotTimeMap</literal></entry>
-      <entry>Waiting to read or update old snapshot control information.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelAppend</literal></entry>
-      <entry>Waiting to choose the next subplan during Parallel Append plan
-       execution.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelHashJoin</literal></entry>
-      <entry>Waiting to synchronize workers during Parallel Hash Join plan
-       execution.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelQueryDSA</literal></entry>
-      <entry>Waiting for parallel query dynamic shared memory allocation.</entry>
-     </row>
-     <row>
-      <entry><literal>PerSessionDSA</literal></entry>
-      <entry>Waiting for parallel query dynamic shared memory allocation.</entry>
-     </row>
-     <row>
-      <entry><literal>PerSessionRecordType</literal></entry>
-      <entry>Waiting to access a parallel query's information about composite
-       types.</entry>
-     </row>
-     <row>
-      <entry><literal>PerSessionRecordTypmod</literal></entry>
-      <entry>Waiting to access a parallel query's information about type
-       modifiers that identify anonymous record types.</entry>
-     </row>
-     <row>
-      <entry><literal>PerXactPredicateList</literal></entry>
-      <entry>Waiting to access the list of predicate locks held by the current
-       serializable transaction during a parallel query.</entry>
-     </row>
-     <row>
-      <entry><literal>PgStatsData</literal></entry>
-      <entry>Waiting for shared memory stats data access</entry>
-     </row>
-     <row>
-      <entry><literal>PgStatsDSA</literal></entry>
-      <entry>Waiting for stats dynamic shared memory allocator access</entry>
-     </row>
-     <row>
-      <entry><literal>PgStatsHash</literal></entry>
-      <entry>Waiting for stats shared memory hash table access</entry>
-     </row>
-     <row>
-      <entry><literal>PredicateLockManager</literal></entry>
-      <entry>Waiting to access predicate lock information used by
-       serializable transactions.</entry>
-     </row>
-     <row>
-      <entry><literal>ProcArray</literal></entry>
-      <entry>Waiting to access the shared per-process data structures
-       (typically, to get a snapshot or report a session's transaction
-       ID).</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapping</literal></entry>
-      <entry>Waiting to read or update
-       a <filename>pg_filenode.map</filename> file (used to track the
-       filenode assignments of certain system catalogs).</entry>
-     </row>
-     <row>
-      <entry><literal>RelCacheInit</literal></entry>
-      <entry>Waiting to read or update a <filename>pg_internal.init</filename>
-       relation cache initialization file.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationOrigin</literal></entry>
-      <entry>Waiting to create, drop or use a replication origin.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationOriginState</literal></entry>
-      <entry>Waiting to read or update the progress of one replication
-       origin.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotAllocation</literal></entry>
-      <entry>Waiting to allocate or free a replication slot.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotControl</literal></entry>
-      <entry>Waiting to read or update replication slot state.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotIO</literal></entry>
-      <entry>Waiting for I/O on a replication slot.</entry>
-     </row>
-     <row>
-      <entry><literal>SerialBuffer</literal></entry>
-      <entry>Waiting for I/O on a serializable transaction conflict SLRU
-       buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>SerializableFinishedList</literal></entry>
-      <entry>Waiting to access the list of finished serializable
-       transactions.</entry>
-     </row>
-     <row>
-      <entry><literal>SerializablePredicateList</literal></entry>
-      <entry>Waiting to access the list of predicate locks held by
-       serializable transactions.</entry>
-     </row>
-     <row>
-      <entry><literal>SerializableXactHash</literal></entry>
-      <entry>Waiting to read or update information about serializable
-       transactions.</entry>
-     </row>
-     <row>
-      <entry><literal>SerialSLRU</literal></entry>
-      <entry>Waiting to access the serializable transaction conflict SLRU
-       cache.</entry>
-     </row>
-     <row>
-      <entry><literal>SharedTidBitmap</literal></entry>
-      <entry>Waiting to access a shared TID bitmap during a parallel bitmap
-       index scan.</entry>
-     </row>
-     <row>
-      <entry><literal>SharedTupleStore</literal></entry>
-      <entry>Waiting to access a shared tuple store during parallel
-       query.</entry>
-     </row>
-     <row>
-      <entry><literal>ShmemIndex</literal></entry>
-      <entry>Waiting to find or allocate space in shared memory.</entry>
-     </row>
-     <row>
-      <entry><literal>SInvalRead</literal></entry>
-      <entry>Waiting to retrieve messages from the shared catalog invalidation
-       queue.</entry>
-     </row>
-     <row>
-      <entry><literal>SInvalWrite</literal></entry>
-      <entry>Waiting to add a message to the shared catalog invalidation
-      queue.</entry>
-     </row>
-     <row>
-      <entry><literal>SubtransBuffer</literal></entry>
-      <entry>Waiting for I/O on a sub-transaction SLRU buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>SubtransSLRU</literal></entry>
-      <entry>Waiting to access the sub-transaction SLRU cache.</entry>
-     </row>
-     <row>
-      <entry><literal>SyncRep</literal></entry>
-      <entry>Waiting to read or update information about the state of
-       synchronous replication.</entry>
-     </row>
-     <row>
-      <entry><literal>SyncScan</literal></entry>
-      <entry>Waiting to select the starting location of a synchronized table
-       scan.</entry>
-     </row>
-     <row>
-      <entry><literal>TablespaceCreate</literal></entry>
-      <entry>Waiting to create or drop a tablespace.</entry>
-     </row>
-     <row>
-      <entry><literal>TwoPhaseState</literal></entry>
-      <entry>Waiting to read or update the state of prepared transactions.</entry>
-     </row>
-     <row>
-      <entry><literal>WALBufMapping</literal></entry>
-      <entry>Waiting to replace a page in WAL buffers.</entry>
-     </row>
-     <row>
-      <entry><literal>WALInsert</literal></entry>
-      <entry>Waiting to insert WAL data into a memory buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>WALWrite</literal></entry>
-      <entry>Waiting for WAL buffers to be written to disk.</entry>
-     </row>
-     <row>
-      <entry><literal>WrapLimitsVacuum</literal></entry>
-      <entry>Waiting to update limits on transaction id and multixact
-       consumption.</entry>
-     </row>
-     <row>
-      <entry><literal>XactBuffer</literal></entry>
-      <entry>Waiting for I/O on a transaction status SLRU buffer.</entry>
-     </row>
-     <row>
-      <entry><literal>XactSLRU</literal></entry>
-      <entry>Waiting to access the transaction status SLRU cache.</entry>
-     </row>
-     <row>
-      <entry><literal>XactTruncation</literal></entry>
-      <entry>Waiting to execute <function>pg_xact_status</function> or update
-       the oldest transaction ID available to it.</entry>
-     </row>
-     <row>
-      <entry><literal>XidGen</literal></entry>
-      <entry>Waiting to allocate a new transaction ID.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-   <note>
-    <para>
-     Extensions can add <literal>LWLock</literal> types to the list shown in
-     <xref linkend="wait-event-lwlock-table"/>.  In some cases, the name
-     assigned by an extension will not be available in all server processes;
-     so an <literal>LWLock</literal> wait event might be reported as
-     just <quote><literal>extension</literal></quote> rather than the
-     extension-assigned name.
-    </para>
-   </note>
-
-  <table id="wait-event-timeout-table">
-   <title>Wait Events of Type <literal>Timeout</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Timeout</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>BaseBackupThrottle</literal></entry>
-      <entry>Waiting during base backup when throttling activity.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointWriteDelay</literal></entry>
-      <entry>Waiting between writes while performing a checkpoint.</entry>
-     </row>
-     <row>
-      <entry><literal>PgSleep</literal></entry>
-      <entry>Waiting due to a call to <function>pg_sleep</function> or
-       a sibling function.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryApplyDelay</literal></entry>
-      <entry>Waiting to apply WAL during recovery because of a delay
-       setting.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryRetrieveRetryInterval</literal></entry>
-      <entry>Waiting during recovery when WAL data is not available from any
-       source (<filename>pg_wal</filename>, archive or stream).</entry>
-     </row>
-     <row>
-      <entry><literal>RegisterSyncRequest</literal></entry>
-      <entry>Waiting while sending synchronization requests to the
-       checkpointer, because the request queue is full.</entry>
-     </row>
-     <row>
-      <entry><literal>SpinDelay</literal></entry>
-      <entry>Waiting while acquiring a contended spinlock.</entry>
-     </row>
-     <row>
-      <entry><literal>VacuumDelay</literal></entry>
-      <entry>Waiting in a cost-based vacuum delay point.</entry>
-     </row>
-     <row>
-      <entry><literal>VacuumTruncate</literal></entry>
-      <entry>Waiting to acquire an exclusive lock to truncate off any
-       empty pages at the end of a table vacuumed.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
+  &waiteventnames;
 
    <para>
      Here is an example of how wait events can be viewed:
@@ -2374,6 +1115,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
 </programlisting>
    </para>
 
+   <note>
+    <para>
+     Extensions can add <literal>LWLock</literal> types to the list shown in
+     <xref linkend="wait-event-lwlock-table"/>.  In some cases, the name
+     assigned by an extension will not be available in all server processes;
+     so an <literal>LWLock</literal> wait event might be reported as
+     just <quote><literal>extension</literal></quote> rather than the
+     extension-assigned name.
+    </para>
+   </note>
  </sect2>
 
  <sect2 id="monitoring-pg-stat-replication-view">
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 55f75eff36..f167cb71d4 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -203,7 +203,7 @@ dblink_get_conn(char *conname_or_str,
 		dblink_connstr_check(connstr);
 
 		/* OK to make connection */
-		conn = libpqsrv_connect(connstr, PG_WAIT_EXTENSION);
+		conn = libpqsrv_connect(connstr, WAIT_EVENT_EXTENSION);
 
 		if (PQstatus(conn) == CONNECTION_BAD)
 		{
@@ -293,7 +293,7 @@ dblink_connect(PG_FUNCTION_ARGS)
 	dblink_connstr_check(connstr);
 
 	/* OK to make connection */
-	conn = libpqsrv_connect(connstr, PG_WAIT_EXTENSION);
+	conn = libpqsrv_connect(connstr, WAIT_EVENT_EXTENSION);
 
 	if (PQstatus(conn) == CONNECTION_BAD)
 	{
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 93835449c0..d0efc9e524 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -237,7 +237,7 @@ autoprewarm_main(Datum main_arg)
 			(void) WaitLatch(MyLatch,
 							 WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
 							 -1L,
-							 PG_WAIT_EXTENSION);
+							 WAIT_EVENT_EXTENSION);
 		}
 		else
 		{
@@ -264,7 +264,7 @@ autoprewarm_main(Datum main_arg)
 			(void) WaitLatch(MyLatch,
 							 WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
 							 delay_in_ms,
-							 PG_WAIT_EXTENSION);
+							 WAIT_EVENT_EXTENSION);
 		}
 
 		/* Reset the latch, loop. */
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index da32d503bc..25d0c43b64 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -530,7 +530,7 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		/* OK to make connection */
 		conn = libpqsrv_connect_params(keywords, values,
 									   false,	/* expand_dbname */
-									   PG_WAIT_EXTENSION);
+									   WAIT_EVENT_EXTENSION);
 
 		if (!conn || PQstatus(conn) != CONNECTION_OK)
 			ereport(ERROR,
@@ -863,7 +863,7 @@ pgfdw_get_result(PGconn *conn, const char *query)
 									   WL_LATCH_SET | WL_SOCKET_READABLE |
 									   WL_EXIT_ON_PM_DEATH,
 									   PQsocket(conn),
-									   -1L, PG_WAIT_EXTENSION);
+									   -1L, WAIT_EVENT_EXTENSION);
 				ResetLatch(MyLatch);
 
 				CHECK_FOR_INTERRUPTS();
@@ -1567,7 +1567,7 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result,
 									   WL_LATCH_SET | WL_SOCKET_READABLE |
 									   WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
 									   PQsocket(conn),
-									   cur_timeout, PG_WAIT_EXTENSION);
+									   cur_timeout, WAIT_EVENT_EXTENSION);
 				ResetLatch(MyLatch);
 
 				CHECK_FOR_INTERRUPTS();
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..596131ab6b 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -591,6 +591,24 @@ sub GenerateFiles
 			'src/include/storage/lwlocknames.h');
 	}
 
+	if (IsNewer(
+			'src/include/utils/wait_event_types.h',
+			'src/backend/utils/activity/waiteventnames.txt'))
+	{
+		print "Generating pgstat_wait_event.c and wait_event_types.h...\n";
+		my $activ = 'src/backend/utils/activity';
+		system("perl $activ/generate-waiteventnames.pl --outdir $activ $activ/waiteventnames.txt");
+	}
+
+	if (IsNewer(
+			'src/include/utils/wait_event_types.h',
+			'src/backend/utils/activity/wait_event_types.h'))
+	{
+		copyFile(
+			'src/backend/utils/activity/wait_event_types.h',
+			'src/include/utils/wait_event_types.h');
+	}
+
 	if (IsNewer('src/include/utils/probes.h', 'src/backend/utils/probes.d'))
 	{
 		print "Generating probes.h...\n";
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index d0e8bfbf86..4f06edc7db 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -47,6 +47,7 @@ if exist src\include\utils\errcodes.h del /q src\include\utils\errcodes.h
 if exist src\include\utils\fmgroids.h del /q src\include\utils\fmgroids.h
 if exist src\include\utils\fmgrprotos.h del /q src\include\utils\fmgrprotos.h
 if exist src\include\storage\lwlocknames.h del /q src\include\storage\lwlocknames.h
+if exist src\include\utils\wait_event_types.h del /q src\include\utils\wait_event_types.h
 if exist src\include\utils\probes.h del /q src\include\utils\probes.h
 if exist src\include\catalog\schemapg.h del /q src\include\catalog\schemapg.h
 if exist src\include\catalog\system_fk_info.h del /q src\include\catalog\system_fk_info.h
@@ -54,6 +55,8 @@ if exist src\include\catalog\pg_*_d.h del /q src\include\catalog\pg_*_d.h
 if exist src\include\catalog\header-stamp del /q src\include\catalog\header-stamp
 if exist doc\src\sgml\version.sgml del /q doc\src\sgml\version.sgml
 
+if %DIST%==1 if exist src\backend\utils\activity\pgstat_wait_event.c del /q src\backend\utils\activity\pgstat_wait_event.c
+if %DIST%==1 if exist src\backend\utils\activity\wait_event_types.h del /q src\backend\utils\activity\wait_event_types.h
 if %DIST%==1 if exist src\backend\utils\fmgroids.h del /q src\backend\utils\fmgroids.h
 if %DIST%==1 if exist src\backend\utils\fmgrprotos.h del /q src\backend\utils\fmgrprotos.h
 if %DIST%==1 if exist src\backend\utils\fmgrtab.c del /q src\backend\utils\fmgrtab.c
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index b4058b88c3..018d42ef14 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2970,7 +2970,9 @@ WSANETWORKEVENTS
 WSAPROTOCOL_INFO
 WaitEvent
 WaitEventActivity
+WaitEventBufferPin
 WaitEventClient
+WaitEventExtension
 WaitEventIO
 WaitEventIPC
 WaitEventSet
-- 
2.40.1

Attachment: signature.asc
Description: PGP signature

Reply via email to