Autogenerate some wait events code and documentation

Started by Drouvot, Bertrandalmost 3 years ago77 messages
#1Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
2 attachment(s)

Hi hackers,

In another thread [1]/messages/by-id/CA+hUKG+ewEpxm=hPNXyupRUB_SKGh-6tO86viaco0g-P_pm_Cw@mail.gmail.com, Thomas had the idea to $SUBJECT in a similar way
to what is currently done with src/backend/storage/lmgr/lwlocknames.txt.

Doing so, like in the attached patch proposal, would help to avoid:

- wait event without documentation like observed in [2]/messages/by-id/CA+hUKGJixAHc860Ej9Qzd_z96Z6aoajAgJ18bYfV3Lfn6t9=+Q@mail.gmail.com
- orphaned wait event like observed in [3]/messages/by-id/CA+hUKGK6tqm59KuF1z+h5Y8fsWcu5v8+84kduSHwRzwjB2aa_A@mail.gmail.com

The patch relies on a new src/backend/utils/activity/waiteventnames.txt file that contains on row
per wait event, with this format:

<ENUM NAME> <WAIT EVENT ENUM> <WAIT EVENT NAME> <WAIT EVENT DOC SENTENCE>

Then, a new perl script (src/backend/utils/activity/generate-waiteventnames.pl) generates the new:

- waiteventnames.c
- waiteventnames.h
- waiteventnames.sgml

files.

Remarks:

- The new src/backend/utils/activity/waiteventnames.txt file has been created with (a quickly written, non polished
and not part of the patch) generate_waiteventnames_txt.sh script attached. Then, the proposal for the 2 wait events
missing documentation (non committed yet) done in [2]/messages/by-id/CA+hUKGJixAHc860Ej9Qzd_z96Z6aoajAgJ18bYfV3Lfn6t9=+Q@mail.gmail.com has been added manually to waiteventnames.txt.

- The patch does take care of wait events that currently are linked to enums, means:

- PG_WAIT_ACTIVITY
- PG_WAIT_CLIENT
- PG_WAIT_IPC
- PG_WAIT_TIMEOUT
- PG_WAIT_IO

so that PG_WAIT_LWLOCK, PG_WAIT_LOCK, PG_WAIT_BUFFER_PIN and PG_WAIT_EXTENSION are not autogenerated.

This result to having the wait event part of the documentation "monitoring-stats" not ordered as compared to the "Wait Event Types" Table.

This is due to the fact that the new waiteventnames.sgml that contains the documentation for
the autogenerated ones listed above is "included" into doc/src/sgml/monitoring.sgml and then breaks the alphabetical ordering
with the ones not autogenerated.

To fix this I've in mind to also autogenerate enums for PG_WAIT_BUFFER_PIN and PG_WAIT_EXTENSION and
split the current documentation "Wait Event Types" Table in 2 tables: one for the autogenerated ones and one (then for
PG_WAIT_LWLOCK, PG_WAIT_LOCK) for the non autogenerated "lock" related ones.

Looking forward to your feedback,

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

[1]: /messages/by-id/CA+hUKG+ewEpxm=hPNXyupRUB_SKGh-6tO86viaco0g-P_pm_Cw@mail.gmail.com
[2]: /messages/by-id/CA+hUKGJixAHc860Ej9Qzd_z96Z6aoajAgJ18bYfV3Lfn6t9=+Q@mail.gmail.com
[3]: /messages/by-id/CA+hUKGK6tqm59KuF1z+h5Y8fsWcu5v8+84kduSHwRzwjB2aa_A@mail.gmail.com

Attachments:

v1-0001-Generating-waiteventnames.h-waiteventnames.c-and-.patchtext/plain; charset=UTF-8; name=v1-0001-Generating-waiteventnames.h-waiteventnames.c-and-.patchDownload
From 6c7b71324963228521d74b3b4aec5a65b9ea89aa Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Fri, 24 Mar 2023 08:37:29 +0000
Subject: [PATCH v1] Generating waiteventnames.h, waiteventnames.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
---
 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                  | 784 +-----------------
 src/backend/Makefile                          |  14 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 157 ++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 157 ++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 178 +---
 src/tools/msvc/Solution.pm                    |  19 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 426 insertions(+), 1525 deletions(-)
  36.7% doc/src/sgml/
  53.3% src/backend/utils/activity/
   7.6% src/include/utils/

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 b96c7cbf22..24bce44bbe 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 waiteventnames.c; rm waiteventnames.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 157b8589e5..2e983daf0a 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -49,6 +49,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 c809ff1ba4..df927e4178 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +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>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -1257,615 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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>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">
@@ -2297,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
     </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>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..258935c647 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/waiteventnames.h: utils/activity/generate-waiteventnames.pl utils/activity/waiteventnames.txt
+	$(MAKE) -C utils/activity waiteventnames.h waiteventnames.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/waiteventnames.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/waiteventnames.h: utils/activity/waiteventnames.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 $@
 
@@ -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	waiteventnames.h waiteventnames.c
 
 
 ##########################################################################
@@ -305,6 +314,9 @@ maintainer-clean: distclean
 	      utils/adt/jsonpath_gram.c \
 	      utils/adt/jsonpath_gram.h \
 	      utils/adt/jsonpath_scan.c \
+	      utils/activity/waiteventnames.c \
+	      utils/activity/waiteventnames.h \
+	      utils/adt/jsonpath_scan.c \
 	      utils/misc/guc-file.c
 
 
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..b3c3519124 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: waiteventnames.c
+waiteventnames.c: waiteventnames.h
+	touch $@
+
+waiteventnames.h: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt generate-waiteventnames.pl
+	$(PERL) $(srcdir)/generate-waiteventnames.pl $<
+
+maintainer-clean: clean
+	rm -f waiteventnames.h waiteventnames.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..8f9b2e2251
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,157 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - waiteventnames.h
+# - waiteventnames.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;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", "PG_WAIT_TIMEOUT", "PG_WAIT_IO");
+
+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/waiteventnames.h.tmp$$";
+my $ctmp = "$output_path/waiteventnames.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, 'waiteventnames.h';
+printf $h "#ifndef WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_H\n\n";
+printf $h "#include \"utils/wait_event.h\"\n\n";
+
+printf $c $header_comment, 'waiteventnames.c';
+
+# Read the input file and populate the hash table
+while (<$waiteventnames>)
+{
+	chomp;
+
+	# Skip comments
+	next if /^#/;
+	next if /^\s*$/;
+
+	die "unable to parse waiteventnames.txt"
+	  unless /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+
+	(my $waitclassname, my $waiteventenumname, my $waiteventdescription, my $waitevendocsentence) = ($1, $2, $3, $4);
+
+	my @waiteventlist = [$waiteventenumname, $waiteventdescription, $waitevendocsentence];
+	my $trimmedwaiteventname = $waiteventenumname;
+	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
+	die "wait event names must start with 'WAIT_EVENT_'" if $trimmedwaiteventname eq $waiteventenumname;
+	$continue    = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe) {
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastuc = uc $last;
+	my $lastlc = lc $last;
+	my $firstpass = 1;
+	my $pg_wait_class;
+
+	printf $h "typedef enum\n{\n";
+
+	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";
+
+	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>Activity</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}}) {
+		if ($firstpass) {
+			$pg_wait_class = "PG_WAIT_".$lastuc;
+			die "waitclass $pg_wait_class does not exist" unless grep( /^$pg_wait_class$/, @wait_classes );
+			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 $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 $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 $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+close $s;
+
+rename($htmp, "$output_path/waiteventnames.h") || die "rename: $htmp to $output_path/waiteventnames.h: $!";
+rename($ctmp, "$output_path/waiteventnames.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..d20e3f7167 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: ['waiteventnames.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..59b548e543 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,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 "waiteventnames.c"
diff --git a/src/backend/utils/activity/waiteventnames.txt b/src/backend/utils/activity/waiteventnames.txt
new file mode 100644
index 0000000000..3654905086
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,157 @@
+WaitEventActivity	WAIT_EVENT_ARCHIVER_MAIN	"ArchiverMain"	"Waiting in main loop of archiver process."
+WaitEventActivity	WAIT_EVENT_AUTOVACUUM_MAIN	"AutoVacuumMain"	"Waiting in main loop of autovacuum launcher process."
+WaitEventActivity	WAIT_EVENT_BGWRITER_HIBERNATE	"BgWriterHibernate"	"Waiting in background writer process, hibernating."
+WaitEventActivity	WAIT_EVENT_BGWRITER_MAIN	"BgWriterMain"	"Waiting in main loop of background writer process."
+WaitEventActivity	WAIT_EVENT_CHECKPOINTER_MAIN	"CheckpointerMain"	"Waiting in main loop of checkpointer process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_APPLY_MAIN	"LogicalApplyMain"	"Waiting in main loop of logical replication apply process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_LAUNCHER_MAIN	"LogicalLauncherMain"	"Waiting in main loop of logical replication launcher process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN	"LogicalParallelApplyMain"	"Waiting in main loop of logical replication parallel apply process."
+WaitEventActivity	WAIT_EVENT_RECOVERY_WAL_STREAM	"RecoveryWalStream"	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+WaitEventActivity	WAIT_EVENT_SYSLOGGER_MAIN	"SysLoggerMain"	"Waiting in main loop of syslogger process."
+WaitEventActivity	WAIT_EVENT_WAL_RECEIVER_MAIN	"WalReceiverMain"	"Waiting in main loop of WAL receiver process."
+WaitEventActivity	WAIT_EVENT_WAL_SENDER_MAIN	"WalSenderMain"	"Waiting in main loop of WAL sender process."
+WaitEventActivity	WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer process."
+WaitEventClient	WAIT_EVENT_CLIENT_READ	"ClientRead"	"Waiting to read data from the client."
+WaitEventClient	WAIT_EVENT_CLIENT_WRITE	"ClientWrite"	"Waiting to write data to the client."
+WaitEventClient	WAIT_EVENT_GSS_OPEN_SERVER	"GSSOpenServer"	"Waiting to read data from the client while establishing a GSSAPI session."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_CONNECT	"LibPQWalReceiverConnect"	"Waiting in WAL receiver to establish connection to remote server."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE	"LibPQWalReceiverReceive"	"Waiting in WAL receiver to receive data from remote server."
+WaitEventClient	WAIT_EVENT_SSL_OPEN_SERVER	"SSLOpenServer"	"Waiting for SSL while attempting connection."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WAIT_WAL	"WalSenderWaitForWAL"	"Waiting for WAL to be flushed in WAL sender process."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
+WaitEventIPC	WAIT_EVENT_APPEND_READY	"AppendReady"	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	"ArchiveCleanupCommand"	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_COMMAND	"ArchiveCommand"	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_BACKEND_TERMINATION	"BackendTermination"	"Waiting for the termination of another backend."
+WaitEventIPC	WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE	"BackupWaitWalArchive"	"Waiting for WAL files required for a backup to be successfully archived."
+WaitEventIPC	WAIT_EVENT_BGWORKER_SHUTDOWN	"BgWorkerShutdown"	"Waiting for background worker to shut down."
+WaitEventIPC	WAIT_EVENT_BGWORKER_STARTUP	"BgWorkerStartup"	"Waiting for background worker to start up."
+WaitEventIPC	WAIT_EVENT_BTREE_PAGE	"BtreePage"	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+WaitEventIPC	WAIT_EVENT_BUFFER_IO	"BufferIO"	"Waiting for buffer I/O to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_DONE	"CheckpointDone"	"Waiting for a checkpoint to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_START	"CheckpointStart"	"Waiting for a checkpoint to start."
+WaitEventIPC	WAIT_EVENT_EXECUTE_GATHER	"ExecuteGather"	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ALLOCATE	"HashBatchAllocate"	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ELECT	"HashBatchElect"	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_LOAD	"HashBatchLoad"	"Waiting for other Parallel Hash participants to finish loading a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ALLOCATE	"HashBuildAllocate"	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ELECT	"HashBuildElect"	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_INNER	"HashBuildHashInner"	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_OUTER	"HashBuildHashOuter"	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE	"HashGrowBatchesDecide"	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_ELECT	"HashGrowBatchesElect"	"Waiting to elect a Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_FINISH	"HashGrowBatchesFinish"	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE	"HashGrowBatchesReallocate"	"Waiting for an elected Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION	"HashGrowBatchesRepartition"	"Waiting for other Parallel Hash participants to finish repartitioning."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT	"HashGrowBucketsElect"	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE	"HashGrowBucketsReallocate"	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT	"HashGrowBucketsReinsert"	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+WaitEventIPC	WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	"LogicalApplySendData"	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+WaitEventIPC	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"LogicalParallelApplyStateChange"	"Waiting for a logical replication parallel apply process to change state."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_DATA	"LogicalSyncData"	"Waiting for a logical replication remote server to send data for initial table synchronization."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE	"LogicalSyncStateChange"	"Waiting for a logical replication remote server to change state."
+WaitEventIPC	WAIT_EVENT_MQ_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_SEND	"MessageQueueSend"	"Waiting to send bytes to a shared message queue."
+WaitEventIPC	WAIT_EVENT_PARALLEL_BITMAP_SCAN	"ParallelBitmapScan"	"Waiting for parallel bitmap scan to become initialized."
+WaitEventIPC	WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN	"ParallelCreateIndexScan"	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+WaitEventIPC	WAIT_EVENT_PARALLEL_FINISH	"ParallelFinish"	"Waiting for parallel workers to finish computing."
+WaitEventIPC	WAIT_EVENT_PROCARRAY_GROUP_UPDATE	"ProcArrayGroupUpdate"	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+WaitEventIPC	WAIT_EVENT_PROC_SIGNAL_BARRIER	"ProcSignalBarrier"	"Waiting for a barrier event to be processed by all backends."
+WaitEventIPC	WAIT_EVENT_PROMOTE	"Promote"	"Waiting for standby promotion."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT	"RecoveryConflictSnapshot"	"Waiting for recovery conflict resolution for a vacuum cleanup."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE	"RecoveryConflictTablespace"	"Waiting for recovery conflict resolution for dropping a tablespace."
+WaitEventIPC	WAIT_EVENT_RECOVERY_END_COMMAND	"RecoveryEndCommand"	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_RECOVERY_PAUSE	"RecoveryPause"	"Waiting for recovery to be resumed."
+WaitEventIPC	WAIT_EVENT_REPLICATION_ORIGIN_DROP	"ReplicationOriginDrop"	"Waiting for a replication origin to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_REPLICATION_SLOT_DROP	"ReplicationSlotDrop"	"Waiting for a replication slot to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_RESTORE_COMMAND	"RestoreCommand"	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_SAFE_SNAPSHOT	"SafeSnapshot"	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+WaitEventIPC	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."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_EXIT	"WalReceiverExit"	"Waiting for the WAL receiver to exit."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_WAIT_START	"WalReceiverWaitStart"	"Waiting for startup process to send initial data for streaming replication."
+WaitEventIPC	WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to update transaction status at end of a parallel operation."
+WaitEventTimeout	WAIT_EVENT_BASE_BACKUP_THROTTLE	"BaseBackupThrottle"	"Waiting during base backup when throttling activity."
+WaitEventTimeout	WAIT_EVENT_CHECKPOINT_WRITE_DELAY	"CheckpointWriteDelay"	"Waiting between writes while performing a checkpoint."
+WaitEventTimeout	WAIT_EVENT_PG_SLEEP	"PgSleep"	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+WaitEventTimeout	WAIT_EVENT_RECOVERY_APPLY_DELAY	"RecoveryApplyDelay"	"Waiting to apply WAL during recovery because of a delay setting."
+WaitEventTimeout	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)."
+WaitEventTimeout	WAIT_EVENT_REGISTER_SYNC_REQUEST	"RegisterSyncRequest"	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+WaitEventTimeout	WAIT_EVENT_SPIN_DELAY	"SpinDelay"	"Waiting while acquiring a contended spinlock."
+WaitEventTimeout	WAIT_EVENT_VACUUM_DELAY	"VacuumDelay"	"Waiting in a cost-based vacuum delay point."
+WaitEventTimeout	WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_READ	"BaseBackupRead"	"Waiting for base backup to read from a file."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_SYNC	"BaseBackupSync"	"Waiting for data written by a base backup to reach durable storage."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_WRITE	"BaseBackupWrite"	"Waiting for base backup to write to a file."
+WaitEventIO	WAIT_EVENT_BUFFILE_READ	"BufFileRead"	"Waiting for a read from a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_WRITE	"BufFileWrite"	"Waiting for a write to a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_TRUNCATE	"BufFileTruncate"	"Waiting for a buffered file to be truncated."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_READ	"ControlFileRead"	"Waiting for a read from the <filename>pg_control</filename> file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	"ControlFileSyncUpdate"	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE	"ControlFileWriteUpdate"	"Waiting for a write to update the <filename>pg_control</filename> file."
+WaitEventIO	WAIT_EVENT_COPY_FILE_READ	"CopyFileRead"	"Waiting for a read during a file copy operation."
+WaitEventIO	WAIT_EVENT_COPY_FILE_WRITE	"CopyFileWrite"	"Waiting for a write during a file copy operation."
+WaitEventIO	WAIT_EVENT_DATA_FILE_EXTEND	"DataFileExtend"	"Waiting for a relation data file to be extended."
+WaitEventIO	WAIT_EVENT_DATA_FILE_FLUSH	"DataFileFlush"	"Waiting for a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC	"DataFileImmediateSync"	"Waiting for an immediate synchronization of a relation data file to durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_PREFETCH	"DataFilePrefetch"	"Waiting for an asynchronous prefetch from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_READ	"DataFileRead"	"Waiting for a read from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_SYNC	"DataFileSync"	"Waiting for changes to a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_TRUNCATE	"DataFileTruncate"	"Waiting for a relation data file to be truncated."
+WaitEventIO	WAIT_EVENT_DATA_FILE_WRITE	"DataFileWrite"	"Waiting for a write to a relation data file."
+WaitEventIO	WAIT_EVENT_DSM_ALLOCATE	"DSMAllocate"	"Waiting for a dynamic shared memory segment to be allocated."
+WaitEventIO	WAIT_EVENT_DSM_FILL_ZERO_WRITE	"DSMFillZeroWrite"	"Waiting to fill a dynamic shared memory backing file with zeroes."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ	"LockFileAddToDataDirRead"	"Waiting for a read while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC	"LockFileAddToDataDirSync"	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE	"LockFileAddToDataDirWrite"	"Waiting for a write while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_READ	"LockFileCreateRead"	"Waiting to read while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_SYNC	"LockFileCreateSync"	"Waiting for data to reach durable storage while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_WRITE	"LockFileCreateWrite"	"Waiting for a write while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ	"LockFileReCheckDataDirRead"	"Waiting for a read during recheck of the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC	"LogicalRewriteCheckpointSync"	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC	"LogicalRewriteMappingSync"	"Waiting for mapping data to reach durable storage during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE	"LogicalRewriteMappingWrite"	"Waiting for a write of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_SYNC	"LogicalRewriteSync"	"Waiting for logical rewrite mappings to reach durable storage."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE	"LogicalRewriteTruncate"	"Waiting for truncate of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_WRITE	"LogicalRewriteWrite"	"Waiting for a write of logical rewrite mappings."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_READ	"RelationMapRead"	"Waiting for a read of the relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_REPLACE	"RelationMapReplace"	"Waiting for durable replacement of a relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_WRITE	"RelationMapWrite"	"Waiting for a write to the relation map file."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_READ	"ReorderBufferRead"	"Waiting for a read during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_WRITE	"ReorderBufferWrite"	"Waiting for a write during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ	"ReorderLogicalMappingRead"	"Waiting for a read of a logical mapping during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_READ	"ReplicationSlotRead"	"Waiting for a read from a replication slot control file."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC	"ReplicationSlotRestoreSync"	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_SYNC	"ReplicationSlotSync"	"Waiting for a replication slot control file to reach durable storage."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_WRITE	"ReplicationSlotWrite"	"Waiting for a write to a replication slot control file."
+WaitEventIO	WAIT_EVENT_SLRU_FLUSH_SYNC	"SLRUFlushSync"	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+WaitEventIO	WAIT_EVENT_SLRU_READ	"SLRURead"	"Waiting for a read of an SLRU page."
+WaitEventIO	WAIT_EVENT_SLRU_SYNC	"SLRUSync"	"Waiting for SLRU data to reach durable storage following a page write."
+WaitEventIO	WAIT_EVENT_SLRU_WRITE	"SLRUWrite"	"Waiting for a write of an SLRU page."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_READ	"SnapbuildRead"	"Waiting for a read of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_SYNC	"SnapbuildSync"	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_WRITE	"SnapbuildWrite"	"Waiting for a write of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC	"TimelineHistoryFileSync"	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE	"TimelineHistoryFileWrite"	"Waiting for a write of a timeline history file received via streaming replication."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_READ	"TimelineHistoryRead"	"Waiting for a read of a timeline history file."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_SYNC	"TimelineHistorySync"	"Waiting for a newly created timeline history file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_WRITE	"TimelineHistoryWrite"	"Waiting for a write of a newly created timeline history file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_READ	"TwophaseFileRead"	"Waiting for a read of a two phase state file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_SYNC	"TwophaseFileSync"	"Waiting for a two phase state file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_WRITE	"TwophaseFileWrite"	"Waiting for a write of a two phase state file."
+WaitEventIO	WAIT_EVENT_VERSION_FILE_WRITE	"VersionFileWrite"	"Waiting for the version file to be written while creating a database."
+WaitEventIO	WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ	"WALSenderTimelineHistoryRead"	"Waiting for a read from a timeline history file during a walsender timeline command."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_SYNC	"WALBootstrapSync"	"Waiting for WAL to reach durable storage during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_WRITE	"WALBootstrapWrite"	"Waiting for a write of a WAL page during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_COPY_READ	"WALCopyRead"	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_COPY_SYNC	"WALCopySync"	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_COPY_WRITE	"WALCopyWrite"	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_INIT_SYNC	"WALInitSync"	"Waiting for a newly initialized WAL file to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_INIT_WRITE	"WALInitWrite"	"Waiting for a write while initializing a new WAL file."
+WaitEventIO	WAIT_EVENT_WAL_READ	"WALRead"	"Waiting for a read from a WAL file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN	"WALSyncMethodAssign"	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WaitEventIO	WAIT_EVENT_WAL_WRITE	"WALWrite"	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
diff --git a/src/include/Makefile b/src/include/Makefile
index 56576dcf5c..280b6968d7 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/waiteventnames.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..b4f82b3d21 100644
--- a/src/include/utils/.gitignore
+++ b/src/include/utils/.gitignore
@@ -3,3 +3,4 @@
 /probes.h
 /errcodes.h
 /header-stamp
+/waiteventnames.h
diff --git a/src/include/utils/meson.build b/src/include/utils/meson.build
index 2fed1e3f8e..826fa89323 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: ['waiteventnames.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'],
+)
+
+waiteventnames_h = waiteventnames[0]
+generated_backend_headers += waiteventnames_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': ['waiteventnames.h']}
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..57a5de5ae1 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,6 +25,11 @@
 #define PG_WAIT_TIMEOUT				0x09000000U
 #define PG_WAIT_IO					0x0A000000U
 
+/* enums for wait events */
+#include "utils/waiteventnames.h"
+
+/* The include above includes those categories */
+
 /* ----------
  * Wait Events - Activity
  *
@@ -33,22 +38,6 @@
  * 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
@@ -58,17 +47,6 @@ typedef enum
  * 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
@@ -77,62 +55,6 @@ typedef enum
  * 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
@@ -140,18 +62,6 @@ typedef enum
  * 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
@@ -159,84 +69,6 @@ typedef enum
  * 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;
-
 
 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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 153be7be11..8c1b9a53cb 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -580,6 +580,7 @@ sub GenerateFiles
 		my $lmgr = 'src/backend/storage/lmgr';
 		system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr $lmgr/lwlocknames.txt");
 	}
+
 	if (IsNewer(
 			'src/include/storage/lwlocknames.h',
 			'src/backend/storage/lmgr/lwlocknames.h'))
@@ -589,6 +590,24 @@ sub GenerateFiles
 			'src/include/storage/lwlocknames.h');
 	}
 
+	if (IsNewer(
+			'src/include/utils/waiteventnames.h',
+			'src/backend/utils/activity/waiteventnames.txt'))
+	{
+		print "Generating waiteventnames.c and waiteventnames.h...\n";
+		my $activ = 'src/backend/utils/activity';
+		system("perl $activ/generate-waiteventnames.pl --outdir $activ $activ/waiteventnames.txt");
+	}
+
+	if (IsNewer(
+			'src/include/utils/waiteventnames.h',
+			'src/backend/utils/activity/waiteventnames.h'))
+	{
+		copyFile(
+			'src/backend/utils/activity/waiteventnames.h',
+			'src/include/utils/waiteventnames.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..6c1c3d0816 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\waiteventnames.h del /q src\include\utils\waiteventnames.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
@@ -61,7 +62,9 @@ if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q src\backend\utils\fmgr
 if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h
 if %DIST%==1 if exist src\backend\nodes\nodetags.h del /q src\backend\nodes\nodetags.h
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q src\backend\storage\lmgr\lwlocknames.c
+if %DIST%==1 if exist src\backend\utils\activity\waiteventnames.c del /q src\backend\utils\activity\waiteventnames.c
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+if %DIST%==1 if exist src\backend\utils\activity\waiteventnames.h del /q src\backend\utils\activity\waiteventnames.h
 if %DIST%==1 if exist src\pl\plpython\spiexceptions.h del /q src\pl\plpython\spiexceptions.h
 if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q src\pl\plpgsql\src\plerrcodes.h
 if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q src\pl\tcl\pltclerrcodes.h
-- 
2.34.1

generate_waiteventnames_txt.shapplication/x-sh; name=generate_waiteventnames_txt.shDownload
#2Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Drouvot, Bertrand (#1)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 3/29/23 11:44 AM, Drouvot, Bertrand wrote:

Looking forward to your feedback,

Just realized that more polishing was needed.

Done in V2 attached.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v2-0001-Generating-waiteventnames.h-waiteventnames.c-and-.patchtext/plain; charset=UTF-8; name=v2-0001-Generating-waiteventnames.h-waiteventnames.c-and-.patchDownload
From 5ce9b8bd7d5bb5f6d0905a0ce4afd8d63b5adacf Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Fri, 24 Mar 2023 08:37:29 +0000
Subject: [PATCH v2] Generating waiteventnames.h, waiteventnames.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
---
 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                  | 784 +-----------------
 src/backend/Makefile                          |  14 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 157 ++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 157 ++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 214 +----
 src/tools/msvc/Solution.pm                    |  19 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 423 insertions(+), 1564 deletions(-)
  36.3% doc/src/sgml/
  52.6% src/backend/utils/activity/
   8.7% src/include/utils/

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 b96c7cbf22..24bce44bbe 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 waiteventnames.c; rm waiteventnames.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 157b8589e5..2e983daf0a 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -49,6 +49,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 c809ff1ba4..df927e4178 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +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>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -1257,615 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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>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">
@@ -2297,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
     </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>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..258935c647 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/waiteventnames.h: utils/activity/generate-waiteventnames.pl utils/activity/waiteventnames.txt
+	$(MAKE) -C utils/activity waiteventnames.h waiteventnames.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/waiteventnames.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/waiteventnames.h: utils/activity/waiteventnames.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 $@
 
@@ -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	waiteventnames.h waiteventnames.c
 
 
 ##########################################################################
@@ -305,6 +314,9 @@ maintainer-clean: distclean
 	      utils/adt/jsonpath_gram.c \
 	      utils/adt/jsonpath_gram.h \
 	      utils/adt/jsonpath_scan.c \
+	      utils/activity/waiteventnames.c \
+	      utils/activity/waiteventnames.h \
+	      utils/adt/jsonpath_scan.c \
 	      utils/misc/guc-file.c
 
 
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..b3c3519124 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: waiteventnames.c
+waiteventnames.c: waiteventnames.h
+	touch $@
+
+waiteventnames.h: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt generate-waiteventnames.pl
+	$(PERL) $(srcdir)/generate-waiteventnames.pl $<
+
+maintainer-clean: clean
+	rm -f waiteventnames.h waiteventnames.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..8f9b2e2251
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,157 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - waiteventnames.h
+# - waiteventnames.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;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", "PG_WAIT_TIMEOUT", "PG_WAIT_IO");
+
+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/waiteventnames.h.tmp$$";
+my $ctmp = "$output_path/waiteventnames.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, 'waiteventnames.h';
+printf $h "#ifndef WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_H\n\n";
+printf $h "#include \"utils/wait_event.h\"\n\n";
+
+printf $c $header_comment, 'waiteventnames.c';
+
+# Read the input file and populate the hash table
+while (<$waiteventnames>)
+{
+	chomp;
+
+	# Skip comments
+	next if /^#/;
+	next if /^\s*$/;
+
+	die "unable to parse waiteventnames.txt"
+	  unless /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+
+	(my $waitclassname, my $waiteventenumname, my $waiteventdescription, my $waitevendocsentence) = ($1, $2, $3, $4);
+
+	my @waiteventlist = [$waiteventenumname, $waiteventdescription, $waitevendocsentence];
+	my $trimmedwaiteventname = $waiteventenumname;
+	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
+	die "wait event names must start with 'WAIT_EVENT_'" if $trimmedwaiteventname eq $waiteventenumname;
+	$continue    = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe) {
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastuc = uc $last;
+	my $lastlc = lc $last;
+	my $firstpass = 1;
+	my $pg_wait_class;
+
+	printf $h "typedef enum\n{\n";
+
+	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";
+
+	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>Activity</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}}) {
+		if ($firstpass) {
+			$pg_wait_class = "PG_WAIT_".$lastuc;
+			die "waitclass $pg_wait_class does not exist" unless grep( /^$pg_wait_class$/, @wait_classes );
+			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 $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 $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 $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+close $s;
+
+rename($htmp, "$output_path/waiteventnames.h") || die "rename: $htmp to $output_path/waiteventnames.h: $!";
+rename($ctmp, "$output_path/waiteventnames.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..d20e3f7167 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: ['waiteventnames.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..59b548e543 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,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 "waiteventnames.c"
diff --git a/src/backend/utils/activity/waiteventnames.txt b/src/backend/utils/activity/waiteventnames.txt
new file mode 100644
index 0000000000..3654905086
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,157 @@
+WaitEventActivity	WAIT_EVENT_ARCHIVER_MAIN	"ArchiverMain"	"Waiting in main loop of archiver process."
+WaitEventActivity	WAIT_EVENT_AUTOVACUUM_MAIN	"AutoVacuumMain"	"Waiting in main loop of autovacuum launcher process."
+WaitEventActivity	WAIT_EVENT_BGWRITER_HIBERNATE	"BgWriterHibernate"	"Waiting in background writer process, hibernating."
+WaitEventActivity	WAIT_EVENT_BGWRITER_MAIN	"BgWriterMain"	"Waiting in main loop of background writer process."
+WaitEventActivity	WAIT_EVENT_CHECKPOINTER_MAIN	"CheckpointerMain"	"Waiting in main loop of checkpointer process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_APPLY_MAIN	"LogicalApplyMain"	"Waiting in main loop of logical replication apply process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_LAUNCHER_MAIN	"LogicalLauncherMain"	"Waiting in main loop of logical replication launcher process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN	"LogicalParallelApplyMain"	"Waiting in main loop of logical replication parallel apply process."
+WaitEventActivity	WAIT_EVENT_RECOVERY_WAL_STREAM	"RecoveryWalStream"	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+WaitEventActivity	WAIT_EVENT_SYSLOGGER_MAIN	"SysLoggerMain"	"Waiting in main loop of syslogger process."
+WaitEventActivity	WAIT_EVENT_WAL_RECEIVER_MAIN	"WalReceiverMain"	"Waiting in main loop of WAL receiver process."
+WaitEventActivity	WAIT_EVENT_WAL_SENDER_MAIN	"WalSenderMain"	"Waiting in main loop of WAL sender process."
+WaitEventActivity	WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer process."
+WaitEventClient	WAIT_EVENT_CLIENT_READ	"ClientRead"	"Waiting to read data from the client."
+WaitEventClient	WAIT_EVENT_CLIENT_WRITE	"ClientWrite"	"Waiting to write data to the client."
+WaitEventClient	WAIT_EVENT_GSS_OPEN_SERVER	"GSSOpenServer"	"Waiting to read data from the client while establishing a GSSAPI session."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_CONNECT	"LibPQWalReceiverConnect"	"Waiting in WAL receiver to establish connection to remote server."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE	"LibPQWalReceiverReceive"	"Waiting in WAL receiver to receive data from remote server."
+WaitEventClient	WAIT_EVENT_SSL_OPEN_SERVER	"SSLOpenServer"	"Waiting for SSL while attempting connection."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WAIT_WAL	"WalSenderWaitForWAL"	"Waiting for WAL to be flushed in WAL sender process."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
+WaitEventIPC	WAIT_EVENT_APPEND_READY	"AppendReady"	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	"ArchiveCleanupCommand"	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_COMMAND	"ArchiveCommand"	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_BACKEND_TERMINATION	"BackendTermination"	"Waiting for the termination of another backend."
+WaitEventIPC	WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE	"BackupWaitWalArchive"	"Waiting for WAL files required for a backup to be successfully archived."
+WaitEventIPC	WAIT_EVENT_BGWORKER_SHUTDOWN	"BgWorkerShutdown"	"Waiting for background worker to shut down."
+WaitEventIPC	WAIT_EVENT_BGWORKER_STARTUP	"BgWorkerStartup"	"Waiting for background worker to start up."
+WaitEventIPC	WAIT_EVENT_BTREE_PAGE	"BtreePage"	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+WaitEventIPC	WAIT_EVENT_BUFFER_IO	"BufferIO"	"Waiting for buffer I/O to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_DONE	"CheckpointDone"	"Waiting for a checkpoint to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_START	"CheckpointStart"	"Waiting for a checkpoint to start."
+WaitEventIPC	WAIT_EVENT_EXECUTE_GATHER	"ExecuteGather"	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ALLOCATE	"HashBatchAllocate"	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ELECT	"HashBatchElect"	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_LOAD	"HashBatchLoad"	"Waiting for other Parallel Hash participants to finish loading a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ALLOCATE	"HashBuildAllocate"	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ELECT	"HashBuildElect"	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_INNER	"HashBuildHashInner"	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_OUTER	"HashBuildHashOuter"	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE	"HashGrowBatchesDecide"	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_ELECT	"HashGrowBatchesElect"	"Waiting to elect a Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_FINISH	"HashGrowBatchesFinish"	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE	"HashGrowBatchesReallocate"	"Waiting for an elected Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION	"HashGrowBatchesRepartition"	"Waiting for other Parallel Hash participants to finish repartitioning."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT	"HashGrowBucketsElect"	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE	"HashGrowBucketsReallocate"	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT	"HashGrowBucketsReinsert"	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+WaitEventIPC	WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	"LogicalApplySendData"	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+WaitEventIPC	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"LogicalParallelApplyStateChange"	"Waiting for a logical replication parallel apply process to change state."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_DATA	"LogicalSyncData"	"Waiting for a logical replication remote server to send data for initial table synchronization."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE	"LogicalSyncStateChange"	"Waiting for a logical replication remote server to change state."
+WaitEventIPC	WAIT_EVENT_MQ_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_SEND	"MessageQueueSend"	"Waiting to send bytes to a shared message queue."
+WaitEventIPC	WAIT_EVENT_PARALLEL_BITMAP_SCAN	"ParallelBitmapScan"	"Waiting for parallel bitmap scan to become initialized."
+WaitEventIPC	WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN	"ParallelCreateIndexScan"	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+WaitEventIPC	WAIT_EVENT_PARALLEL_FINISH	"ParallelFinish"	"Waiting for parallel workers to finish computing."
+WaitEventIPC	WAIT_EVENT_PROCARRAY_GROUP_UPDATE	"ProcArrayGroupUpdate"	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+WaitEventIPC	WAIT_EVENT_PROC_SIGNAL_BARRIER	"ProcSignalBarrier"	"Waiting for a barrier event to be processed by all backends."
+WaitEventIPC	WAIT_EVENT_PROMOTE	"Promote"	"Waiting for standby promotion."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT	"RecoveryConflictSnapshot"	"Waiting for recovery conflict resolution for a vacuum cleanup."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE	"RecoveryConflictTablespace"	"Waiting for recovery conflict resolution for dropping a tablespace."
+WaitEventIPC	WAIT_EVENT_RECOVERY_END_COMMAND	"RecoveryEndCommand"	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_RECOVERY_PAUSE	"RecoveryPause"	"Waiting for recovery to be resumed."
+WaitEventIPC	WAIT_EVENT_REPLICATION_ORIGIN_DROP	"ReplicationOriginDrop"	"Waiting for a replication origin to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_REPLICATION_SLOT_DROP	"ReplicationSlotDrop"	"Waiting for a replication slot to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_RESTORE_COMMAND	"RestoreCommand"	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_SAFE_SNAPSHOT	"SafeSnapshot"	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+WaitEventIPC	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."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_EXIT	"WalReceiverExit"	"Waiting for the WAL receiver to exit."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_WAIT_START	"WalReceiverWaitStart"	"Waiting for startup process to send initial data for streaming replication."
+WaitEventIPC	WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to update transaction status at end of a parallel operation."
+WaitEventTimeout	WAIT_EVENT_BASE_BACKUP_THROTTLE	"BaseBackupThrottle"	"Waiting during base backup when throttling activity."
+WaitEventTimeout	WAIT_EVENT_CHECKPOINT_WRITE_DELAY	"CheckpointWriteDelay"	"Waiting between writes while performing a checkpoint."
+WaitEventTimeout	WAIT_EVENT_PG_SLEEP	"PgSleep"	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+WaitEventTimeout	WAIT_EVENT_RECOVERY_APPLY_DELAY	"RecoveryApplyDelay"	"Waiting to apply WAL during recovery because of a delay setting."
+WaitEventTimeout	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)."
+WaitEventTimeout	WAIT_EVENT_REGISTER_SYNC_REQUEST	"RegisterSyncRequest"	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+WaitEventTimeout	WAIT_EVENT_SPIN_DELAY	"SpinDelay"	"Waiting while acquiring a contended spinlock."
+WaitEventTimeout	WAIT_EVENT_VACUUM_DELAY	"VacuumDelay"	"Waiting in a cost-based vacuum delay point."
+WaitEventTimeout	WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_READ	"BaseBackupRead"	"Waiting for base backup to read from a file."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_SYNC	"BaseBackupSync"	"Waiting for data written by a base backup to reach durable storage."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_WRITE	"BaseBackupWrite"	"Waiting for base backup to write to a file."
+WaitEventIO	WAIT_EVENT_BUFFILE_READ	"BufFileRead"	"Waiting for a read from a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_WRITE	"BufFileWrite"	"Waiting for a write to a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_TRUNCATE	"BufFileTruncate"	"Waiting for a buffered file to be truncated."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_READ	"ControlFileRead"	"Waiting for a read from the <filename>pg_control</filename> file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	"ControlFileSyncUpdate"	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE	"ControlFileWriteUpdate"	"Waiting for a write to update the <filename>pg_control</filename> file."
+WaitEventIO	WAIT_EVENT_COPY_FILE_READ	"CopyFileRead"	"Waiting for a read during a file copy operation."
+WaitEventIO	WAIT_EVENT_COPY_FILE_WRITE	"CopyFileWrite"	"Waiting for a write during a file copy operation."
+WaitEventIO	WAIT_EVENT_DATA_FILE_EXTEND	"DataFileExtend"	"Waiting for a relation data file to be extended."
+WaitEventIO	WAIT_EVENT_DATA_FILE_FLUSH	"DataFileFlush"	"Waiting for a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC	"DataFileImmediateSync"	"Waiting for an immediate synchronization of a relation data file to durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_PREFETCH	"DataFilePrefetch"	"Waiting for an asynchronous prefetch from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_READ	"DataFileRead"	"Waiting for a read from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_SYNC	"DataFileSync"	"Waiting for changes to a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_TRUNCATE	"DataFileTruncate"	"Waiting for a relation data file to be truncated."
+WaitEventIO	WAIT_EVENT_DATA_FILE_WRITE	"DataFileWrite"	"Waiting for a write to a relation data file."
+WaitEventIO	WAIT_EVENT_DSM_ALLOCATE	"DSMAllocate"	"Waiting for a dynamic shared memory segment to be allocated."
+WaitEventIO	WAIT_EVENT_DSM_FILL_ZERO_WRITE	"DSMFillZeroWrite"	"Waiting to fill a dynamic shared memory backing file with zeroes."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ	"LockFileAddToDataDirRead"	"Waiting for a read while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC	"LockFileAddToDataDirSync"	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE	"LockFileAddToDataDirWrite"	"Waiting for a write while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_READ	"LockFileCreateRead"	"Waiting to read while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_SYNC	"LockFileCreateSync"	"Waiting for data to reach durable storage while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_WRITE	"LockFileCreateWrite"	"Waiting for a write while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ	"LockFileReCheckDataDirRead"	"Waiting for a read during recheck of the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC	"LogicalRewriteCheckpointSync"	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC	"LogicalRewriteMappingSync"	"Waiting for mapping data to reach durable storage during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE	"LogicalRewriteMappingWrite"	"Waiting for a write of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_SYNC	"LogicalRewriteSync"	"Waiting for logical rewrite mappings to reach durable storage."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE	"LogicalRewriteTruncate"	"Waiting for truncate of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_WRITE	"LogicalRewriteWrite"	"Waiting for a write of logical rewrite mappings."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_READ	"RelationMapRead"	"Waiting for a read of the relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_REPLACE	"RelationMapReplace"	"Waiting for durable replacement of a relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_WRITE	"RelationMapWrite"	"Waiting for a write to the relation map file."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_READ	"ReorderBufferRead"	"Waiting for a read during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_WRITE	"ReorderBufferWrite"	"Waiting for a write during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ	"ReorderLogicalMappingRead"	"Waiting for a read of a logical mapping during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_READ	"ReplicationSlotRead"	"Waiting for a read from a replication slot control file."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC	"ReplicationSlotRestoreSync"	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_SYNC	"ReplicationSlotSync"	"Waiting for a replication slot control file to reach durable storage."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_WRITE	"ReplicationSlotWrite"	"Waiting for a write to a replication slot control file."
+WaitEventIO	WAIT_EVENT_SLRU_FLUSH_SYNC	"SLRUFlushSync"	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+WaitEventIO	WAIT_EVENT_SLRU_READ	"SLRURead"	"Waiting for a read of an SLRU page."
+WaitEventIO	WAIT_EVENT_SLRU_SYNC	"SLRUSync"	"Waiting for SLRU data to reach durable storage following a page write."
+WaitEventIO	WAIT_EVENT_SLRU_WRITE	"SLRUWrite"	"Waiting for a write of an SLRU page."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_READ	"SnapbuildRead"	"Waiting for a read of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_SYNC	"SnapbuildSync"	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_WRITE	"SnapbuildWrite"	"Waiting for a write of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC	"TimelineHistoryFileSync"	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE	"TimelineHistoryFileWrite"	"Waiting for a write of a timeline history file received via streaming replication."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_READ	"TimelineHistoryRead"	"Waiting for a read of a timeline history file."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_SYNC	"TimelineHistorySync"	"Waiting for a newly created timeline history file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_WRITE	"TimelineHistoryWrite"	"Waiting for a write of a newly created timeline history file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_READ	"TwophaseFileRead"	"Waiting for a read of a two phase state file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_SYNC	"TwophaseFileSync"	"Waiting for a two phase state file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_WRITE	"TwophaseFileWrite"	"Waiting for a write of a two phase state file."
+WaitEventIO	WAIT_EVENT_VERSION_FILE_WRITE	"VersionFileWrite"	"Waiting for the version file to be written while creating a database."
+WaitEventIO	WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ	"WALSenderTimelineHistoryRead"	"Waiting for a read from a timeline history file during a walsender timeline command."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_SYNC	"WALBootstrapSync"	"Waiting for WAL to reach durable storage during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_WRITE	"WALBootstrapWrite"	"Waiting for a write of a WAL page during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_COPY_READ	"WALCopyRead"	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_COPY_SYNC	"WALCopySync"	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_COPY_WRITE	"WALCopyWrite"	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_INIT_SYNC	"WALInitSync"	"Waiting for a newly initialized WAL file to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_INIT_WRITE	"WALInitWrite"	"Waiting for a write while initializing a new WAL file."
+WaitEventIO	WAIT_EVENT_WAL_READ	"WALRead"	"Waiting for a read from a WAL file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN	"WALSyncMethodAssign"	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WaitEventIO	WAIT_EVENT_WAL_WRITE	"WALWrite"	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
diff --git a/src/include/Makefile b/src/include/Makefile
index 56576dcf5c..280b6968d7 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/waiteventnames.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..b4f82b3d21 100644
--- a/src/include/utils/.gitignore
+++ b/src/include/utils/.gitignore
@@ -3,3 +3,4 @@
 /probes.h
 /errcodes.h
 /header-stamp
+/waiteventnames.h
diff --git a/src/include/utils/meson.build b/src/include/utils/meson.build
index 2fed1e3f8e..826fa89323 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: ['waiteventnames.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'],
+)
+
+waiteventnames_h = waiteventnames[0]
+generated_backend_headers += waiteventnames_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': ['waiteventnames.h']}
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..7eaff872de 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -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/waiteventnames.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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 153be7be11..8c1b9a53cb 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -580,6 +580,7 @@ sub GenerateFiles
 		my $lmgr = 'src/backend/storage/lmgr';
 		system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr $lmgr/lwlocknames.txt");
 	}
+
 	if (IsNewer(
 			'src/include/storage/lwlocknames.h',
 			'src/backend/storage/lmgr/lwlocknames.h'))
@@ -589,6 +590,24 @@ sub GenerateFiles
 			'src/include/storage/lwlocknames.h');
 	}
 
+	if (IsNewer(
+			'src/include/utils/waiteventnames.h',
+			'src/backend/utils/activity/waiteventnames.txt'))
+	{
+		print "Generating waiteventnames.c and waiteventnames.h...\n";
+		my $activ = 'src/backend/utils/activity';
+		system("perl $activ/generate-waiteventnames.pl --outdir $activ $activ/waiteventnames.txt");
+	}
+
+	if (IsNewer(
+			'src/include/utils/waiteventnames.h',
+			'src/backend/utils/activity/waiteventnames.h'))
+	{
+		copyFile(
+			'src/backend/utils/activity/waiteventnames.h',
+			'src/include/utils/waiteventnames.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..6c1c3d0816 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\waiteventnames.h del /q src\include\utils\waiteventnames.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
@@ -61,7 +62,9 @@ if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q src\backend\utils\fmgr
 if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h
 if %DIST%==1 if exist src\backend\nodes\nodetags.h del /q src\backend\nodes\nodetags.h
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q src\backend\storage\lmgr\lwlocknames.c
+if %DIST%==1 if exist src\backend\utils\activity\waiteventnames.c del /q src\backend\utils\activity\waiteventnames.c
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+if %DIST%==1 if exist src\backend\utils\activity\waiteventnames.h del /q src\backend\utils\activity\waiteventnames.h
 if %DIST%==1 if exist src\pl\plpython\spiexceptions.h del /q src\pl\plpython\spiexceptions.h
 if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q src\pl\plpgsql\src\plerrcodes.h
 if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q src\pl\tcl\pltclerrcodes.h
-- 
2.34.1

#3Corey Huinker
corey.huinker@gmail.com
In reply to: Drouvot, Bertrand (#2)
Re: Autogenerate some wait events code and documentation

On Wed, Mar 29, 2023 at 8:51 AM Drouvot, Bertrand <
bertranddrouvot.pg@gmail.com> wrote:

Hi,

On 3/29/23 11:44 AM, Drouvot, Bertrand wrote:

Looking forward to your feedback,

Just realized that more polishing was needed.

Done in V2 attached.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

I think this is good work, but I can't help thinking it would be easier to
understand and maintain if we used a template engine like Text::Template,
and filled out the template with the variant bits. I'll ask that question
in another thread for higher visibility.

#4Michael Paquier
michael@paquier.xyz
In reply to: Corey Huinker (#3)
Re: Autogenerate some wait events code and documentation

On Thu, Mar 30, 2023 at 12:41:27PM -0400, Corey Huinker wrote:

I think this is good work, but I can't help thinking it would be easier to
understand and maintain if we used a template engine like Text::Template,
and filled out the template with the variant bits. I'll ask that question
in another thread for higher visibility.

Hmm.. This is not part of the main perl distribution, is it? I am
not sure that it is a good idea to increase the requirement bar when
it comes to build the code and documentation by depending more on
external modules, and the minimum version of perl supported is very
old^D^D^D ancient, making it harder to satisfy.
--
Michael

#5Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#2)
Re: Autogenerate some wait events code and documentation

On Wed, Mar 29, 2023 at 02:51:27PM +0200, Drouvot, Bertrand wrote:

Just realized that more polishing was needed.

Done in V2 attached.

That would be pretty cool to get that done in an automated way, I've
wanted that for a few years now. And I guess that a few others have
the same feeling after missing to update these docs when adding a new
wait event, or just to enforce this alphabetically, so let's do
something about it in v17.

About the alphabetical order, could we have the script enforce a sort
of the elements parsed from waiteventnames.txt, based on the second
column? This now relies on the order of the items in the file, but
my history with this stuff has proved that forcing an ordering rule
would be a very good thing long-term.

Seeing waiteventnames.txt, I think that we should have something
closer to errcodes.txt. Well, seeing the patch, I assume that this is
inspired by errcodes.txt, but this new file should be able to do more
IMO:
- Supporting the parsing of comments, by ignoring them in
generate-waiteventnames.pl.
- Ignore empty likes.
- Add a proper header, copyright, the output generated from it, etc.
- Document the format lines of the file.

It is clear that the format of the file is:
- category
- C symbol in enums.
- Format in the system views.
- Description in the docs.
Or perhaps it would be better to divide this file by sections (like
errcodes.txt) for each category so as we eliminate entirely the first
column?

This number from v2 is nice to see:
17 files changed, 423 insertions(+), 955 deletions(-)

Perhaps waiteventnames.c should be named pgstat_wait_event.c? The
result is simply the set of pgstat functions, included in
wait_event.c (this inclusion is OK for me). Similarly,
wait_event_types.h would be a better name for the set of enums?

          utils/adt/jsonpath_scan.c \
+         utils/activity/waiteventnames.c \
+         utils/activity/waiteventnames.h \
+         utils/adt/jsonpath_scan.c \

Looks like a copy-pasto.

Note that the patch does not apply, there is a conflict in the docs.
--
Michael

#6Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#5)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 4/20/23 3:09 AM, Michael Paquier wrote:

On Wed, Mar 29, 2023 at 02:51:27PM +0200, Drouvot, Bertrand wrote:

Just realized that more polishing was needed.

Done in V2 attached.

That would be pretty cool to get that done in an automated way, I've
wanted that for a few years now. And I guess that a few others have
the same feeling after missing to update these docs when adding a new
wait event, or just to enforce this alphabetically, so let's do
something about it in v17.

Thanks for the feedback!

About the alphabetical order, could we have the script enforce a sort
of the elements parsed from waiteventnames.txt, based on the second
column? This now relies on the order of the items in the file, but
my history with this stuff has proved that forcing an ordering rule
would be a very good thing long-term.

Not having the lines in order would not have been a problem for the perl script
(as it populated the hash table based on the category column while reading the
text file).

That said I do agree that enforcing an order is a good idea, as it's "easier" to read
the generated output files (their content is now somehow "ordered").

This is done in V3 attached.

Seeing waiteventnames.txt, I think that we should have something
closer to errcodes.txt. Well, seeing the patch, I assume that this is
inspired by errcodes.txt, but this new file should be able to do more
IMO:
- Supporting the parsing of comments, by ignoring them in
generate-waiteventnames.pl.
- Ignore empty likes.
- Add a proper header, copyright, the output generated from it, etc.
- Document the format lines of the file.

Fully agree, it's done in V3 attached.

It is clear that the format of the file is:
- category
- C symbol in enums.
- Format in the system views.
- Description in the docs.
Or perhaps it would be better to divide this file by sections (like
errcodes.txt) for each category so as we eliminate entirely the first
column?

Yeah, that could be an option. V3 is still using the category as the first column
but I'm ok to change it by a section if you prefer (though I don't really see the need).

Perhaps waiteventnames.c should be named pgstat_wait_event.c?

Agree, done.

Similarly,
wait_event_types.h would be a better name for the set of enums?

Also agree, done.

utils/adt/jsonpath_scan.c \
+         utils/activity/waiteventnames.c \
+         utils/activity/waiteventnames.h \
+         utils/adt/jsonpath_scan.c \

Looks like a copy-pasto.

Why do you think so? both files have to be removed.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v3-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v3-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From aa359811161198d7a811113e2853e22aec10a40f Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Sat, 22 Apr 2023 10:37:56 +0000
Subject: [PATCH v3] 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
---
 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                  | 792 +-----------------
 src/backend/Makefile                          |  14 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 171 ++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 188 +++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 214 +----
 src/tools/msvc/Solution.pm                    |  19 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 468 insertions(+), 1572 deletions(-)
  35.9% doc/src/sgml/
  53.1% src/backend/utils/activity/
   8.6% src/include/utils/

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..c8648fca18 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +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>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -1257,623 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -2305,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
     </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>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..fb67f13822 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 $@
 
@@ -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
 
 
 ##########################################################################
@@ -305,6 +314,9 @@ maintainer-clean: distclean
 	      utils/adt/jsonpath_gram.c \
 	      utils/adt/jsonpath_gram.h \
 	      utils/adt/jsonpath_scan.c \
+	      utils/activity/pgstat_wait_event.c \
+	      utils/activity/wait_event_types.h \
+	      utils/adt/jsonpath_scan.c \
 	      utils/misc/guc-file.c
 
 
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..219807fe56
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,171 @@
+#!/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;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", "PG_WAIT_TIMEOUT", "PG_WAIT_IO");
+
+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 WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_H\n\n";
+printf $h "#include \"utils/wait_event.h\"\n\n";
+
+printf $c $header_comment, 'pgstat_wait_event.c';
+
+my @lines;
+my $line;
+
+# Remove comments and empty lines
+while (<$waiteventnames>)
+{
+	chomp;
+
+	# Skip comments
+	next if /^#/;
+
+	# Skip empty lines
+	next if /^\s*$/;
+
+	push(@lines, $_);
+}
+
+# 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_//;
+	die "wait event names must start with 'WAIT_EVENT_'" if $trimmedwaiteventname eq $waiteventenumname;
+	$continue    = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe) {
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastuc = uc $last;
+	my $lastlc = lc $last;
+	my $firstpass = 1;
+	my $pg_wait_class;
+
+	printf $h "typedef enum\n{\n";
+
+	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";
+
+	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>Activity</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}}) {
+		if ($firstpass) {
+			$pg_wait_class = "PG_WAIT_".$lastuc;
+			die "waitclass $pg_wait_class does not exist" unless grep( /^$pg_wait_class$/, @wait_classes );
+			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 $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 $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 $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+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..4831f8a25e 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,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..0e56afaea7
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,188 @@
+#
+# 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 following
+# tab-separated fields:
+#
+#      category "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
+# category.
+#
+# This file is used as input by src/backend/utils/activity/generate-waiteventnames.pl
+#
+
+WaitEventActivity	WAIT_EVENT_ARCHIVER_MAIN	"ArchiverMain"	"Waiting in main loop of archiver process."
+WaitEventActivity	WAIT_EVENT_AUTOVACUUM_MAIN	"AutoVacuumMain"	"Waiting in main loop of autovacuum launcher process."
+WaitEventActivity	WAIT_EVENT_BGWRITER_HIBERNATE	"BgWriterHibernate"	"Waiting in background writer process, hibernating."
+WaitEventActivity	WAIT_EVENT_BGWRITER_MAIN	"BgWriterMain"	"Waiting in main loop of background writer process."
+WaitEventActivity	WAIT_EVENT_CHECKPOINTER_MAIN	"CheckpointerMain"	"Waiting in main loop of checkpointer process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_APPLY_MAIN	"LogicalApplyMain"	"Waiting in main loop of logical replication apply process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_LAUNCHER_MAIN	"LogicalLauncherMain"	"Waiting in main loop of logical replication launcher process."
+WaitEventActivity	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN	"LogicalParallelApplyMain"	"Waiting in main loop of logical replication parallel apply process."
+WaitEventActivity	WAIT_EVENT_RECOVERY_WAL_STREAM	"RecoveryWalStream"	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+WaitEventActivity	WAIT_EVENT_SYSLOGGER_MAIN	"SysLoggerMain"	"Waiting in main loop of syslogger process."
+WaitEventActivity	WAIT_EVENT_WAL_RECEIVER_MAIN	"WalReceiverMain"	"Waiting in main loop of WAL receiver process."
+WaitEventActivity	WAIT_EVENT_WAL_SENDER_MAIN	"WalSenderMain"	"Waiting in main loop of WAL sender process."
+WaitEventActivity	WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer process."
+WaitEventClient	WAIT_EVENT_CLIENT_READ	"ClientRead"	"Waiting to read data from the client."
+WaitEventClient	WAIT_EVENT_CLIENT_WRITE	"ClientWrite"	"Waiting to write data to the client."
+WaitEventClient	WAIT_EVENT_GSS_OPEN_SERVER	"GSSOpenServer"	"Waiting to read data from the client while establishing a GSSAPI session."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_CONNECT	"LibPQWalReceiverConnect"	"Waiting in WAL receiver to establish connection to remote server."
+WaitEventClient	WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE	"LibPQWalReceiverReceive"	"Waiting in WAL receiver to receive data from remote server."
+WaitEventClient	WAIT_EVENT_SSL_OPEN_SERVER	"SSLOpenServer"	"Waiting for SSL while attempting connection."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WAIT_WAL	"WalSenderWaitForWAL"	"Waiting for WAL to be flushed in WAL sender process."
+WaitEventClient	WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
+WaitEventIPC	WAIT_EVENT_APPEND_READY	"AppendReady"	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	"ArchiveCleanupCommand"	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_ARCHIVE_COMMAND	"ArchiveCommand"	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_BACKEND_TERMINATION	"BackendTermination"	"Waiting for the termination of another backend."
+WaitEventIPC	WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE	"BackupWaitWalArchive"	"Waiting for WAL files required for a backup to be successfully archived."
+WaitEventIPC	WAIT_EVENT_BGWORKER_SHUTDOWN	"BgWorkerShutdown"	"Waiting for background worker to shut down."
+WaitEventIPC	WAIT_EVENT_BGWORKER_STARTUP	"BgWorkerStartup"	"Waiting for background worker to start up."
+WaitEventIPC	WAIT_EVENT_BTREE_PAGE	"BtreePage"	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+WaitEventIPC	WAIT_EVENT_BUFFER_IO	"BufferIO"	"Waiting for buffer I/O to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_DONE	"CheckpointDone"	"Waiting for a checkpoint to complete."
+WaitEventIPC	WAIT_EVENT_CHECKPOINT_START	"CheckpointStart"	"Waiting for a checkpoint to start."
+WaitEventIPC	WAIT_EVENT_EXECUTE_GATHER	"ExecuteGather"	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ALLOCATE	"HashBatchAllocate"	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_ELECT	"HashBatchElect"	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BATCH_LOAD	"HashBatchLoad"	"Waiting for other Parallel Hash participants to finish loading a hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ALLOCATE	"HashBuildAllocate"	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_ELECT	"HashBuildElect"	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_INNER	"HashBuildHashInner"	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+WaitEventIPC	WAIT_EVENT_HASH_BUILD_HASH_OUTER	"HashBuildHashOuter"	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE	"HashGrowBatchesDecide"	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_ELECT	"HashGrowBatchesElect"	"Waiting to elect a Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_FINISH	"HashGrowBatchesFinish"	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE	"HashGrowBatchesReallocate"	"Waiting for an elected Parallel Hash participant to allocate more batches."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION	"HashGrowBatchesRepartition"	"Waiting for other Parallel Hash participants to finish repartitioning."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT	"HashGrowBucketsElect"	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE	"HashGrowBucketsReallocate"	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+WaitEventIPC	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT	"HashGrowBucketsReinsert"	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+WaitEventIPC	WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	"LogicalApplySendData"	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+WaitEventIPC	WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"LogicalParallelApplyStateChange"	"Waiting for a logical replication parallel apply process to change state."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_DATA	"LogicalSyncData"	"Waiting for a logical replication remote server to send data for initial table synchronization."
+WaitEventIPC	WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE	"LogicalSyncStateChange"	"Waiting for a logical replication remote server to change state."
+WaitEventIPC	WAIT_EVENT_MQ_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
+WaitEventIPC	WAIT_EVENT_MQ_SEND	"MessageQueueSend"	"Waiting to send bytes to a shared message queue."
+WaitEventIPC	WAIT_EVENT_PARALLEL_BITMAP_SCAN	"ParallelBitmapScan"	"Waiting for parallel bitmap scan to become initialized."
+WaitEventIPC	WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN	"ParallelCreateIndexScan"	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+WaitEventIPC	WAIT_EVENT_PARALLEL_FINISH	"ParallelFinish"	"Waiting for parallel workers to finish computing."
+WaitEventIPC	WAIT_EVENT_PROCARRAY_GROUP_UPDATE	"ProcArrayGroupUpdate"	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+WaitEventIPC	WAIT_EVENT_PROC_SIGNAL_BARRIER	"ProcSignalBarrier"	"Waiting for a barrier event to be processed by all backends."
+WaitEventIPC	WAIT_EVENT_PROMOTE	"Promote"	"Waiting for standby promotion."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT	"RecoveryConflictSnapshot"	"Waiting for recovery conflict resolution for a vacuum cleanup."
+WaitEventIPC	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE	"RecoveryConflictTablespace"	"Waiting for recovery conflict resolution for dropping a tablespace."
+WaitEventIPC	WAIT_EVENT_RECOVERY_END_COMMAND	"RecoveryEndCommand"	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_RECOVERY_PAUSE	"RecoveryPause"	"Waiting for recovery to be resumed."
+WaitEventIPC	WAIT_EVENT_REPLICATION_ORIGIN_DROP	"ReplicationOriginDrop"	"Waiting for a replication origin to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_REPLICATION_SLOT_DROP	"ReplicationSlotDrop"	"Waiting for a replication slot to become inactive so it can be dropped."
+WaitEventIPC	WAIT_EVENT_RESTORE_COMMAND	"RestoreCommand"	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+WaitEventIPC	WAIT_EVENT_SAFE_SNAPSHOT	"SafeSnapshot"	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+WaitEventIPC	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."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_EXIT	"WalReceiverExit"	"Waiting for the WAL receiver to exit."
+WaitEventIPC	WAIT_EVENT_WAL_RECEIVER_WAIT_START	"WalReceiverWaitStart"	"Waiting for startup process to send initial data for streaming replication."
+WaitEventIPC	WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to update transaction status at end of a parallel operation."
+WaitEventTimeout	WAIT_EVENT_BASE_BACKUP_THROTTLE	"BaseBackupThrottle"	"Waiting during base backup when throttling activity."
+WaitEventTimeout	WAIT_EVENT_CHECKPOINT_WRITE_DELAY	"CheckpointWriteDelay"	"Waiting between writes while performing a checkpoint."
+WaitEventTimeout	WAIT_EVENT_PG_SLEEP	"PgSleep"	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+WaitEventTimeout	WAIT_EVENT_RECOVERY_APPLY_DELAY	"RecoveryApplyDelay"	"Waiting to apply WAL during recovery because of a delay setting."
+WaitEventTimeout	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)."
+WaitEventTimeout	WAIT_EVENT_REGISTER_SYNC_REQUEST	"RegisterSyncRequest"	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+WaitEventTimeout	WAIT_EVENT_SPIN_DELAY	"SpinDelay"	"Waiting while acquiring a contended spinlock."
+WaitEventTimeout	WAIT_EVENT_VACUUM_DELAY	"VacuumDelay"	"Waiting in a cost-based vacuum delay point."
+WaitEventTimeout	WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_READ	"BaseBackupRead"	"Waiting for base backup to read from a file."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_SYNC	"BaseBackupSync"	"Waiting for data written by a base backup to reach durable storage."
+WaitEventIO	WAIT_EVENT_BASEBACKUP_WRITE	"BaseBackupWrite"	"Waiting for base backup to write to a file."
+WaitEventIO	WAIT_EVENT_BUFFILE_READ	"BufFileRead"	"Waiting for a read from a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_WRITE	"BufFileWrite"	"Waiting for a write to a buffered file."
+WaitEventIO	WAIT_EVENT_BUFFILE_TRUNCATE	"BufFileTruncate"	"Waiting for a buffered file to be truncated."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_READ	"ControlFileRead"	"Waiting for a read from the <filename>pg_control</filename> file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	"ControlFileSyncUpdate"	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE	"ControlFileWriteUpdate"	"Waiting for a write to update the <filename>pg_control</filename> file."
+WaitEventIO	WAIT_EVENT_COPY_FILE_READ	"CopyFileRead"	"Waiting for a read during a file copy operation."
+WaitEventIO	WAIT_EVENT_COPY_FILE_WRITE	"CopyFileWrite"	"Waiting for a write during a file copy operation."
+WaitEventIO	WAIT_EVENT_DATA_FILE_EXTEND	"DataFileExtend"	"Waiting for a relation data file to be extended."
+WaitEventIO	WAIT_EVENT_DATA_FILE_FLUSH	"DataFileFlush"	"Waiting for a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC	"DataFileImmediateSync"	"Waiting for an immediate synchronization of a relation data file to durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_PREFETCH	"DataFilePrefetch"	"Waiting for an asynchronous prefetch from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_READ	"DataFileRead"	"Waiting for a read from a relation data file."
+WaitEventIO	WAIT_EVENT_DATA_FILE_SYNC	"DataFileSync"	"Waiting for changes to a relation data file to reach durable storage."
+WaitEventIO	WAIT_EVENT_DATA_FILE_TRUNCATE	"DataFileTruncate"	"Waiting for a relation data file to be truncated."
+WaitEventIO	WAIT_EVENT_DATA_FILE_WRITE	"DataFileWrite"	"Waiting for a write to a relation data file."
+WaitEventIO	WAIT_EVENT_DSM_ALLOCATE	"DSMAllocate"	"Waiting for a dynamic shared memory segment to be allocated."
+WaitEventIO	WAIT_EVENT_DSM_FILL_ZERO_WRITE	"DSMFillZeroWrite"	"Waiting to fill a dynamic shared memory backing file with zeroes."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ	"LockFileAddToDataDirRead"	"Waiting for a read while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC	"LockFileAddToDataDirSync"	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE	"LockFileAddToDataDirWrite"	"Waiting for a write while adding a line to the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_READ	"LockFileCreateRead"	"Waiting to read while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_SYNC	"LockFileCreateSync"	"Waiting for data to reach durable storage while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_CREATE_WRITE	"LockFileCreateWrite"	"Waiting for a write while creating the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ	"LockFileReCheckDataDirRead"	"Waiting for a read during recheck of the data directory lock file."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC	"LogicalRewriteCheckpointSync"	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC	"LogicalRewriteMappingSync"	"Waiting for mapping data to reach durable storage during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE	"LogicalRewriteMappingWrite"	"Waiting for a write of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_SYNC	"LogicalRewriteSync"	"Waiting for logical rewrite mappings to reach durable storage."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE	"LogicalRewriteTruncate"	"Waiting for truncate of mapping data during a logical rewrite."
+WaitEventIO	WAIT_EVENT_LOGICAL_REWRITE_WRITE	"LogicalRewriteWrite"	"Waiting for a write of logical rewrite mappings."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_READ	"RelationMapRead"	"Waiting for a read of the relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_REPLACE	"RelationMapReplace"	"Waiting for durable replacement of a relation map file."
+WaitEventIO	WAIT_EVENT_RELATION_MAP_WRITE	"RelationMapWrite"	"Waiting for a write to the relation map file."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_READ	"ReorderBufferRead"	"Waiting for a read during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_BUFFER_WRITE	"ReorderBufferWrite"	"Waiting for a write during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ	"ReorderLogicalMappingRead"	"Waiting for a read of a logical mapping during reorder buffer management."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_READ	"ReplicationSlotRead"	"Waiting for a read from a replication slot control file."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC	"ReplicationSlotRestoreSync"	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_SYNC	"ReplicationSlotSync"	"Waiting for a replication slot control file to reach durable storage."
+WaitEventIO	WAIT_EVENT_REPLICATION_SLOT_WRITE	"ReplicationSlotWrite"	"Waiting for a write to a replication slot control file."
+WaitEventIO	WAIT_EVENT_SLRU_FLUSH_SYNC	"SLRUFlushSync"	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+WaitEventIO	WAIT_EVENT_SLRU_READ	"SLRURead"	"Waiting for a read of an SLRU page."
+WaitEventIO	WAIT_EVENT_SLRU_SYNC	"SLRUSync"	"Waiting for SLRU data to reach durable storage following a page write."
+WaitEventIO	WAIT_EVENT_SLRU_WRITE	"SLRUWrite"	"Waiting for a write of an SLRU page."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_READ	"SnapbuildRead"	"Waiting for a read of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_SYNC	"SnapbuildSync"	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+WaitEventIO	WAIT_EVENT_SNAPBUILD_WRITE	"SnapbuildWrite"	"Waiting for a write of a serialized historical catalog snapshot."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC	"TimelineHistoryFileSync"	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE	"TimelineHistoryFileWrite"	"Waiting for a write of a timeline history file received via streaming replication."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_READ	"TimelineHistoryRead"	"Waiting for a read of a timeline history file."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_SYNC	"TimelineHistorySync"	"Waiting for a newly created timeline history file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TIMELINE_HISTORY_WRITE	"TimelineHistoryWrite"	"Waiting for a write of a newly created timeline history file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_READ	"TwophaseFileRead"	"Waiting for a read of a two phase state file."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_SYNC	"TwophaseFileSync"	"Waiting for a two phase state file to reach durable storage."
+WaitEventIO	WAIT_EVENT_TWOPHASE_FILE_WRITE	"TwophaseFileWrite"	"Waiting for a write of a two phase state file."
+WaitEventIO	WAIT_EVENT_VERSION_FILE_WRITE	"VersionFileWrite"	"Waiting for the version file to be written while creating a database."
+WaitEventIO	WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ	"WALSenderTimelineHistoryRead"	"Waiting for a read from a timeline history file during a walsender timeline command."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_SYNC	"WALBootstrapSync"	"Waiting for WAL to reach durable storage during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_BOOTSTRAP_WRITE	"WALBootstrapWrite"	"Waiting for a write of a WAL page during bootstrapping."
+WaitEventIO	WAIT_EVENT_WAL_COPY_READ	"WALCopyRead"	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_COPY_SYNC	"WALCopySync"	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_COPY_WRITE	"WALCopyWrite"	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WaitEventIO	WAIT_EVENT_WAL_INIT_SYNC	"WALInitSync"	"Waiting for a newly initialized WAL file to reach durable storage."
+WaitEventIO	WAIT_EVENT_WAL_INIT_WRITE	"WALInitWrite"	"Waiting for a write while initializing a new WAL file."
+WaitEventIO	WAIT_EVENT_WAL_READ	"WALRead"	"Waiting for a read from a WAL file."
+WaitEventIO	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."
+WaitEventIO	WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN	"WALSyncMethodAssign"	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WaitEventIO	WAIT_EVENT_WAL_WRITE	"WALWrite"	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
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..160227972e 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..784d2f518d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -582,6 +582,7 @@ sub GenerateFiles
 		my $lmgr = 'src/backend/storage/lmgr';
 		system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr $lmgr/lwlocknames.txt");
 	}
+
 	if (IsNewer(
 			'src/include/storage/lwlocknames.h',
 			'src/backend/storage/lmgr/lwlocknames.h'))
@@ -591,6 +592,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..22d6f52e72 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
@@ -61,7 +62,9 @@ if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q src\backend\utils\fmgr
 if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h
 if %DIST%==1 if exist src\backend\nodes\nodetags.h del /q src\backend\nodes\nodetags.h
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q src\backend\storage\lmgr\lwlocknames.c
+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\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+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\pl\plpython\spiexceptions.h del /q src\pl\plpython\spiexceptions.h
 if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q src\pl\plpgsql\src\plerrcodes.h
 if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q src\pl\tcl\pltclerrcodes.h
-- 
2.34.1

#7Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#6)
Re: Autogenerate some wait events code and documentation

On Sat, Apr 22, 2023 at 03:36:05PM +0200, Drouvot, Bertrand wrote:

On 4/20/23 3:09 AM, Michael Paquier wrote:

It is clear that the format of the file is:
- category
- C symbol in enums.
- Format in the system views.
- Description in the docs.
Or perhaps it would be better to divide this file by sections (like
errcodes.txt) for each category so as we eliminate entirely the first
column?

Yeah, that could be an option. V3 is still using the category as the first column
but I'm ok to change it by a section if you prefer (though I don't really see the need).

It can make the file width shorter, at least..

[ .. thinks .. ]

+my $waitclass;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", "PG_WAIT_TIMEOUT", "PG_WAIT_IO");

Actually, having a "Section" in waiteventnames.txt would remove the
need to store this knowledge in generate-waiteventnames.pl, which is
a duplicate of the txt contents. If somebody adds a new class in the
future, it would be necessary to update this path as well. Well, that
would not be a huge effort in itself, but IMO the script translating
the .txt to the docs and the code should have no need to know the
types of classes. I guess that a format like that would make the most
sense to me, then:
Section: ClassName PG_WAIT_CLASS_NAME

# ClassName would be "IO", "IPC", "Timeout", etc.

WAIT_EVENT_NAME_1 "WaitEventName1" "Description of wait event 1"
WAIT_EVENT_NAME_N "WaitEventNameN" "Description of wait event N"

utils/adt/jsonpath_scan.c \
+         utils/activity/waiteventnames.c \
+         utils/activity/waiteventnames.h \
+         utils/adt/jsonpath_scan.c \

Looks like a copy-pasto.

Why do you think so? both files have to be removed.

jsonpath_scan.c is listed twice, and that's still the case in v3. The
list of files deleted for maintainer-clean in src/backend/Makefile
should be listed alphabetically (utils/activity/ before utils/adt/),
but that's a nit ;)
--
Michael

#8Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#7)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 4/24/23 5:15 AM, Michael Paquier wrote:

On Sat, Apr 22, 2023 at 03:36:05PM +0200, Drouvot, Bertrand wrote:

On 4/20/23 3:09 AM, Michael Paquier wrote:

It is clear that the format of the file is:
- category
- C symbol in enums.
- Format in the system views.
- Description in the docs.
Or perhaps it would be better to divide this file by sections (like
errcodes.txt) for each category so as we eliminate entirely the first
column?

Yeah, that could be an option. V3 is still using the category as the first column
but I'm ok to change it by a section if you prefer (though I don't really see the need).

It can make the file width shorter, at least..

Right.

[ .. thinks .. ]

+my $waitclass;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", "PG_WAIT_TIMEOUT", "PG_WAIT_IO");

Actually, having a "Section" in waiteventnames.txt would remove the
need to store this knowledge in generate-waiteventnames.pl, which is
a duplicate of the txt contents. If somebody adds a new class in the
future, it would be necessary to update this path as well. Well, that
would not be a huge effort in itself, but IMO the script translating
the .txt to the docs and the code should have no need to know the
types of classes. I guess that a format like that would make the most
sense to me, then:
Section: ClassName PG_WAIT_CLASS_NAME

# ClassName would be "IO", "IPC", "Timeout", etc.

WAIT_EVENT_NAME_1 "WaitEventName1" "Description of wait event 1"
WAIT_EVENT_NAME_N "WaitEventNameN" "Description of wait event N"

I gave another thought on it, and do agree that's better to use sections
in the .txt file. This is done in V4 attached.

utils/adt/jsonpath_scan.c \
+         utils/activity/waiteventnames.c \
+         utils/activity/waiteventnames.h \
+         utils/adt/jsonpath_scan.c \

Looks like a copy-pasto.

Why do you think so? both files have to be removed.

jsonpath_scan.c is listed twice, and that's still the case in v3.

Oh I see, I misunderstood what you thought the typo was.
Fixed in V4 thanks!

The
list of files deleted for maintainer-clean in src/backend/Makefile
should be listed alphabetically (utils/activity/ before utils/adt/),
but that's a nit ;)

Oh right, fixed.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v4-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v4-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From 2d3fa2567a80c3431bf9682510d483ac0f1d7cec Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Sat, 22 Apr 2023 10:37:56 +0000
Subject: [PATCH v4] 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
---
 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                  | 792 +-----------------
 src/backend/Makefile                          |  13 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 178 ++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 202 +++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 214 +----
 src/tools/msvc/Solution.pm                    |  19 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 488 insertions(+), 1572 deletions(-)
  36.8% doc/src/sgml/
  52.0% src/backend/utils/activity/
   8.8% src/include/utils/

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..c8648fca18 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +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>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -1257,623 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -2305,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
     </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>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..a82c908315 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 $@
 
@@ -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
 
 
 ##########################################################################
@@ -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/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..ae49e0d9d9
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,178 @@
+#!/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 WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_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;
+
+# 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:(.*)/)
+	{
+		$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_//;
+	die "wait event names must start with 'WAIT_EVENT_'" if $trimmedwaiteventname eq $waiteventenumname;
+	$continue    = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe) {
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	my $lastuc = uc $last;
+	my $lastlc = lc $last;
+	my $firstpass = 1;
+	my $pg_wait_class;
+
+	printf $h "typedef enum\n{\n";
+
+	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";
+
+	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>Activity</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}}) {
+		if ($firstpass) {
+			$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 $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 $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 $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+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..4831f8a25e 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,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..1994823666
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,202 @@
+#
+# 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
+# section.
+#
+# This file is used as input by src/backend/utils/activity/generate-waiteventnames.pl
+#
+
+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."
+
+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."
+
+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."
+
+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."
+
+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."
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..160227972e 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..784d2f518d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -582,6 +582,7 @@ sub GenerateFiles
 		my $lmgr = 'src/backend/storage/lmgr';
 		system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr $lmgr/lwlocknames.txt");
 	}
+
 	if (IsNewer(
 			'src/include/storage/lwlocknames.h',
 			'src/backend/storage/lmgr/lwlocknames.h'))
@@ -591,6 +592,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..22d6f52e72 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
@@ -61,7 +62,9 @@ if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q src\backend\utils\fmgr
 if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h
 if %DIST%==1 if exist src\backend\nodes\nodetags.h del /q src\backend\nodes\nodetags.h
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q src\backend\storage\lmgr\lwlocknames.c
+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\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+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\pl\plpython\spiexceptions.h del /q src\pl\plpython\spiexceptions.h
 if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q src\pl\plpgsql\src\plerrcodes.h
 if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q src\pl\tcl\pltclerrcodes.h
-- 
2.34.1

#9Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#8)
Re: Autogenerate some wait events code and documentation

On Mon, Apr 24, 2023 at 09:03:53AM +0200, Drouvot, Bertrand wrote:

Oh right, fixed.

I may tweak a few things if I put my hands on it, but that looks
pretty solid seen from here.. I have spotted a few extra issues.

One thing I have noticed with v4 is that the order of the tables
generated in wait_event_types.h and the SGML docs is inconsistent with
previous versions, and these are not in an alphabetical order. HEAD
orders them as Activity, BufferPin, Client, Extension, IO, IPC, Lock,
LWLock and Timeout. This patch switches the order to become
different, and note that the first table describing each of the wait
event type classes gets it right.

It seems to me that you should apply an extra ordering in
generate-waiteventnames.pl to make sure that the tables are printed in
the same order as previously, around here:
+# Generate the output files
+foreach $waitclass (keys %hashwe) {

(The table describing all the wait event types could be removed from
the SGML docs as well, at the cost of having their description in the
new .txt file. However, as these are long, it would make the .txt
file much messier, so not doing this extra part is OK for me.)

- * 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

wait_event.h includes a set of comments describing each category, that
this patch removes. Rather than removing this information, which is
helpful to have around, why not making them comments of
waiteventnames.txt instead? Losing this information would be sad.

+#   src/backend/utils/activity/pgstat_wait_event.c
+#      c functions to get the wait event name based on the enum
Nit.  'c' should be upper-case.

}
+
if (IsNewer(
'src/include/storage/lwlocknames.h',
Not wrong, but this is an unrelated diff.

+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\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+if %DIST%==1 if exist src\backend\utils\activity\wait_event_types.h del /q src\backend\utils\activity\wait_event_types.h
The order here is off a bit.  Missed that previously..

perltidy had better be run on generate-waiteventnames.pl (I can do
that myself, no worries), as a couple of lines' format don't seem
quite in line.
--
Michael

#10Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#9)
Re: Autogenerate some wait events code and documentation

Hi,

On 4/25/23 7:15 AM, Michael Paquier wrote:

On Mon, Apr 24, 2023 at 09:03:53AM +0200, Drouvot, Bertrand wrote:

Oh right, fixed.

I may tweak a few things if I put my hands on it, but that looks
pretty solid seen from here..

Glad to hear! ;-)

I have spotted a few extra issues.

One thing I have noticed with v4 is that the order of the tables
generated in wait_event_types.h and the SGML docs is inconsistent with
previous versions, and these are not in an alphabetical order. HEAD
orders them as Activity, BufferPin, Client, Extension, IO, IPC, Lock,
LWLock and Timeout. This patch switches the order to become
different, and note that the first table describing each of the wait
event type classes gets it right.

Right, ordering being somehow broken is also something I did mention initially when I first
presented this patch up-thread. That's also due to the fact that this patch
does not autogenerate PG_WAIT_LWLOCK, PG_WAIT_LOCK, PG_WAIT_BUFFER_PIN and PG_WAIT_EXTENSION.

It seems to me that you should apply an extra ordering in
generate-waiteventnames.pl to make sure that the tables are printed in
the same order as previously, around here:
+# Generate the output files
+foreach $waitclass (keys %hashwe) {

Yeah but that would still affect only the auto-generated one and then
result to having the wait event part of the documentation "monitoring-stats"
not ordered as compared to the "Wait Event Types" Table.

And as we have only one "include" in doc/src/sgml/monitoring.sgml for all the
auto-generated one, the ordering would still be broken.

(The table describing all the wait event types could be removed from
the SGML docs as well, at the cost of having their description in the
new .txt file. However, as these are long, it would make the .txt
file much messier, so not doing this extra part is OK for me.)

Right, but that might be a valuable option to also fix the ordering issue
mentioned above (need to look deeper at this).

- * 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

wait_event.h includes a set of comments describing each category, that
this patch removes. Rather than removing this information, which is
helpful to have around, why not making them comments of
waiteventnames.txt instead? Losing this information would be sad.

Yeah, good point, I'll look at this.

+#   src/backend/utils/activity/pgstat_wait_event.c
+#      c functions to get the wait event name based on the enum
Nit.  'c' should be upper-case.

}
+
if (IsNewer(
'src/include/storage/lwlocknames.h',
Not wrong, but this is an unrelated diff.

Yeah, probably due to a pgindent run.

+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\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h
+if %DIST%==1 if exist src\backend\utils\activity\wait_event_types.h del /q src\backend\utils\activity\wait_event_types.h
The order here is off a bit.  Missed that previously..

perltidy had better be run on generate-waiteventnames.pl (I can do
that myself, no worries), as a couple of lines' format don't seem
quite in line.

Will do, no problem at all.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#11Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Drouvot, Bertrand (#10)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 4/26/23 6:51 PM, Drouvot, Bertrand wrote:

Hi,

On 4/25/23 7:15 AM, Michael Paquier wrote:

Will do, no problem at all.

Please find attached V5 addressing the previous comments except
the "ordering" one (need to look deeper at this).

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v5-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v5-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From b9a270c72ede800f2819b326aef7a7144027d861 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Sat, 22 Apr 2023 10:37:56 +0000
Subject: [PATCH v5] 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
---
 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                  | 792 +-----------------
 src/backend/Makefile                          |  13 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 204 +++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 245 ++++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 214 +----
 src/tools/msvc/Solution.pm                    |  18 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 556 insertions(+), 1572 deletions(-)
  36.2% doc/src/sgml/
  52.9% src/backend/utils/activity/
   8.6% src/include/utils/

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..c8648fca18 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +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>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -1257,623 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
    </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">
@@ -2305,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
     </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>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..a82c908315 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 $@
 
@@ -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
 
 
 ##########################################################################
@@ -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/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..a3c78178bd
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,204 @@
+#!/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 %hashwrc_comment;
+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 WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_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;
+
+# 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:(.*)/)
+	{
+		$section_name = $_;
+		$section_name =~ s/^.*- //;
+		next;
+	}
+
+	if (/^.\*/)
+	{
+		# Those are comments we want to see in the header file
+		push(@{ $hashwrc_comment{$section_name} }, $_);
+	}
+	else
+	{
+		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_//;
+	die "wait event names must start with 'WAIT_EVENT_'"
+	  if $trimmedwaiteventname eq $waiteventenumname;
+	$continue = ",\n";
+	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe)
+{
+	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";
+
+	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>Activity</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} })
+	{
+		if ($firstpass)
+		{
+			foreach my $wcc (@{ $hashwrc_comment{$waitclass} })
+			{
+				printf $h "%s\n", $wcc;
+			}
+			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 $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 $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 $s "    </tbody>\n";
+	printf $s "   </tgroup>\n";
+	printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+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..4831f8a25e 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,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..7cab9e506e
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,245 @@
+#
+# 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
+# section.
+#
+# The lines that start with /* or " *" are treated as comments that will be
+# put in the wait_event_types.h file based on their associated sections.
+#
+# This file is used as input by src/backend/utils/activity/generate-waiteventnames.pl
+#
+
+Section: ClassName - WaitEventActivity
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventClient
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventIPC
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventTimeout
+
+/* ----------
+ * Wait Events - Timeout
+ *
+ * Use this category when a process is waiting for a timeout to expire.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventIO
+
+/* ----------
+ * Wait Events - IO
+ *
+ * Use this category when a process is waiting for a IO.
+ * ----------
+ */
+
+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."
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..160227972e 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -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/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
-- 
2.34.1

#12Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#11)
Re: Autogenerate some wait events code and documentation

On Wed, Apr 26, 2023 at 08:36:44PM +0200, Drouvot, Bertrand wrote:

Please find attached V5 addressing the previous comments except
the "ordering" one (need to look deeper at this).

I was putting my hands into that, and I see now what you mean here..
Among the nine types of wait events, Lock, LWLock, BufferPin and
Extension don't get generated at all.

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. I
would be tempted to do that, actually, and force an ordering for all
the wait event categories in generate-waiteventnames.pl with something
like that:
# Generate the output files
-foreach $waitclass (keys %hashwe)
+foreach $waitclass (sort keys %hashwe)

BufferPin and Extension don't really imply an extra cost by the way:
they could just be added to the txt for the wait events even if they
have one single element for now.
--
Michael

#13Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#12)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 4/27/23 8:13 AM, Michael Paquier wrote:

On Wed, Apr 26, 2023 at 08:36:44PM +0200, Drouvot, Bertrand wrote:

Please find attached V5 addressing the previous comments except
the "ordering" one (need to look deeper at this).

I was putting my hands into that, and I see now what you mean here..
Among the nine types of wait events, Lock, LWLock, BufferPin and
Extension don't get generated at all.

Right.

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.

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.

I would be tempted to do that, actually, and force an ordering for all
the wait event categories in generate-waiteventnames.pl with something
like that:
# Generate the output files
-foreach $waitclass (keys %hashwe)
+foreach $waitclass (sort keys %hashwe)

Agree, done in V6.

BufferPin and Extension don't really imply an extra cost by the way:
they could just be added to the txt for the wait events even if they
have one single element for now.

Right, done that way in V6.

Please note that it creates 2 new "wait events": WAIT_EVENT_EXTENSION and WAIT_EVENT_BUFFER_PIN.

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

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v6-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v6-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From ae6aa94c61c15aad99b9cb66cd7f6ca121ebdf91 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Sat, 22 Apr 2023 10:37:56 +0000
Subject: [PATCH v6] 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
---
 contrib/dblink/dblink.c                       |    4 +-
 contrib/pg_prewarm/autoprewarm.c              |    4 +-
 contrib/postgres_fdw/connection.c             |    6 +-
 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                  | 1261 +----------------
 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/Makefile           |   10 +
 .../utils/activity/generate-waiteventnames.pl |  255 ++++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  585 +-------
 src/backend/utils/activity/waiteventnames.txt |  332 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  214 +--
 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 +-
 src/tools/msvc/Solution.pm                    |   18 +
 src/tools/msvc/clean.bat                      |    3 +
 src/tools/pgindent/typedefs.list              |    2 +
 28 files changed, 726 insertions(+), 2060 deletions(-)
  42.7% doc/src/sgml/
  47.7% src/backend/utils/activity/
   6.5% src/include/utils/

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/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..0862285548 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:
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..a82c908315 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 $@
 
@@ -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
 
 
 ##########################################################################
@@ -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..93587fb627 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 WaitEventLWLOCK
+# section in src/backend/utils/activity/waiteventnames.txt.
 
 # 0 is available; was formerly BufFreelistLock
 ShmemIndexLock						1
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..02fc1c6520
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,255 @@
+#!/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 %hashwc_comment;
+my %hashwc_note;
+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 WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_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/^.*- //;
+		$note = 0;
+		next;
+	}
+
+	# Get note (if any) based on the section
+	if (/^Section: Note(.*)/)
+	{
+		$note_name = $_;
+		$note_name =~ s/^.*- //;
+		$note = 1;
+		next;
+	}
+
+	if (/^.\*/)
+	{
+		# Those are comments we want to see in the header file
+		push(@{ $hashwc_comment{$section_name} }, $_);
+	}
+	elsif (!$note)
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
+	elsif ($note)
+	{
+		# Those are note per wait event class
+		push(@{ $hashwc_note{$note_name} }, $_);
+	}
+}
+
+# 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_//;
+	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
+	next if ($waitclass =~ /^WaitEventLWLOCK$/ || $waitclass =~ /^WaitEventLOCK$/);
+
+	my $last = $waitclass;
+	$last =~ s/^WaitEvent//;
+	# Exception here
+	if ($last =~ /^BufferPin/)
+	{
+		$last = "Buffer_Pin";
+	}
+	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)
+		{
+			foreach my $wcc (@{ $hashwc_comment{$waitclass} })
+			{
+				printf $h "%s\n", $wcc;
+			}
+			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                          /* WAITEVENTNAMES_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";
+
+	# Add note (if any) related to this wait class
+	if (exists $hashwc_note{$waitclass}) {
+		printf $s "   <note>\n";
+		printf $s "    <para>\n";
+		foreach my $wcn (@{ $hashwc_note{$waitclass} })
+		{
+			 printf $s "     %s\n", $wcn;
+		}
+		printf $s "    </para>\n";
+		printf $s "   </note>\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..2d9d30ae20 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_buffer_pin(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);
@@ -148,8 +150,12 @@ pgstat_get_wait_event(uint32 wait_event_info)
 			event_name = GetLockNameFromTagType(eventId);
 			break;
 		case PG_WAIT_BUFFER_PIN:
-			event_name = "BufferPin";
-			break;
+			{
+				WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info;
+
+				event_name = pgstat_get_wait_buffer_pin(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..a6d3ec127b
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,332 @@
+#
+# 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.
+#
+# If you need to add a Note for a wait event class, then add a Note section for
+# it.
+#
+# The lines that start with /* or " *" are treated as comments that will be
+# put in the wait_event_types.h file based on their associated sections.
+#
+# The purpose of WaitEventLWLOCK and WaitEventLOCK is only to generate the
+# .sgml file. It's important to keep the "WaitEvent" part in their names for
+# ordering purpose in the caller perl script.
+#
+# This file is used as input by src/backend/utils/activity/generate-waiteventnames.pl
+#
+
+Section: ClassName - WaitEventActivity
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventClient
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventIPC
+
+/* ----------
+ * 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.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventTimeout
+
+/* ----------
+ * Wait Events - Timeout
+ *
+ * Use this category when a process is waiting for a timeout to expire.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventIO
+
+/* ----------
+ * Wait Events - IO
+ *
+ * Use this category when a process is waiting for a IO.
+ * ----------
+ */
+
+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."
+
+Section: ClassName - WaitEventBufferPin
+
+WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buffer."
+
+Section: ClassName - WaitEventExtension
+
+WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
+
+Section: ClassName - WaitEventLWLOCK
+
+LWLOCK_DOCONLY	"ShmemIndex"	"Waiting to find or allocate space in shared memory."
+LWLOCK_DOCONLY	"OidGen"	"Waiting to allocate a new OID."
+LWLOCK_DOCONLY	"XidGen"	"Waiting to allocate a new transaction ID."
+LWLOCK_DOCONLY	"ProcArray"	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+LWLOCK_DOCONLY	"SInvalRead"	"Waiting to retrieve messages from the shared catalog invalidation queue."
+LWLOCK_DOCONLY	"SInvalWrite"	"Waiting to add a message to the shared catalog invalidation queue."
+LWLOCK_DOCONLY	"WALBufMapping"	"Waiting to replace a page in WAL buffers."
+LWLOCK_DOCONLY	"WALWrite"	"Waiting for WAL buffers to be written to disk."
+LWLOCK_DOCONLY	"ControlFile"	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+LWLOCK_DOCONLY	"XactSLRU"	"Waiting to access the transaction status SLRU cache."
+LWLOCK_DOCONLY	"SubtransSLRU"	"Waiting to access the sub-transaction SLRU cache."
+LWLOCK_DOCONLY	"MultiXactGen"	"Waiting to read or update shared multixact state."
+LWLOCK_DOCONLY	"MultiXactOffsetSLRU"	"Waiting to access the multixact offset SLRU cache."
+LWLOCK_DOCONLY	"MultiXactMemberSLRU"	"Waiting to access the multixact member SLRU cache."
+LWLOCK_DOCONLY	"RelCacheInit"	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+LWLOCK_DOCONLY	"CheckpointerComm"	"Waiting to manage fsync requests."
+LWLOCK_DOCONLY	"TwoPhaseState"	"Waiting to read or update the state of prepared transactions."
+LWLOCK_DOCONLY	"TablespaceCreate"	"Waiting to create or drop a tablespace."
+LWLOCK_DOCONLY	"BtreeVacuum"	"Waiting to read or update vacuum-related information for a B-tree index."
+LWLOCK_DOCONLY	"AddinShmemInit"	"Waiting to manage an extension's space allocation in shared memory."
+LWLOCK_DOCONLY	"Autovacuum"	"Waiting to read or update the current state of autovacuum workers."
+LWLOCK_DOCONLY	"AutovacuumSchedule"	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+LWLOCK_DOCONLY	"SyncScan"	"Waiting to select the starting location of a synchronized table scan."
+LWLOCK_DOCONLY	"RelationMapping"	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+LWLOCK_DOCONLY	"NotifySLRU"	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+LWLOCK_DOCONLY	"NotifyQueue"	"Waiting to read or update <command>NOTIFY</command> messages."
+LWLOCK_DOCONLY	"SerializableXactHash"	"Waiting to read or update information about serializable transactions."
+LWLOCK_DOCONLY	"SerializableFinishedList"	"Waiting to access the list of finished serializable transactions."
+LWLOCK_DOCONLY	"SerializablePredicateList"	"Waiting to access the list of predicate locks held by serializable transactions."
+LWLOCK_DOCONLY	"SerialSLRU"	"Waiting to access the serializable transaction conflict SLRU cache."
+LWLOCK_DOCONLY	"SyncRep"	"Waiting to read or update information about the state of synchronous replication."
+LWLOCK_DOCONLY	"BackgroundWorker"	"Waiting to read or update background worker state."
+LWLOCK_DOCONLY	"DynamicSharedMemoryControl"	"Waiting to read or update dynamic shared memory allocation information."
+LWLOCK_DOCONLY	"AutoFile"	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+LWLOCK_DOCONLY	"ReplicationSlotAllocation"	"Waiting to allocate or free a replication slot."
+LWLOCK_DOCONLY	"ReplicationSlotControl"	"Waiting to read or update replication slot state."
+LWLOCK_DOCONLY	"CommitTsSLRU"	"Waiting to access the commit timestamp SLRU cache."
+LWLOCK_DOCONLY	"CommitTs"	"Waiting to read or update the last value set for a transaction commit timestamp."
+LWLOCK_DOCONLY	"ReplicationOrigin"	"Waiting to create, drop or use a replication origin."
+LWLOCK_DOCONLY	"MultiXactTruncation"	"Waiting to read or truncate multixact information."
+LWLOCK_DOCONLY	"OldSnapshotTimeMap"	"Waiting to read or update old snapshot control information."
+LWLOCK_DOCONLY	"LogicalRepWorker"	"Waiting to read or update the state of logical replication workers."
+LWLOCK_DOCONLY	"XactTruncation"	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+LWLOCK_DOCONLY	"WrapLimitsVacuum"	"Waiting to update limits on transaction id and multixact consumption."
+LWLOCK_DOCONLY	"NotifyQueueTail"	"Waiting to update limit on <command>NOTIFY</command> message storage."
+
+Section: Note - WaitEventLWLOCK
+
+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.
+
+Section: ClassName - WaitEventLOCK
+
+LOCK_DOCONLY	"relation"	"Waiting to acquire a lock on a relation."
+LOCK_DOCONLY	"extend"	"Waiting to extend a relation."
+LOCK_DOCONLY	"frozenid"	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+LOCK_DOCONLY	"page"	"Waiting to acquire a lock on a page of a relation."
+LOCK_DOCONLY	"tuple"	"Waiting to acquire a lock on a tuple."
+LOCK_DOCONLY	"transactionid"	"Waiting for a transaction to finish."
+LOCK_DOCONLY	"virtualxid"	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+LOCK_DOCONLY	"spectoken"	"Waiting to acquire a speculative insertion lock."
+LOCK_DOCONLY	"object"	"Waiting to acquire a lock on a non-relation database object."
+LOCK_DOCONLY	"userlock"	"Waiting to acquire a user lock."
+LOCK_DOCONLY	"advisory"	"Waiting to acquire an advisory user lock."
+LOCK_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/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..160227972e 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -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/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/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.34.1

#14Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#13)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

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

Attachments:

v7-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/x-diff; charset=us-asciiDownload
From d6a5c46411b5506588c77ebe52310a324e99033f Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@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

#15Thomas Munro
thomas.munro@gmail.com
In reply to: Michael Paquier (#14)
Re: Autogenerate some wait events code and documentation

[patch]

This is not a review of the perl/make/meson glue/details, but I just
wanted to say thanks for working on this Bertrand & Michael, at a
quick glance that .txt file looks like it's going to be a lot more fun
to maintain!

#16Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#14)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/1/23 1:59 AM, Michael Paquier wrote:

On Fri, Apr 28, 2023 at 02:29:13PM +0200, Drouvot, Bertrand wrote:

On 4/27/23 8:13 AM, Michael Paquier wrote:

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 understand your concern.

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.

I'm not sure I like it. First, it does break the "Note" ordering as compare
to the current documentation. That's not a big deal though.

Secondly, what If we need to add some note(s) in the future for another wait class? Having all the notes
after all the tables are generated would sound weird to me.

We could discuss another approach for the "Note" part if there is a need to add one for an existing/new wait class
though.

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.

Oh I see. The advantage of the previous approach is to have them at both places (.txt and header).
But that said I understand your point about having the perl script minimalistic and simpler.

Please note that it creates 2 new "wait events":
WAIT_EVENT_EXTENSION and WAIT_EVENT_BUFFER_PIN.

Noted. Makes sense here.

Yup and that may help to add "custom" wait event for extensions too (need to think about it once
this refactoring is done).

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.

Good point, agree.

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.

Yes, I can look at it.

@@ -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').

Nice catch.

+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.

Agree.

@@ -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.

Agree, I'll look at this.

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.

Thanks for the v7! I did not look at the details but just replied to this thread.

I'll look at v7 when the v17 branch opens and propose the separate patch
mentioned above at that time too.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#17Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Thomas Munro (#15)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/2/23 4:50 AM, Thomas Munro wrote:

[patch]

This is not a review of the perl/make/meson glue/details, but I just
wanted to say thanks for working on this Bertrand & Michael, at a
quick glance that .txt file looks like it's going to be a lot more fun
to maintain!

Thanks Thomas! Yeah and probably less error prone too ;-)

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#18Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#16)
Re: Autogenerate some wait events code and documentation

On Thu, May 04, 2023 at 08:39:49AM +0200, Drouvot, Bertrand wrote:

On 5/1/23 1:59 AM, Michael Paquier wrote:
I'm not sure I like it. First, it does break the "Note" ordering as compare
to the current documentation. That's not a big deal though.

Secondly, what If we need to add some note(s) in the future for
another wait class? Having all the notes after all the tables are
generated would sound weird to me.

Appending these notes at the end of all the tables does not strike me
as a big dea, TBH. But, well, my sole opinion is not the final choice
either. For now, I am mostly tempted to keep the generation script as
minimalistic as possible.

We could discuss another approach for the "Note" part if there is a
need to add one for an existing/new wait class though.

Documenting what's expected from the wait event classes is critical in
the .txt file as that's what developers are going to look at when
adding a new wait event. Adding them in the header is less appealing
to me considering that is it now generated, and the docs provide a lot
of explanation as well.

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.

Yes, I can look at it.
[...]
Agree, I'll look at this.

Thanks!

I'll look at v7 when the v17 branch opens and propose the separate patch
mentioned above at that time too.

Thanks, again.
--
Michael

#19Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#18)
Re: Autogenerate some wait events code and documentation

On Sat, May 06, 2023 at 11:23:17AM +0900, Michael Paquier wrote:

I'll look at v7 when the v17 branch opens and propose the separate patch
mentioned above at that time too.

Thanks, again.

By the way, while browsing through the patch, I have noticed two
things:
- The ordering of the items for Lock and LWLock is incorrect.
- We are missing some of the LWLock entries, like CommitTsBuffer,
XactBuffer or WALInsert, as of all the entries in
BuiltinTrancheNames.

My apologies for not noticing that earlier. This exists in v6 as much
as v7.
--
Michael

#20Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#18)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/6/23 4:23 AM, Michael Paquier wrote:

On Thu, May 04, 2023 at 08:39:49AM +0200, Drouvot, Bertrand wrote:

On 5/1/23 1:59 AM, Michael Paquier wrote:
I'm not sure I like it. First, it does break the "Note" ordering as compare
to the current documentation. That's not a big deal though.

Secondly, what If we need to add some note(s) in the future for
another wait class? Having all the notes after all the tables are
generated would sound weird to me.

Appending these notes at the end of all the tables does not strike me
as a big dea, TBH. But, well, my sole opinion is not the final choice
either. For now, I am mostly tempted to keep the generation script as
minimalistic as possible.

I agree that's not a big deal and I'm not against having these notes at the end
of all the tables.

We could discuss another approach for the "Note" part if there is a
need to add one for an existing/new wait class though.

means, that was more a NIT comment from my side.

Documenting what's expected from the wait event classes is critical in
the .txt file as that's what developers are going to look at when
adding a new wait event. Adding them in the header is less appealing
to me considering that is it now generated, and the docs provide a lot
of explanation as well.

Your argument that the header is now generated makes me change my mind: I
know think that having the comments in the .txt file is enough.

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.

Yes, I can look at it.
[...]
Agree, I'll look at this.

Thanks!

Please find the dedicated patch proposal in [1]/messages/by-id/c6f35117-4b20-4c78-1df5-d3056010dcf5@gmail.com.

[1]: /messages/by-id/c6f35117-4b20-4c78-1df5-d3056010dcf5@gmail.com

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#21Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#19)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/6/23 4:37 AM, Michael Paquier wrote:

On Sat, May 06, 2023 at 11:23:17AM +0900, Michael Paquier wrote:

I'll look at v7 when the v17 branch opens and propose the separate patch
mentioned above at that time too.

Thanks, again.

By the way, while browsing through the patch, I have noticed two
things:
- The ordering of the items for Lock and LWLock is incorrect.

Oh right, fixed in V8 attached (moved the sort on the third column
instead of the second which has always the same content "WAIT_EVENT_DOCONLY"
for Lock and LWLock).

- We are missing some of the LWLock entries, like CommitTsBuffer,
XactBuffer or WALInsert, as of all the entries in
BuiltinTrancheNames.

Yeah, my bad. Fixed in V8 attached.

My apologies for not noticing that earlier. This exists in v6 as much
as v7.

No problem at all and thanks for the call out!

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v8-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v8-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From b3d3c1d4c38f83765d9cd6faba1eaf0e221187b4 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 1 May 2023 08:51:05 +0900
Subject: [PATCH v8] 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
---
 contrib/dblink/dblink.c                       |    4 +-
 contrib/pg_prewarm/autoprewarm.c              |    4 +-
 contrib/postgres_fdw/connection.c             |    6 +-
 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 +----------------
 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 |  371 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  216 +--
 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 +-
 src/tools/msvc/Solution.pm                    |   18 +
 src/tools/msvc/clean.bat                      |    3 +
 src/tools/pgindent/typedefs.list              |    2 +
 29 files changed, 739 insertions(+), 2063 deletions(-)
  41.6% doc/src/sgml/
  48.9% src/backend/utils/activity/
   6.5% src/include/utils/

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/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/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..c61b3a65d8
--- /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 third column
+my @lines_sorted =
+  sort { (split(/\t/, $a))[2] cmp(split(/\t/, $b))[2] } @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..09a58c78bc
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,371 @@
+#
+# 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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+
+#
+# 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/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/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/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.34.1

#22Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#21)
Re: Autogenerate some wait events code and documentation

On Mon, May 15, 2023 at 06:45:23PM +0200, Drouvot, Bertrand wrote:

On 5/6/23 4:37 AM, Michael Paquier wrote:

On Sat, May 06, 2023 at 11:23:17AM +0900, Michael Paquier wrote:

I'll look at v7 when the v17 branch opens and propose the separate patch
mentioned above at that time too.

Thanks, again.

By the way, while browsing through the patch, I have noticed two
things:
- The ordering of the items for Lock and LWLock is incorrect.

Oh right, fixed in V8 attached (moved the sort on the third column
instead of the second which has always the same content "WAIT_EVENT_DOCONLY"
for Lock and LWLock).

Ah, I didn't notice that. Makes sense.

- We are missing some of the LWLock entries, like CommitTsBuffer,
XactBuffer or WALInsert, as of all the entries in
BuiltinTrancheNames.

Yeah, my bad. Fixed in V8 attached.

BufFileTruncate and BufFileWrite have an incorrect order in HEAD's
monitoring.sgml (will fix in a minute for 16~). So your patch fixes
that.

PgStatsDSA and PgStatsData are reversed in your patch compared to
HEAD, actually, based on the way perl sees fit to do its ordering by
giving priority to upper-case characters.  Same for RelCacheInit and
RelationMapping, or even SInvalRead/SInvalWrite being now before the
"Serial" family.  Worse, the tables LWLock and Lock are in an
incorrect order as well with the patch.  We'd better be a bit more
verbose with the sort step, I think..  perl does not handle well
sorting with collations from what I recall, but we could use uc() with
a block sort to force the operation to be case-insensitive, like "sort
{uc($a) cmp uc($b)}".  That needs to be applied here, I guess: 
+# Sort the lines based on the third column
+my @lines_sorted =
+  sort { (split(/\t/, $a))[2] cmp(split(/\t/, $b))[2] } @lines;

And it looks like you'd need to apply uc() on each [2] element. I
would add a comment about this detail, as well.

No entries are missing, after comparing what's generated by the patch
with the contents of HEAD.

Small nit-ish question: waiteventnames.sgml or wait_event_types.sgml?
Same for generate-waiteventtypes.pl?

My apologies for not noticing that earlier. This exists in v6 as much
as v7.

No problem at all and thanks for the call out!

FWIW, I would have posted two patches, one with the refactoring of
done in [1]/messages/by-id/c6f35117-4b20-4c78-1df5-d3056010dcf5@gmail.com -- Michael, and a second that switches to the automation, to make
clear the preparatory step.

[1]: /messages/by-id/c6f35117-4b20-4c78-1df5-d3056010dcf5@gmail.com -- Michael
--
Michael

#23Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#22)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/16/23 9:48 AM, Michael Paquier wrote:

On Mon, May 15, 2023 at 06:45:23PM +0200, Drouvot, Bertrand wrote:

On 5/6/23 4:37 AM, Michael Paquier wrote:

On Sat, May 06, 2023 at 11:23:17AM +0900, Michael Paquier wrote:

BufFileTruncate and BufFileWrite have an incorrect order in HEAD's
monitoring.sgml (will fix in a minute for 16~). So your patch fixes
that.

Oh nice catch!

PgStatsDSA and PgStatsData are reversed in your patch compared to
HEAD, actually, based on the way perl sees fit to do its ordering by
giving priority to upper-case characters.  Same for RelCacheInit and
RelationMapping, or even SInvalRead/SInvalWrite being now before the
"Serial" family.  Worse, the tables LWLock and Lock are in an
incorrect order as well with the patch.  We'd better be a bit more
verbose with the sort step, I think..  perl does not handle well
sorting with collations from what I recall, but we could use uc() with
a block sort to force the operation to be case-insensitive, like "sort
{uc($a) cmp uc($b)}".  That needs to be applied here, I guess:
+# Sort the lines based on the third column
+my @lines_sorted =
+  sort { (split(/\t/, $a))[2] cmp(split(/\t/, $b))[2] } @lines;

Oh right, nice catch.

And it looks like you'd need to apply uc() on each [2] element. I
would add a comment about this detail, as well.

Did it that way in V9 attached and the sorting does look like what we expect now.

No entries are missing, after comparing what's generated by the patch
with the contents of HEAD.

Small nit-ish question: waiteventnames.sgml or wait_event_types.sgml?
Same for generate-waiteventtypes.pl?

Agree, it's more consistent. Done that way in V9.

FWIW, I would have posted two patches, one with the refactoring of
done in [1], and a second that switches to the automation, to make
clear the preparatory step.

[1]: /messages/by-id/c6f35117-4b20-4c78-1df5-d3056010dcf5@gmail.com
--

Agree, V9 does now apply on top of v2-0001-Introducing-WAIT_EVENT_EXTENSION-and-WAIT_EVENT_B.patch
(just shared in [1]/messages/by-id/a82c2660-64b4-1c59-3eef-bf82b86fb99a@gmail.com).

[1]: /messages/by-id/a82c2660-64b4-1c59-3eef-bf82b86fb99a@gmail.com

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v9-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchtext/plain; charset=UTF-8; name=v9-0001-Generating-wait_event_types.h-pgstat_wait_event.c.patchDownload
From e6f7211f959c829e3dee30d7b8daca1ca2719e41 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 1 May 2023 08:51:05 +0900
Subject: [PATCH v9] Generating wait_event_types.h, pgstat_wait_event.c and
 wait_event_types.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
---
 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 +----------------
 src/backend/Makefile                          |   13 +-
 src/backend/storage/lmgr/lwlocknames.txt      |    4 +-
 src/backend/utils/activity/.gitignore         |    3 +
 src/backend/utils/activity/Makefile           |   10 +
 .../utils/activity/generate-waiteventtypes.pl |  214 +++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  611 +-------
 src/backend/utils/activity/waiteventnames.txt |  371 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  232 +--
 src/tools/msvc/Solution.pm                    |   18 +
 src/tools/msvc/clean.bat                      |    3 +
 20 files changed, 709 insertions(+), 2106 deletions(-)
  41.8% doc/src/sgml/
  49.4% src/backend/utils/activity/
   6.7% src/include/utils/

diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..1ccb72227e 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/wait_event_types.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..e19f198201 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 wait_event_types.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) > $@
 
+wait_event_types.sgml: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt $(top_srcdir)/src/backend/utils/activity/generate-waiteventtypes.pl
+	$(PERL) $(top_srcdir)/src/backend/utils/activity/generate-waiteventtypes.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..0d19e9141f 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 wait_event_types    SYSTEM "wait_event_types.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..826d6c78b6 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('wait_event_types.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/waiteventnames.txt'),
+  output: 'wait_event_types.sgml',
+  command: [perl, files('../../../src/backend/utils/activity/generate-waiteventtypes.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 9842f82091..609d486bb1 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>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</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>
+  &wait_event_types;
 
    <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/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..8353e7b354 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-waiteventtypes.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/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..a62378405e
--- /dev/null
+++ b/src/backend/utils/activity/.gitignore
@@ -0,0 +1,3 @@
+/pgstat_wait_event.c
+/wait_event_types.h
+/wait_event_types.sgml
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..5006b818d0 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-waiteventtypes.pl
+	$(PERL) $(srcdir)/generate-waiteventtypes.pl $<
+
+maintainer-clean: clean
+	rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-waiteventtypes.pl b/src/backend/utils/activity/generate-waiteventtypes.pl
new file mode 100644
index 0000000000..7805790101
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventtypes.pl
@@ -0,0 +1,214 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - wait_event_types.h
+# - pgstat_wait_event.c
+# - wait_event_types.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-waiteventtypes.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-waiteventtypes.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 third column.
+# uc() is being used to force the comparison to be case-insensitive.
+my @lines_sorted =
+  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @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/wait_event_types.sgml") || die "rename: $ctmp: $!";
+
+close $waiteventnames;
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index 518ee3f798..d7050829dc 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-waiteventtypes.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 8572cf169e..4aad11c111 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -206,613 +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_bufferpin() -
- *
- * Convert WaitEventBufferPin to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_bufferpin(WaitEventBufferPin w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_BUFFER_PIN:
-			event_name = "BufferPin";
-			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_extension() -
- *
- * Convert WaitEventExtension to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_extension(WaitEventExtension w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_EXTENSION:
-			event_name = "Extension";
-			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..9b29957e90
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,371 @@
+#
+# 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/wait_event_types.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-waiteventtypes.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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+
+#
+# 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/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..1b080bd436 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-waiteventtypes.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 dc01d4e84d..4517425f84 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,236 +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 - BUFFERPIN
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
-} WaitEventBufferPin;
-
-/* ----------
- * 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 - EXTENSION
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION
-} WaitEventExtension;
-
-/* ----------
- * 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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..8db0a87df4 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-waiteventtypes.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
-- 
2.34.1

#24Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#23)
Re: Autogenerate some wait events code and documentation

On Wed, May 17, 2023 at 08:31:53AM +0200, Drouvot, Bertrand wrote:

Did it that way in V9 attached and the sorting does look like what
we expect now.

Yes, the order of the items in the individual tables is fine, but this
is still a bit incorrect for the classes? Note that the tables for
the LWLock and Lock are still in reverse order :)

+foreach $waitclass (sort keys %hashwe)

Meaning that you may want to add an extra case-insensitive rule for
the sorting on this line for the SGML docs (also the C part, I guess,
but we care less).

Agree, V9 does now apply on top of v2-0001-Introducing-WAIT_EVENT_EXTENSION-and-WAIT_EVENT_B.patch
(just shared in [1]).

If you don't send both patches in the same message the CF bot is going
to complain as v9-0001 is not able to apply independently of the other
patch v2-0001 on the other thread (you could do a git apply -2 -v2,
for example).
--
Michael

#25Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#24)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 5/17/23 10:14 AM, Michael Paquier wrote:

On Wed, May 17, 2023 at 08:31:53AM +0200, Drouvot, Bertrand wrote:

Did it that way in V9 attached and the sorting does look like what
we expect now.

Yes, the order of the items in the individual tables is fine, but this
is still a bit incorrect for the classes? Note that the tables for
the LWLock and Lock are still in reverse order :)

Sorry did not pay enough attention to it ;-(

+foreach $waitclass (sort keys %hashwe)

Meaning that you may want to add an extra case-insensitive rule for
the sorting on this line for the SGML docs (also the C part, I guess,
but we care less).

Yeap, done in V10 for sgml and the C part too (for consistency).

Agree, V9 does now apply on top of v2-0001-Introducing-WAIT_EVENT_EXTENSION-and-WAIT_EVENT_B.patch
(just shared in [1]).

If you don't send both patches in the same message the CF bot is going
to complain as v9-0001 is not able to apply independently of the other
patch v2-0001 on the other thread

Yeah, good point, attaching both here to keep the CF bot happy.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v10-0002-Generating-wait_event_types.h-pgstat_wait_event..patchtext/plain; charset=UTF-8; name=v10-0002-Generating-wait_event_types.h-pgstat_wait_event..patchDownload
From fd43b20f92f52047a04d2bed8d68b4021c276081 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 1 May 2023 08:51:05 +0900
Subject: [PATCH v10 2/2] Generating wait_event_types.h, pgstat_wait_event.c
 and wait_event_types.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
---
 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 +----------------
 src/backend/Makefile                          |   13 +-
 src/backend/storage/lmgr/lwlocknames.txt      |    4 +-
 src/backend/utils/activity/.gitignore         |    3 +
 src/backend/utils/activity/Makefile           |   10 +
 .../utils/activity/generate-waiteventtypes.pl |  216 +++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  611 +-------
 src/backend/utils/activity/waiteventnames.txt |  371 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  232 +--
 src/tools/msvc/Solution.pm                    |   18 +
 src/tools/msvc/clean.bat                      |    3 +
 20 files changed, 711 insertions(+), 2106 deletions(-)
  41.7% doc/src/sgml/
  49.4% src/backend/utils/activity/
   6.7% src/include/utils/

diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..1ccb72227e 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/wait_event_types.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..e19f198201 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 wait_event_types.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) > $@
 
+wait_event_types.sgml: $(top_srcdir)/src/backend/utils/activity/waiteventnames.txt $(top_srcdir)/src/backend/utils/activity/generate-waiteventtypes.pl
+	$(PERL) $(top_srcdir)/src/backend/utils/activity/generate-waiteventtypes.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..0d19e9141f 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 wait_event_types    SYSTEM "wait_event_types.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..826d6c78b6 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('wait_event_types.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/waiteventnames.txt'),
+  output: 'wait_event_types.sgml',
+  command: [perl, files('../../../src/backend/utils/activity/generate-waiteventtypes.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 9842f82091..609d486bb1 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>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</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>
+  &wait_event_types;
 
    <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/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..8353e7b354 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-waiteventtypes.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/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..a62378405e
--- /dev/null
+++ b/src/backend/utils/activity/.gitignore
@@ -0,0 +1,3 @@
+/pgstat_wait_event.c
+/wait_event_types.h
+/wait_event_types.sgml
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..5006b818d0 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-waiteventtypes.pl
+	$(PERL) $(srcdir)/generate-waiteventtypes.pl $<
+
+maintainer-clean: clean
+	rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-waiteventtypes.pl b/src/backend/utils/activity/generate-waiteventtypes.pl
new file mode 100644
index 0000000000..1ff0e788fc
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventtypes.pl
@@ -0,0 +1,216 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - wait_event_types.h
+# - pgstat_wait_event.c
+# - wait_event_types.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-waiteventtypes.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-waiteventtypes.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 third column.
+# uc() is being used to force the comparison to be case-insensitive.
+my @lines_sorted =
+  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @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.
+# uc() is being used to force the comparison to be case-insensitive.
+foreach $waitclass (sort {uc($a) cmp uc($b)} 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.
+# uc() is being used to force the comparison to be case-insensitive.
+foreach $waitclass (sort {uc($a) cmp uc($b)} 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/wait_event_types.sgml") || die "rename: $ctmp: $!";
+
+close $waiteventnames;
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index 518ee3f798..d7050829dc 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-waiteventtypes.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 8572cf169e..4aad11c111 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -206,613 +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_bufferpin() -
- *
- * Convert WaitEventBufferPin to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_bufferpin(WaitEventBufferPin w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_BUFFER_PIN:
-			event_name = "BufferPin";
-			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_extension() -
- *
- * Convert WaitEventExtension to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_extension(WaitEventExtension w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_EXTENSION:
-			event_name = "Extension";
-			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..9b29957e90
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,371 @@
+#
+# 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/wait_event_types.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-waiteventtypes.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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+
+#
+# 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/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..1b080bd436 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-waiteventtypes.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 dc01d4e84d..4517425f84 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,236 +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 - BUFFERPIN
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
-} WaitEventBufferPin;
-
-/* ----------
- * 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 - EXTENSION
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION
-} WaitEventExtension;
-
-/* ----------
- * 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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..8db0a87df4 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-waiteventtypes.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
-- 
2.34.1

v10-0001-Introducing-WAIT_EVENT_EXTENSION-and-WAIT_EVENT_.patchtext/plain; charset=UTF-8; name=v10-0001-Introducing-WAIT_EVENT_EXTENSION-and-WAIT_EVENT_.patchDownload
From 8c4b344f18609b15fd470c3cff1b5360a81686d7 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Sat, 13 May 2023 07:59:08 +0000
Subject: [PATCH v10 1/2] Introducing WAIT_EVENT_EXTENSION and
 WAIT_EVENT_BUFFER_PIN

---
 contrib/dblink/dblink.c                  |  4 +-
 contrib/pg_prewarm/autoprewarm.c         |  4 +-
 contrib/postgres_fdw/connection.c        |  6 +--
 src/backend/storage/buffer/bufmgr.c      |  2 +-
 src/backend/storage/ipc/standby.c        |  2 +-
 src/backend/utils/activity/wait_event.c  | 66 +++++++++++++++++++++---
 src/include/utils/wait_event.h           | 20 ++++++-
 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 +-
 src/tools/pgindent/typedefs.list         |  2 +
 11 files changed, 93 insertions(+), 19 deletions(-)
   8.8% contrib/dblink/
   4.6% contrib/pg_prewarm/
   9.3% contrib/postgres_fdw/
   3.4% src/backend/storage/buffer/
   3.2% src/backend/storage/ipc/
  47.9% src/backend/utils/activity/
  14.2% src/include/utils/
   4.5% src/test/modules/test_shm_mq/
   3.7% src/

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/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/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 7940d64639..8572cf169e 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;
@@ -254,6 +264,28 @@ pgstat_get_wait_activity(WaitEventActivity w)
 	return event_name;
 }
 
+/* ----------
+ * pgstat_get_wait_bufferpin() -
+ *
+ * Convert WaitEventBufferPin to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_bufferpin(WaitEventBufferPin w)
+{
+	const char *event_name = "unknown wait event";
+
+	switch (w)
+	{
+		case WAIT_EVENT_BUFFER_PIN:
+			event_name = "BufferPin";
+			break;
+			/* no default case, so that compiler will warn */
+	}
+
+	return event_name;
+}
+
 /* ----------
  * pgstat_get_wait_client() -
  *
@@ -297,6 +329,28 @@ pgstat_get_wait_client(WaitEventClient w)
 	return event_name;
 }
 
+/* ----------
+ * pgstat_get_wait_extension() -
+ *
+ * Convert WaitEventExtension to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_extension(WaitEventExtension w)
+{
+	const char *event_name = "unknown wait event";
+
+	switch (w)
+	{
+		case WAIT_EVENT_EXTENSION:
+			event_name = "Extension";
+			break;
+			/* no default case, so that compiler will warn */
+	}
+
+	return event_name;
+}
+
 /* ----------
  * pgstat_get_wait_ipc() -
  *
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..dc01d4e84d 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
@@ -50,6 +50,15 @@ typedef enum
 	WAIT_EVENT_WAL_WRITER_MAIN
 } WaitEventActivity;
 
+/* ----------
+ * Wait Events - BUFFERPIN
+ * ----------
+ */
+typedef enum
+{
+	WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
+} WaitEventBufferPin;
+
 /* ----------
  * Wait Events - Client
  *
@@ -70,6 +79,15 @@ typedef enum
 	WAIT_EVENT_WAL_SENDER_WRITE_DATA,
 } WaitEventClient;
 
+/* ----------
+ * Wait Events - EXTENSION
+ * ----------
+ */
+typedef enum
+{
+	WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION
+} WaitEventExtension;
+
 /* ----------
  * Wait Events - IPC
  *
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/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 06da7cd428..dce1bcbfdf 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2972,7 +2972,9 @@ WSANETWORKEVENTS
 WSAPROTOCOL_INFO
 WaitEvent
 WaitEventActivity
+WaitEventBufferPin
 WaitEventClient
+WaitEventExtension
 WaitEventIO
 WaitEventIPC
 WaitEventSet
-- 
2.34.1

#26Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#25)
Re: Autogenerate some wait events code and documentation

On Wed, May 17, 2023 at 11:10:21AM +0200, Drouvot, Bertrand wrote:

Sorry did not pay enough attention to it ;-(

No problem.

Yeap, done in V10 for sgml and the C part too (for consistency).

The order looks fine seen from here, thanks!
--
Michael

#27Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#26)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

On Thu, May 18, 2023 at 01:36:30PM +0900, Michael Paquier wrote:

The order looks fine seen from here, thanks!

Now that v17 is open for business, I have looked again at this patch.

perlcritic is formulating three complaints:
./src/backend/utils/activity/generate-waiteventtypes.pl: Loop iterator
is not lexical at line 99, column 1. See page 108 of PBP.
([Variables::RequireLexicalLoopIterators] Severity: 5)
./src/backend/utils/activity/generate-waiteventtypes.pl: Loop iterator
is not lexical at line 126, column 1. See page 108 of PBP.
([Variables::RequireLexicalLoopIterators] Severity: 5)
./src/backend/utils/activity/generate-waiteventtypes.pl: Loop iterator
is not lexical at line 181, column 1. See page 108 of PBP.
([Variables::RequireLexicalLoopIterators] Severity: 5)

These are caused by three foreach loops, where perl wants to use a
local declaration for the iterators.

The indentation was a bit off, as well, perltidy v20230309 has
reported a few diffs. Not a big deal.

src/common/meson.build includes the following comment:
# For the server build of pgcommon, depend on lwlocknames_h, because at least
# cryptohash_openssl.c, hmac_openssl.c depend on it. That's arguably a
# layering violation, but ...

The thing is that controldata_utils.c has a dependency to wait events
so we should add wait_event_types_h to 'sources'.

The names chosen, as of wait_event_types.h, pgstat_wait_event.c,
waiteventnames.txt and generate-wait_event_types.pl are inconsistent,
comparing them for instance with the lwlock parts. I have renamed
these a bit, with more underscores.

Building the documentation in a meson/ninja build can be done with the
following command run from the root of the build directory:
ninja alldocs

However this command fails with v10. The step that fails is:
[6/14] Generating doc/src/sgml/postgres-full.xml with a custom command

It seems to me that the correct thing to do is to add --outdir
@OUTDIR@ to the command? However, I do see a few problems even after
that:
- The C and H files are still generated in doc/src/sgml/, which is
useless.
- The SGML file wait_event_types.sgml in doc/src/sgml/ seems to be
empty, still to my surprise the HTML part was created correctly.
- The SGML file is not needed for the C code.

I think that we should add some options to the perl script to be more
selective with the files generated. How about having two options
called --docs and --code to select one or the other, then limit what
gets generated in each path? I guess that it would be cleaner if we
error in the case where both options are defined, and just use some
gotos to redirect to each foreach loop to limit extra indentations in
the script. This would avoid the need to remove the C and H files
from the docs, additionally, which is what the Makefile in doc/ does.

I have fixed all the issues I've found in v11 attached, except for the
last one (I have added the OUTDIR trick for reference, but that's
incorrect and incomplete). Could you look at this part?
--
Michael

Attachments:

v11-0001-Generate-automatically-wait-event-related-code-a.patchtext/x-diff; charset=us-asciiDownload
From d646b6ba4ec743b5294a51875813d614276fd805 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 3 Jul 2023 15:51:40 +0900
Subject: [PATCH v11] Generate automatically wait-event related code and docs

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                |  232 +--
 src/backend/Makefile                          |   13 +-
 src/backend/storage/lmgr/lwlocknames.txt      |    4 +-
 src/backend/utils/activity/.gitignore         |    3 +
 src/backend/utils/activity/Makefile           |   10 +
 .../activity/generate-wait_event_types.pl     |  219 +++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  611 +-------
 .../utils/activity/wait_event_names.txt       |  371 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/common/meson.build                        |    7 +-
 src/test/ssl/t/002_scram.pl                   |    3 +-
 doc/src/sgml/.gitignore                       |    1 +
 doc/src/sgml/Makefile                         |    5 +-
 doc/src/sgml/filelist.sgml                    |    1 +
 doc/src/sgml/meson.build                      |   12 +
 doc/src/sgml/monitoring.sgml                  | 1271 +----------------
 src/tools/msvc/Solution.pm                    |   19 +
 src/tools/msvc/clean.bat                      |    3 +
 22 files changed, 722 insertions(+), 2111 deletions(-)
 create mode 100644 src/backend/utils/activity/.gitignore
 create mode 100644 src/backend/utils/activity/generate-wait_event_types.pl
 create mode 100644 src/backend/utils/activity/wait_event_names.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 c212c4091f..bbbc54fa07 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
 
+wait_event_names = custom_target('wait_event_names',
+  input: files('../../backend/utils/activity/wait_event_names.txt'),
+  output: ['wait_event_types.h'],
+  command: [
+    perl, files('../../backend/utils/activity/generate-wait_event_types.pl'),
+    '-o', '@OUTDIR@',
+    '@INPUT@'
+  ],
+  build_by_default: true,
+  install: true,
+  install_dir: [dir_include_server / 'utils'],
+)
+
+wait_event_types_h = wait_event_names[0]
+generated_backend_headers += wait_event_types_h
+
 errcodes = custom_target('errcodes',
   input: files('../../backend/utils/errcodes.txt'),
   output: ['errcodes.h'],
@@ -58,3 +74,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 dc01d4e84d..4517425f84 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,236 +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 - BUFFERPIN
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
-} WaitEventBufferPin;
-
-/* ----------
- * 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 - EXTENSION
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION
-} WaitEventExtension;
-
-/* ----------
- * 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 3c42003175..1c929383c4 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -133,6 +133,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-wait_event_types.pl utils/activity/wait_event_names.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
@@ -160,13 +163,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 $@
 
@@ -182,6 +190,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
 
@@ -301,6 +310,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/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt
index 6c7cf6c295..b34b6afecd 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/wait_event_names.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..a62378405e
--- /dev/null
+++ b/src/backend/utils/activity/.gitignore
@@ -0,0 +1,3 @@
+/pgstat_wait_event.c
+/wait_event_types.h
+/wait_event_types.sgml
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..5ec53edce9 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/wait_event_names.txt generate-wait_event_types.pl
+	$(PERL) $(srcdir)/generate-wait_event_types.pl $<
+
+maintainer-clean: clean
+	rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
new file mode 100644
index 0000000000..3991a724bb
--- /dev/null
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -0,0 +1,219 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from wait_event_names.txt:
+# - wait_event_types.h
+# - pgstat_wait_event.c
+# - wait_event_types.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-wait_event_types.pl
+#
+#----------------------------------------------------------------------
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+my $output_path = '.';
+
+my $continue = "\n";
+my %hashwe;
+
+GetOptions('outdir:s' => \$output_path);
+
+open my $wait_event_names, '<', $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/wait_event_names.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-wait_event_types.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 $section_name;
+my $note;
+my $note_name;
+
+# Remove comments and empty lines and add waitclassname based on the section
+while (<$wait_event_names>)
+{
+	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 third column.
+# uc() is being used to force the comparison to be case-insensitive.
+my @lines_sorted =
+  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+
+# Read the sorted lines and populate the hash table
+foreach my $line (@lines_sorted)
+{
+	die "unable to parse wait_event_names.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.
+# uc() is being used to force the comparison to be case-insensitive.
+foreach my $waitclass (sort { uc($a) cmp uc($b) } 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.
+# uc() is being used to force the comparison to be case-insensitive.
+foreach my $waitclass (sort { uc($a) cmp uc($b) } 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/wait_event_types.sgml")
+  || die "rename: $ctmp: $!";
+
+close $wait_event_names;
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index 518ee3f798..070c4be66e 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
 
+wait_event_names = custom_target('wait_event_names',
+  input: files('./wait_event_names.txt'),
+  output: ['pgstat_wait_event.c'],
+  command: [
+    perl, files('./generate-wait_event_types.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('wait_event_names',
+  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 8572cf169e..4aad11c111 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -206,613 +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_bufferpin() -
- *
- * Convert WaitEventBufferPin to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_bufferpin(WaitEventBufferPin w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_BUFFER_PIN:
-			event_name = "BufferPin";
-			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_extension() -
- *
- * Convert WaitEventExtension to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_extension(WaitEventExtension w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_EXTENSION:
-			event_name = "Extension";
-			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/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
new file mode 100644
index 0000000000..2e744ea8c7
--- /dev/null
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -0,0 +1,371 @@
+#
+# wait_event_names.txt
+#      PostgreSQL wait events
+#
+# Copyright (c) 2023, PostgreSQL Global Development Group
+#
+# This list serves as the basis for generating source and documentation 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/wait_event_types.sgml
+#      SGML tables of wait events for inclusion in the documentation.
+#
+# This file defines 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-wait_event_types.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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+
+#
+# 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..d05e20b2c8 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/wait_event_names.txt.
  */
 const char *const LockTagTypeNames[] = {
 	"relation",
diff --git a/src/common/meson.build b/src/common/meson.build
index 9efc80ac02..53942a9a61 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -117,13 +117,14 @@ common_sources_frontend_static += files(
 # XXX: in most environments we could probably link_whole pgcommon_shlib
 # against pgcommon_static, instead of compiling twice.
 #
-# For the server build of pgcommon, depend on lwlocknames_h, because at least
-# cryptohash_openssl.c, hmac_openssl.c depend on it. That's arguably a
+# For the server build of pgcommon, depend on lwlocknames_h and because at
+# least cryptohash_openssl.c, hmac_openssl.c depend on it.
+# controldata_utils.c depends on wait_event_types_h. That's arguably a
 # layering violation, but ...
 pgcommon = {}
 pgcommon_variants = {
   '_srv': internal_lib_args + {
-    'sources': common_sources + [lwlocknames_h],
+    'sources': common_sources + [lwlocknames_h] + [wait_event_types_h],
     'dependencies': [backend_common_code],
   },
   '': default_lib_args + {
diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
index 3a798e1a56..27abd02abf 100644
--- a/src/test/ssl/t/002_scram.pl
+++ b/src/test/ssl/t/002_scram.pl
@@ -87,8 +87,7 @@ $node->connect_fails(
 	expected_stderr => qr/invalid channel_binding value: "invalid_value"/);
 $node->connect_ok("$common_connstr user=ssltestuser channel_binding=disable",
 	"SCRAM with SSL and channel_binding=disable");
-$node->connect_ok(
-	"$common_connstr user=ssltestuser channel_binding=require",
+$node->connect_ok("$common_connstr user=ssltestuser channel_binding=require",
 	"SCRAM with SSL and channel_binding=require");
 
 # Now test when the user has an MD5-encrypted password; should fail
diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..1ccb72227e 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/wait_event_types.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..c4aa6a474f 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 wait_event_types.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) > $@
 
+wait_event_types.sgml: $(top_srcdir)/src/backend/utils/activity/wait_event_names.txt $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.pl
+	$(PERL) $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.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 5465f9a46d..63b0fc2a46 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 wait_event_types    SYSTEM "wait_event_types.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..c2cc97d408 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -46,6 +46,18 @@ doc_generated += custom_target('errcodes-table.sgml',
   capture: true,
 )
 
+doc_generated += custom_target('wait_event_types.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/wait_event_names.txt'),
+  output: 'wait_event_types.sgml',
+  command: [perl,
+    files('../../../src/backend/utils/activity/generate-wait_event_types.pl'),
+    '--outdir', '@OUTDIR@', '@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 5cfdc70c03..506aeaa879 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>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</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>
+  &wait_event_types;
 
    <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/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index e6d8f9fedc..f6570db479 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -585,6 +585,25 @@ sub GenerateFiles
 			'src/include/storage/lwlocknames.h');
 	}
 
+	if (IsNewer(
+			'src/include/utils/wait_event_types.h',
+			'src/backend/utils/activity/wait_event_names.txt'))
+	{
+		print "Generating pgstat_wait_event.c and wait_event_types.h...\n";
+		my $activ = 'src/backend/utils/activity';
+		system(
+			"perl $activ/generate-wait_event_types.pl --outdir $activ $activ/wait_event_names.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 cf35764604..7cb23ea894 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -46,6 +46,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
@@ -53,6 +54,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
-- 
2.40.1

#28Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#27)
Re: Autogenerate some wait events code and documentation

On Mon, Jul 03, 2023 at 03:57:42PM +0900, Michael Paquier wrote:

I think that we should add some options to the perl script to be more
selective with the files generated. How about having two options
called --docs and --code to select one or the other, then limit what
gets generated in each path? I guess that it would be cleaner if we
error in the case where both options are defined, and just use some
gotos to redirect to each foreach loop to limit extra indentations in
the script. This would avoid the need to remove the C and H files
from the docs, additionally, which is what the Makefile in doc/ does.

I have fixed all the issues I've found in v11 attached, except for the
last one (I have added the OUTDIR trick for reference, but that's
incorrect and incomplete). Could you look at this part?

Ah. It took me a few extra minutes, but I think that we should set
"capture" to "false", no? It looks like meson is getting confused,
expecting something in stdout but the new script generates a few
files, and does not output anything. That's different from the other
doc-related perl scripts.
--
Michael

#29Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#28)
Re: Autogenerate some wait events code and documentation

Hi,

On 7/3/23 9:11 AM, Michael Paquier wrote:

On Mon, Jul 03, 2023 at 03:57:42PM +0900, Michael Paquier wrote:

Thanks for looking at it and having fixed the issues that were present in
v10.

I think that we should add some options to the perl script to be more
selective with the files generated. How about having two options
called --docs and --code to select one or the other, then limit what
gets generated in each path? I guess that it would be cleaner if we
error in the case where both options are defined, and just use some
gotos to redirect to each foreach loop to limit extra indentations in
the script. This would avoid the need to remove the C and H files
from the docs, additionally, which is what the Makefile in doc/ does.

I have fixed all the issues I've found in v11 attached, except for the
last one (I have added the OUTDIR trick for reference, but that's
incorrect and incomplete). Could you look at this part?

Ah. It took me a few extra minutes, but I think that we should set
"capture" to "false", no? It looks like meson is getting confused,
expecting something in stdout but the new script generates a few
files, and does not output anything. That's different from the other
doc-related perl scripts.
--

Yeah, with "capture" set to "false" then ninja alldocs does not error out
and wait_event_types.sgml gets generated.

I'll look at the extra options --code and --docs.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#30Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Drouvot, Bertrand (#29)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 7/4/23 9:34 AM, Drouvot, Bertrand wrote:

Hi,

On 7/3/23 9:11 AM, Michael Paquier wrote:

On Mon, Jul 03, 2023 at 03:57:42PM +0900, Michael Paquier wrote:

Thanks for looking at it and having fixed the issues that were present in
v10.

I think that we should add some options to the perl script to be more
selective with the files generated.  How about having two options
called --docs and --code to select one or the other, then limit what
gets generated in each path?  I guess that it would be cleaner if we
error in the case where both options are defined, and just use some
gotos to redirect to each foreach loop to limit extra indentations in
the script.  This would avoid the need to remove the C and H files
from the docs, additionally, which is what the Makefile in doc/ does.

I have fixed all the issues I've found in v11 attached, except for the
last one (I have added the OUTDIR trick for reference, but that's
incorrect and incomplete).  Could you look at this part?

Ah.  It took me a few extra minutes, but I think that we should set
"capture" to "false", no?  It looks like meson is getting confused,
expecting something in stdout but the new script generates a few
files, and does not output anything.  That's different from the other
doc-related perl scripts.
--

Yeah, with "capture" set to "false" then ninja alldocs does not error out
and wait_event_types.sgml gets generated.

I'll look at the extra options --code and --docs.

Please find attached v12 that:

- sets "capture" to "false"
- adds the --code and --docs extra options to generate-wait_event_types.pl
- makes sure at least one of those option is provided
- makes sure that both options can't be provided simultaneously
- update the related Makefile/meson.build files accordingly
- fix a bug in generate-wait_event_types.pl (die on rename($stmp...) was not
using the right file (it was using ctmp). That was not visible before the docs/code
split.

Not related to this patch but I noticed that when building with meson some c files
are duplicated a the end of the build.

Indeed, they also appear in some include directories:

./meson_build/src/include/storage/lwlocknames.c
./meson_build/src/include/utils/pgstat_wait_event.c
./meson_build/src/include/utils/fmgrtab.c
./meson_build/src/include/nodes/queryjumblefuncs.funcs.c
./meson_build/src/include/nodes/readfuncs.switch.c
./meson_build/src/include/nodes/readfuncs.funcs.c
./meson_build/src/include/nodes/copyfuncs.switch.c
./meson_build/src/include/nodes/equalfuncs.funcs.c
./meson_build/src/include/nodes/outfuncs.switch.c
./meson_build/src/include/nodes/queryjumblefuncs.switch.c
./meson_build/src/include/nodes/copyfuncs.funcs.c
./meson_build/src/include/nodes/equalfuncs.switch.c
./meson_build/src/include/nodes/outfuncs.funcs.c

Is it expected? If not, I guess it's worth another patch.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v12-0001-Generate-automatically-wait-event-related-code-a.patchtext/plain; charset=UTF-8; name=v12-0001-Generate-automatically-wait-event-related-code-a.patchDownload
From 9f3d5ece902ad2603afdc568204e77e0c168ba39 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 3 Jul 2023 15:51:40 +0900
Subject: [PATCH v12] Generate automatically wait-event related code and docs

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
---
 doc/src/sgml/.gitignore                       |    1 +
 doc/src/sgml/Makefile                         |    4 +-
 doc/src/sgml/filelist.sgml                    |    1 +
 doc/src/sgml/meson.build                      |   12 +
 doc/src/sgml/monitoring.sgml                  | 1271 +----------------
 src/backend/Makefile                          |   13 +-
 src/backend/storage/lmgr/lwlocknames.txt      |    4 +-
 src/backend/utils/activity/.gitignore         |    3 +
 src/backend/utils/activity/Makefile           |   10 +
 .../activity/generate-wait_event_types.pl     |  239 ++++
 src/backend/utils/activity/meson.build        |   24 +
 src/backend/utils/activity/wait_event.c       |  611 +-------
 .../utils/activity/wait_event_names.txt       |  371 +++++
 src/backend/utils/adt/lockfuncs.c             |    3 +-
 src/common/meson.build                        |    7 +-
 src/include/Makefile                          |    2 +-
 src/include/utils/.gitignore                  |    1 +
 src/include/utils/meson.build                 |   18 +
 src/include/utils/wait_event.h                |  232 +--
 src/test/ssl/t/002_scram.pl                   |    3 +-
 src/tools/msvc/Solution.pm                    |   19 +
 src/tools/msvc/clean.bat                      |    3 +
 22 files changed, 741 insertions(+), 2111 deletions(-)
  41.3% doc/src/sgml/
  49.4% src/backend/utils/activity/
   6.6% src/include/utils/

diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..1ccb72227e 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/wait_event_types.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..86a435112b 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 wait_event_types.sgml
 
 ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
 
@@ -111,6 +111,8 @@ 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) > $@
 
+wait_event_types.sgml: $(top_srcdir)/src/backend/utils/activity/wait_event_names.txt $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.pl
+	$(PERL) $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.pl --docs $< > $@
 
 ##
 ## Generation of some text files.
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 5465f9a46d..63b0fc2a46 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 wait_event_types    SYSTEM "wait_event_types.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..16c1aa980c 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -46,6 +46,18 @@ doc_generated += custom_target('errcodes-table.sgml',
   capture: true,
 )
 
+doc_generated += custom_target('wait_event_types.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/wait_event_names.txt'),
+  output: 'wait_event_types.sgml',
+  command: [perl,
+    files('../../../src/backend/utils/activity/generate-wait_event_types.pl'),
+    '--outdir', '@OUTDIR@', '--docs', '@INPUT@'],
+  build_by_default: false,
+  install: false,
+  capture: false,
+)
+
 # 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 5cfdc70c03..506aeaa879 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>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</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>
+  &wait_event_types;
 
    <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/src/backend/Makefile b/src/backend/Makefile
index 3c42003175..1c929383c4 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -133,6 +133,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-wait_event_types.pl utils/activity/wait_event_names.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
@@ -160,13 +163,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 $@
 
@@ -182,6 +190,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
 
@@ -301,6 +310,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/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt
index 6c7cf6c295..b34b6afecd 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/wait_event_names.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..a62378405e
--- /dev/null
+++ b/src/backend/utils/activity/.gitignore
@@ -0,0 +1,3 @@
+/pgstat_wait_event.c
+/wait_event_types.h
+/wait_event_types.sgml
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 7d7482dde0..4c32947016 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/wait_event_names.txt generate-wait_event_types.pl
+	$(PERL) $(srcdir)/generate-wait_event_types.pl --code $<
+
+maintainer-clean: clean
+	rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
new file mode 100644
index 0000000000..0e4ada47a3
--- /dev/null
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -0,0 +1,239 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from wait_event_names.txt:
+# - wait_event_types.h (if --code is passed)
+# - pgstat_wait_event.c (if --code is passed)
+# - wait_event_types.sgml (if --docs is passed)
+#
+# Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/backend/utils/activity/generate-wait_event_types.pl
+#
+#----------------------------------------------------------------------
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+my $output_path = '.';
+my $gen_docs = 0;
+my $gen_code = 0;
+
+my $continue = "\n";
+my %hashwe;
+
+GetOptions(
+	'outdir:s' => \$output_path,
+	'docs' => \$gen_docs,
+	'code' => \$gen_code);
+
+die "Needs to specify --docs or --code"
+	if (!$gen_docs && !$gen_code)  ;
+
+die "Not possible to specify --docs and --code simultaneously"
+	if ($gen_docs && $gen_code)  ;
+
+open my $wait_event_names, '<', $ARGV[0] or die;
+
+my @lines;
+my $section_name;
+my $note;
+my $note_name;
+
+# Remove comments and empty lines and add waitclassname based on the section
+while (<$wait_event_names>)
+{
+	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 third column.
+# uc() is being used to force the comparison to be case-insensitive.
+my @lines_sorted =
+  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+
+# Read the sorted lines and populate the hash table
+foreach my $line (@lines_sorted)
+{
+	die "unable to parse wait_event_names.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.
+if ($gen_code)
+{
+	# 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$$";
+	open my $h, '>', $htmp or die "Could not open $htmp: $!";
+	open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
+
+	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-wait_event_types.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';
+
+	# uc() is being used to force the comparison to be case-insensitive.
+	foreach my $waitclass (sort { uc($a) cmp uc($b) } 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;
+
+	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: $!";
+}
+# Generate the .sgml file.
+elsif ($gen_docs)
+{
+	# Include PID in suffix in case parallel make runs this multiple times.
+	my $stmp = "$output_path/wait_event_names.s.tmp$$";
+	open my $s, '>', $stmp or die "Could not open $stmp: $!";
+
+	# uc() is being used to force the comparison to be case-insensitive.
+	foreach my $waitclass (sort { uc($a) cmp uc($b) } 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($stmp, "$output_path/wait_event_types.sgml")
+	  || die "rename: $stmp: $!";
+}
+
+close $wait_event_names;
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index 518ee3f798..f1cf2af71f 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
 
+wait_event_names = custom_target('wait_event_names',
+  input: files('./wait_event_names.txt'),
+  output: ['pgstat_wait_event.c'],
+  command: [
+    perl, files('./generate-wait_event_types.pl'),
+    '-o', '@OUTDIR@', '--code',
+    '@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('wait_event_names',
+  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 8572cf169e..4aad11c111 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -206,613 +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_bufferpin() -
- *
- * Convert WaitEventBufferPin to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_bufferpin(WaitEventBufferPin w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_BUFFER_PIN:
-			event_name = "BufferPin";
-			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_extension() -
- *
- * Convert WaitEventExtension to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_extension(WaitEventExtension w)
-{
-	const char *event_name = "unknown wait event";
-
-	switch (w)
-	{
-		case WAIT_EVENT_EXTENSION:
-			event_name = "Extension";
-			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/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
new file mode 100644
index 0000000000..2e744ea8c7
--- /dev/null
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -0,0 +1,371 @@
+#
+# wait_event_names.txt
+#      PostgreSQL wait events
+#
+# Copyright (c) 2023, PostgreSQL Global Development Group
+#
+# This list serves as the basis for generating source and documentation 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/wait_event_types.sgml
+#      SGML tables of wait events for inclusion in the documentation.
+#
+# This file defines 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-wait_event_types.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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+
+#
+# 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..d05e20b2c8 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/wait_event_names.txt.
  */
 const char *const LockTagTypeNames[] = {
 	"relation",
diff --git a/src/common/meson.build b/src/common/meson.build
index 9efc80ac02..53942a9a61 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -117,13 +117,14 @@ common_sources_frontend_static += files(
 # XXX: in most environments we could probably link_whole pgcommon_shlib
 # against pgcommon_static, instead of compiling twice.
 #
-# For the server build of pgcommon, depend on lwlocknames_h, because at least
-# cryptohash_openssl.c, hmac_openssl.c depend on it. That's arguably a
+# For the server build of pgcommon, depend on lwlocknames_h and because at
+# least cryptohash_openssl.c, hmac_openssl.c depend on it.
+# controldata_utils.c depends on wait_event_types_h. That's arguably a
 # layering violation, but ...
 pgcommon = {}
 pgcommon_variants = {
   '_srv': internal_lib_args + {
-    'sources': common_sources + [lwlocknames_h],
+    'sources': common_sources + [lwlocknames_h] + [wait_event_types_h],
     'dependencies': [backend_common_code],
   },
   '': default_lib_args + {
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 c212c4091f..0baeb2f69f 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
 
+wait_event_names = custom_target('wait_event_names',
+  input: files('../../backend/utils/activity/wait_event_names.txt'),
+  output: ['wait_event_types.h'],
+  command: [
+    perl, files('../../backend/utils/activity/generate-wait_event_types.pl'),
+    '-o', '@OUTDIR@', '--code',
+    '@INPUT@'
+  ],
+  build_by_default: true,
+  install: true,
+  install_dir: [dir_include_server / 'utils'],
+)
+
+wait_event_types_h = wait_event_names[0]
+generated_backend_headers += wait_event_types_h
+
 errcodes = custom_target('errcodes',
   input: files('../../backend/utils/errcodes.txt'),
   output: ['errcodes.h'],
@@ -58,3 +74,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 dc01d4e84d..4517425f84 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,236 +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 - BUFFERPIN
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_BUFFER_PIN = PG_WAIT_BUFFERPIN
-} WaitEventBufferPin;
-
-/* ----------
- * 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 - EXTENSION
- * ----------
- */
-typedef enum
-{
-	WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION
-} WaitEventExtension;
-
-/* ----------
- * 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/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
index 3a798e1a56..27abd02abf 100644
--- a/src/test/ssl/t/002_scram.pl
+++ b/src/test/ssl/t/002_scram.pl
@@ -87,8 +87,7 @@ $node->connect_fails(
 	expected_stderr => qr/invalid channel_binding value: "invalid_value"/);
 $node->connect_ok("$common_connstr user=ssltestuser channel_binding=disable",
 	"SCRAM with SSL and channel_binding=disable");
-$node->connect_ok(
-	"$common_connstr user=ssltestuser channel_binding=require",
+$node->connect_ok("$common_connstr user=ssltestuser channel_binding=require",
 	"SCRAM with SSL and channel_binding=require");
 
 # Now test when the user has an MD5-encrypted password; should fail
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index e6d8f9fedc..133acc09f2 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -585,6 +585,25 @@ sub GenerateFiles
 			'src/include/storage/lwlocknames.h');
 	}
 
+	if (IsNewer(
+			'src/include/utils/wait_event_types.h',
+			'src/backend/utils/activity/wait_event_names.txt'))
+	{
+		print "Generating pgstat_wait_event.c and wait_event_types.h...\n";
+		my $activ = 'src/backend/utils/activity';
+		system(
+			"perl $activ/generate-wait_event_types.pl --outdir $activ --code $activ/wait_event_names.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 cf35764604..7cb23ea894 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -46,6 +46,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
@@ -53,6 +54,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
-- 
2.34.1

#31Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#29)
Re: Autogenerate some wait events code and documentation

On Tue, Jul 04, 2023 at 09:34:33AM +0200, Drouvot, Bertrand wrote:

Yeah, with "capture" set to "false" then ninja alldocs does not error out
and wait_event_types.sgml gets generated.

I'll look at the extra options --code and --docs.

+wait_event_types.sgml: $(top_srcdir)/src/backend/utils/activity/wait_event_names.txt $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.pl
+   $(PERL) $(top_srcdir)/src/backend/utils/activity/generate-wait_event_types.pl --docs $< > $@

This is doing the same error as meson in v10, there is no need for
the last part doing the redirection because the script outputs
nothing. Here is the command generated:
make -C doc/src/sgml/ wait_event_types.sgml
'/usr/bin/perl'
../../../src/backend/utils/activity/generate-wait_event_types.pl
--docs ../../../src/backend/utils/activity/wait_event_names.txt >
wait_event_types.sgml

+wait_event_names = custom_target('wait_event_names',
+  input: files('../../backend/utils/activity/wait_event_names.txt'),
+  output: ['wait_event_types.h'],
This one was not completely correct (look at fmgrtab, for example), as
it is missing pgstat_wait_event.c in the output generated.  We could
perhaps be more selective with all that, including fmgrtab, but I have
left that out for now.  Note also the tweak with install_dir to not
install the C file.
+wait_event_names = custom_target('wait_event_names',
+  input: files('./wait_event_names.txt'),
+  output: ['pgstat_wait_event.c'],
+  command: [
+    perl, files('./generate-wait_event_types.pl'),
+    '-o', '@OUTDIR@', '--code',
+    '@INPUT@'
+  ],
+  install: true,
+  install_dir: [false],
+)
[...]
+# 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('wait_event_names',
+  waitevent_sources,
+  dependencies: [backend_code],
+  include_directories: include_directories('../../../include/utils'),
+  kwargs: internal_lib_args,
+)

"wait_event_names" with the extra command should not be necessary
here, because we feed from the C file generated in src/include/utils/,
included in wait_event.c. See src/backend/nodes/meson.build for a
similar example

Two of the error messages after rename() in the script were
inconsistent. So reworded these on the way.

I have added a usage() to the script, while on it.

The VPATH build was broken, because the following line was missing
from src/backend/utils/activity/Makefile to be able to detect
pgstat_wait_event.c from wait_event.c:
override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS)

With all that in place, VPATH builds, the CI, meson, configure/make
and the various cleanup targets were working fine, so I have applied
it. Now let's see what the buildfarm tells.

The final --stat number is like that:
22 files changed, 757 insertions(+), 2111 deletions(-)
--
Michael

#32Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#31)
Re: Autogenerate some wait events code and documentation

Hi,

On 2023-07-05 10:57:19 +0900, Michael Paquier wrote:

With all that in place, VPATH builds, the CI, meson, configure/make
and the various cleanup targets were working fine, so I have applied
it. Now let's see what the buildfarm tells.

The final --stat number is like that:
22 files changed, 757 insertions(+), 2111 deletions(-)

That's pretty nice!

Rebasing a patch over this I was a bit confused because I got a bunch of
""unable to parse wait_event_names.txt" errors. Took me a while to figure out
that that was just because I didn't include a trailing . in the description.
Perhaps that could be turned into a more meaningful error?

die "unable to parse wait_event_names.txt"
unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;

It's not helped by the fact that the regex in the error actually doesn't match
any lines, because it's not operating on the input but on
push(@lines, $section_name . "\t" . $_);

I also do wonder if we should invest in generating the lwlock names as
well. Except for a few abbreviations, the second column is always the
camel-cased version of what follows WAIT_EVENT_. Feels pretty tedious to write
that out.

Perhaps we should just change the case of the upper-cased names (DSM, SSL,
WAL, ...) to follow the other names?

Greetings,

Andres Freund

#33Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#32)
Re: Autogenerate some wait events code and documentation

On Wed, Jul 05, 2023 at 02:59:39PM -0700, Andres Freund wrote:

Rebasing a patch over this I was a bit confused because I got a bunch of
""unable to parse wait_event_names.txt" errors. Took me a while to figure out
that that was just because I didn't include a trailing . in the description.
Perhaps that could be turned into a more meaningful error?

die "unable to parse wait_event_names.txt"
unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;

Agreed that we could at least add the $line in the error message
generated, at least, to help with debugging.

I also do wonder if we should invest in generating the lwlock names as
well. Except for a few abbreviations, the second column is always the
camel-cased version of what follows WAIT_EVENT_. Feels pretty tedious to write
that out.

And you mean getting rid of lwlocknames.txt? The impact on dtrace or
other similar tools is uncertain to me because we have free number on
this list, and stuff like GetLWLockIdentifier() rely on the input ID
from lwlocknames.txt.

Perhaps we should just change the case of the upper-cased names (DSM, SSL,
WAL, ...) to follow the other names?

So you mean renaming the existing events like WalSenderWaitForWAL to
WalSenderWaitForWal? The impact on existing monitoring queries is not
zero because any changes would be silent, and that's the part that
worried me the most even if it can remove one column in the txt file.
--
Michael

#34Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#33)
Re: Autogenerate some wait events code and documentation

Hi,

On 2023-07-06 09:36:12 +0900, Michael Paquier wrote:

On Wed, Jul 05, 2023 at 02:59:39PM -0700, Andres Freund wrote:

Rebasing a patch over this I was a bit confused because I got a bunch of
""unable to parse wait_event_names.txt" errors. Took me a while to figure out
that that was just because I didn't include a trailing . in the description.
Perhaps that could be turned into a more meaningful error?

die "unable to parse wait_event_names.txt"
unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;

Agreed that we could at least add the $line in the error message
generated, at least, to help with debugging.

I also do wonder if we should invest in generating the lwlock names as
well. Except for a few abbreviations, the second column is always the
camel-cased version of what follows WAIT_EVENT_. Feels pretty tedious to write
that out.

And you mean getting rid of lwlocknames.txt?

No, I meant the second column in wait_event_names.txt. If you look at stuff
like:
WAIT_EVENT_ARCHIVER_MAIN "ArchiverMain" "Waiting in main loop of archiver process."

It'd be pretty trivial to generate ArchiverMain from ARCHIVER_MAIN.

The impact on dtrace or other similar tools is uncertain to me because we
have free number on this list, and stuff like GetLWLockIdentifier() rely on
the input ID from lwlocknames.txt.

I don't really care, tbh. If we wanted to keep the names the same in case of
abbreviations, we could just make the name optional, and auto-generated if not
explicitly specified.

Perhaps we should just change the case of the upper-cased names (DSM, SSL,
WAL, ...) to follow the other names?

So you mean renaming the existing events like WalSenderWaitForWAL to
WalSenderWaitForWal?

Yes.

The impact on existing monitoring queries is not zero because any changes
would be silent, and that's the part that worried me the most even if it can
remove one column in the txt file.

Then let's just use - or so to indicate the inferred name, with a "string"
overriding it?

Greetings,

Andres Freund

#35Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#34)
Re: Autogenerate some wait events code and documentation

On Thu, Jul 06, 2023 at 06:19:43PM -0700, Andres Freund wrote:

On 2023-07-06 09:36:12 +0900, Michael Paquier wrote:

So you mean renaming the existing events like WalSenderWaitForWAL to
WalSenderWaitForWal?

Yes.

The impact on existing monitoring queries is not zero because any changes
would be silent, and that's the part that worried me the most even if it can
remove one column in the txt file.

Then let's just use - or so to indicate the inferred name, with a "string"
overriding it?

Hmm. If we go down this road I would make the choice of simplicity
and remove entirely a column, then, generating the snakecase from the
camelcase or vice-versa (say like a $string =~ s/([a-z]+)/$1_/g;),
even if it means having slightly incompatible strings showing to the
users. And I'd rather minimize the number of exceptions we need to
handle in this automation (aka no exception rules for some keywords
like "SSL" or "WAL", etc.).
--
Michael

#36Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#35)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Fri, Jul 07, 2023 at 01:49:24PM +0900, Michael Paquier wrote:

Hmm. If we go down this road I would make the choice of simplicity
and remove entirely a column, then, generating the snakecase from the
camelcase or vice-versa (say like a $string =~ s/([a-z]+)/$1_/g;),
even if it means having slightly incompatible strings showing to the
users. And I'd rather minimize the number of exceptions we need to
handle in this automation (aka no exception rules for some keywords
like "SSL" or "WAL", etc.).

After pondering more about that, the attached patch set does exactly
that. Patch 0001 includes an update of the wait event names so as
these are more consistent with the enum elements generated. With this
change, users can apply lower() or upper() across monitoring queries
and still get the same results as before. An exception was the
message queue events, which the enums used "MQ" but the event names
used "MessageQueue", but this concerns only four lines of code in the
backend. The newly-generated enum elements match with the existing
ones, except for MQ.

Patch 0002 introduces a set of simplifications for the format of
wait_event_names.txt:
- Removal of the first column for the enums.
- Removal of the quotes for the event name.  We have a single keyword
for these, so that's kind of annoying to cope with that for new
entries.
- Build of the enum elements using the event names, by applying a
rebuild as simple as that:
+   $waiteventenumname =~ s/([a-z])([A-Z])/$1_$2/g;
+   $waiteventenumname = uc($waiteventenumname);

Thoughts?
--
Michael

Attachments:

0001-Rename-wait-events-with-more-consistent-camelcase-st.patchtext/x-diff; charset=us-asciiDownload
From 30dff3cc8ab825bc968ecfed13eecee6725f6a80 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Sun, 9 Jul 2023 13:24:54 +0900
Subject: [PATCH 1/2] Rename wait events with more consistent camelcase style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 3 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 39e77ef945..87b8570a42 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 7af1a61f95..e706dfd8f3 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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	"WalSenderWaitWal"	"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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	"ArchiveCleanupCommand"	"Waiting for <xref li
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	"LogicalApplySendData"	"Waiting for a logical
 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_MESSAGE_QUEUE_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive loc
 
 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_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."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	"DataFileRead"	"Waiting for a read from a relation dat
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	"ReplicationSlotRead"	"Waiting for a read from
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	"TwophaseFileRead"	"Waiting for a read of a two ph
 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_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."
 
 
 #
-- 
2.40.1

0002-Simplify-format-of-wait_event_names.txt.patchtext/x-diff; charset=us-asciiDownload
From f4646efad35f565f0482f057142ea985c7faa44f Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Sun, 9 Jul 2023 13:21:17 +0900
Subject: [PATCH 2/2] Simplify format of wait_event_names.txt

This file is now made of two columns, removing the column listing the
enum elements for each wait event class:
- Camelcase event name used in pg_stat_activity.  There are now
unquoted.
- Description of the documentation.

While on it, add more information in generate-wait_event_types.pl about
the location of any parsing failure.
---
 .../activity/generate-wait_event_types.pl     |  34 +-
 .../utils/activity/wait_event_names.txt       | 492 +++++++++---------
 2 files changed, 265 insertions(+), 261 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 6d1a2af42a..2f8de3af85 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -72,25 +72,27 @@ my @lines_sorted =
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
-	die "unable to parse wait_event_names.txt"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+	die "unable to parse wait_event_names.txt for line $line\n"
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventdescription, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  Camelcase strings like "WaitEventName"
+	# are converted to WAIT_EVENT_WAIT_EVENT_NAME.
+	my $waiteventenumname = $waiteventdescription;
+	# Add underscores between sequences of lower-case and upper-case
+	# characters, then upper-case the whole.
+	$waiteventenumname =~ s/([a-z])([A-Z])/$1_$2/g;
+	$waiteventenumname = uc($waiteventenumname);
+	$waiteventenumname = "WAIT_EVENT_$waiteventenumname";
+
+	# Store the event into the list for each class.
 	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);
 }
@@ -173,7 +175,9 @@ if ($gen_code)
 			$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];
+			# Apply quotes to the wait event name string.
+			printf $c "\t\t\t event_name = \"%s\";\n\t\t\t break;\n",
+			  $wev->[1];
 		}
 
 		printf $h "\n} $waitclass;\n\n";
@@ -226,7 +230,7 @@ elsif ($gen_docs)
 		{
 			printf $s "     <row>\n";
 			printf $s "      <entry><literal>%s</literal></entry>\n",
-			  substr $wev->[1], 1, -1;
+			  $wev->[1];
 			printf $s "      <entry>%s</entry>\n", substr $wev->[2], 1, -1;
 			printf $s "     </row>\n";
 		}
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index e706dfd8f3..5286b37328 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -21,7 +21,7 @@
 # This file defines one wait event per line, with the following
 # tab-separated fields:
 #
-#   "C symbol in enums" "format in the system views" "description in the docs"
+#   "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.
@@ -44,19 +44,19 @@
 
 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."
+ArchiverMain	"Waiting in main loop of archiver process."
+AutovacuumMain	"Waiting in main loop of autovacuum launcher process."
+BgwriterHibernate	"Waiting in background writer process, hibernating."
+BgwriterMain	"Waiting in main loop of background writer process."
+CheckpointerMain	"Waiting in main loop of checkpointer process."
+LogicalApplyMain	"Waiting in main loop of logical replication apply process."
+LogicalLauncherMain	"Waiting in main loop of logical replication launcher process."
+LogicalParallelApplyMain	"Waiting in main loop of logical replication parallel apply process."
+RecoveryWalStream	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SysloggerMain	"Waiting in main loop of syslogger process."
+WalReceiverMain	"Waiting in main loop of WAL receiver process."
+WalSenderMain	"Waiting in main loop of WAL sender process."
+WalWriterMain	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer p
 
 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	"WalSenderWaitWal"	"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."
+ClientRead	"Waiting to read data from the client."
+ClientWrite	"Waiting to write data to the client."
+GssOpenServer	"Waiting to read data from the client while establishing a GSSAPI session."
+LibpqwalreceiverConnect	"Waiting in WAL receiver to establish connection to remote server."
+LibpqwalreceiverReceive	"Waiting in WAL receiver to receive data from remote server."
+SslOpenServer	"Waiting for SSL while attempting connection."
+WalSenderWaitWal	"Waiting for WAL to be flushed in WAL sender process."
+WalSenderWriteData	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity
 
 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_MESSAGE_QUEUE_INTERNAL	"MessageQueueInternal"	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	"MessageQueuePutMessage"	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	"MessageQueueReceive"	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
+AppendReady	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ArchiveCleanupCommand	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ArchiveCommand	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BackendTermination	"Waiting for the termination of another backend."
+BackupWaitWalArchive	"Waiting for WAL files required for a backup to be successfully archived."
+BgworkerShutdown	"Waiting for background worker to shut down."
+BgworkerStartup	"Waiting for background worker to start up."
+BtreePage	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BufferIo	"Waiting for buffer I/O to complete."
+CheckpointDone	"Waiting for a checkpoint to complete."
+CheckpointStart	"Waiting for a checkpoint to start."
+ExecuteGather	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HashBatchAllocate	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HashBatchElect	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HashBatchLoad	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HashBuildAllocate	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HashBuildElect	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HashBuildHashInner	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HashBuildHashOuter	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HashGrowBatchesDecide	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesElect	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HashGrowBatchesFinish	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesReallocate	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HashGrowBatchesRepartition	"Waiting for other Parallel Hash participants to finish repartitioning."
+HashGrowBucketsElect	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HashGrowBucketsReallocate	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HashGrowBucketsReinsert	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LogicalApplySendData	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LogicalParallelApplyStateChange	"Waiting for a logical replication parallel apply process to change state."
+LogicalSyncData	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LogicalSyncStateChange	"Waiting for a logical replication remote server to change state."
+MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+MessageQueueSend	"Waiting to send bytes to a shared message queue."
+ParallelBitmapScan	"Waiting for parallel bitmap scan to become initialized."
+ParallelCreateIndexScan	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+ParallelFinish	"Waiting for parallel workers to finish computing."
+ProcarrayGroupUpdate	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+ProcSignalBarrier	"Waiting for a barrier event to be processed by all backends."
+Promote	"Waiting for standby promotion."
+RecoveryConflictSnapshot	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RecoveryConflictTablespace	"Waiting for recovery conflict resolution for dropping a tablespace."
+RecoveryEndCommand	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RecoveryPause	"Waiting for recovery to be resumed."
+ReplicationOriginDrop	"Waiting for a replication origin to become inactive so it can be dropped."
+ReplicationSlotDrop	"Waiting for a replication slot to become inactive so it can be dropped."
+RestoreCommand	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SafeSnapshot	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SyncRep	"Waiting for confirmation from a remote server during synchronous replication. Waiting to read or update information about the state of synchronous replication."
+WalReceiverExit	"Waiting for the WAL receiver to exit."
+WalReceiverWaitStart	"Waiting for startup process to send initial data for streaming replication."
+XactGroupUpdate	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to
 
 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."
+BaseBackupThrottle	"Waiting during base backup when throttling activity."
+CheckpointWriteDelay	"Waiting between writes while performing a checkpoint."
+PgSleep	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RecoveryApplyDelay	"Waiting to apply WAL during recovery because of a delay setting."
+RecoveryRetrieveRetryInterval	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+RegisterSyncRequest	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SpinDelay	"Waiting while acquiring a contended spinlock."
+VacuumDelay	"Waiting in a cost-based vacuum delay point."
+VacuumTruncate	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive loc
 
 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."
+BasebackupRead	"Waiting for base backup to read from a file."
+BasebackupSync	"Waiting for data written by a base backup to reach durable storage."
+BasebackupWrite	"Waiting for base backup to write to a file."
+BuffileRead	"Waiting for a read from a buffered file."
+BuffileWrite	"Waiting for a write to a buffered file."
+BuffileTruncate	"Waiting for a buffered file to be truncated."
+ControlFileRead	"Waiting for a read from the <filename>pg_control</filename> file."
+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."
+ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+ControlFileWrite	"Waiting for a write to the <filename>pg_control</filename> file. Waiting for a write to update the <filename>pg_control</filename> file."
+ControlFileWriteUpdate	"Waiting for a write to update the <filename>pg_control</filename> file."
+CopyFileRead	"Waiting for a read during a file copy operation."
+CopyFileWrite	"Waiting for a write during a file copy operation."
+DataFileExtend	"Waiting for a relation data file to be extended."
+DataFileFlush	"Waiting for a relation data file to reach durable storage."
+DataFileImmediateSync	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DataFilePrefetch	"Waiting for an asynchronous prefetch from a relation data file."
+DataFileRead	"Waiting for a read from a relation data file."
+DataFileSync	"Waiting for changes to a relation data file to reach durable storage."
+DataFileTruncate	"Waiting for a relation data file to be truncated."
+DataFileWrite	"Waiting for a write to a relation data file."
+DsmAllocate	"Waiting for a dynamic shared memory segment to be allocated."
+DsmFillZeroWrite	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LockFileAddtodatadirRead	"Waiting for a read while adding a line to the data directory lock file."
+LockFileAddtodatadirSync	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LockFileAddtodatadirWrite	"Waiting for a write while adding a line to the data directory lock file."
+LockFileCreateRead	"Waiting to read while creating the data directory lock file."
+LockFileCreateSync	"Waiting for data to reach durable storage while creating the data directory lock file."
+LockFileCreateWrite	"Waiting for a write while creating the data directory lock file."
+LockFileRecheckdatadirRead	"Waiting for a read during recheck of the data directory lock file."
+LogicalRewriteCheckpointSync	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LogicalRewriteMappingSync	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LogicalRewriteMappingWrite	"Waiting for a write of mapping data during a logical rewrite."
+LogicalRewriteSync	"Waiting for logical rewrite mappings to reach durable storage."
+LogicalRewriteTruncate	"Waiting for truncate of mapping data during a logical rewrite."
+LogicalRewriteWrite	"Waiting for a write of logical rewrite mappings."
+RelationMapRead	"Waiting for a read of the relation map file."
+RelationMapReplace	"Waiting for durable replacement of a relation map file."
+RelationMapWrite	"Waiting for a write to the relation map file."
+ReorderBufferRead	"Waiting for a read during reorder buffer management."
+ReorderBufferWrite	"Waiting for a write during reorder buffer management."
+ReorderLogicalMappingRead	"Waiting for a read of a logical mapping during reorder buffer management."
+ReplicationSlotRead	"Waiting for a read from a replication slot control file."
+ReplicationSlotRestoreSync	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+ReplicationSlotSync	"Waiting for a replication slot control file to reach durable storage."
+ReplicationSlotWrite	"Waiting for a write to a replication slot control file."
+SlruFlushSync	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SlruRead	"Waiting for a read of an SLRU page."
+SlruSync	"Waiting for SLRU data to reach durable storage following a page write."
+SlruWrite	"Waiting for a write of an SLRU page."
+SnapbuildRead	"Waiting for a read of a serialized historical catalog snapshot."
+SnapbuildSync	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SnapbuildWrite	"Waiting for a write of a serialized historical catalog snapshot."
+TimelineHistoryFileSync	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TimelineHistoryFileWrite	"Waiting for a write of a timeline history file received via streaming replication."
+TimelineHistoryRead	"Waiting for a read of a timeline history file."
+TimelineHistorySync	"Waiting for a newly created timeline history file to reach durable storage."
+TimelineHistoryWrite	"Waiting for a write of a newly created timeline history file."
+TwophaseFileRead	"Waiting for a read of a two phase state file."
+TwophaseFileSync	"Waiting for a two phase state file to reach durable storage."
+TwophaseFileWrite	"Waiting for a write of a two phase state file."
+VersionFileWrite	"Waiting for the version file to be written while creating a database."
+WalsenderTimelineHistoryRead	"Waiting for a read from a timeline history file during a walsender timeline command."
+WalBootstrapSync	"Waiting for WAL to reach durable storage during bootstrapping."
+WalBootstrapWrite	"Waiting for a write of a WAL page during bootstrapping."
+WalCopyRead	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WalCopySync	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WalCopyWrite	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WalInitSync	"Waiting for a newly initialized WAL file to reach durable storage."
+WalInitWrite	"Waiting for a write while initializing a new WAL file."
+WalRead	"Waiting for a read from a WAL file."
+WalSync	"Waiting for a WAL file to reach durable storage. Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalSyncMethodAssign	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalWrite	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	"WalWrite"	"Waiting for a write to a WAL file. Waiting for
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buffer."
+BufferPin	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buff
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait events - LWLock
@@ -272,81 +272,81 @@ WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
 
 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."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
 
-WAIT_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait even - Lock
@@ -357,15 +357,15 @@ WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replicati
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#37Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#36)
Re: Autogenerate some wait events code and documentation

Hi,

On 7/9/23 6:32 AM, Michael Paquier wrote:

On Fri, Jul 07, 2023 at 01:49:24PM +0900, Michael Paquier wrote:

Hmm. If we go down this road I would make the choice of simplicity
and remove entirely a column, then, generating the snakecase from the
camelcase or vice-versa (say like a $string =~ s/([a-z]+)/$1_/g;),
even if it means having slightly incompatible strings showing to the
users. And I'd rather minimize the number of exceptions we need to
handle in this automation (aka no exception rules for some keywords
like "SSL" or "WAL", etc.).

After pondering more about that, the attached patch set does exactly
that.

Thanks!

Patch 0001 includes an update of the wait event names so as
these are more consistent with the enum elements generated. With this
change, users can apply lower() or upper() across monitoring queries
and still get the same results as before. An exception was the
message queue events, which the enums used "MQ" but the event names
used "MessageQueue", but this concerns only four lines of code in the
backend. The newly-generated enum elements match with the existing
ones, except for MQ.

Patch 0002 introduces a set of simplifications for the format of
wait_event_names.txt:
- Removal of the first column for the enums.
- Removal of the quotes for the event name.  We have a single keyword
for these, so that's kind of annoying to cope with that for new
entries.
- Build of the enum elements using the event names, by applying a
rebuild as simple as that:
+   $waiteventenumname =~ s/([a-z])([A-Z])/$1_$2/g;
+   $waiteventenumname = uc($waiteventenumname);

Thoughts?

That's great and it does simplify the wait_event_names.txt format (and the
impact on "MQ" does not seem like a big deal).

I also noticed that you now provide the culprit line in case of parsing
failure (thanks for that).

  #
-#   "C symbol in enums" "format in the system views" "description in the docs"
+#   "format in the system views" "description in the docs"

Should we add a note here about the impact of the "format in the system views" on
the auto generated enum? (aka how it is generated based on its format)?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#38Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#37)
Re: Autogenerate some wait events code and documentation

On Sun, Jul 09, 2023 at 09:15:34AM +0200, Drouvot, Bertrand wrote:

I also noticed that you now provide the culprit line in case of parsing
failure (thanks for that).

Yes, that's mentioned in the commit message I quickly wrote in 0002.

#
-#   "C symbol in enums" "format in the system views" "description in the docs"
+#   "format in the system views" "description in the docs"

Should we add a note here about the impact of the "format in the system views" on
the auto generated enum? (aka how it is generated based on its format)?

There is one, but now that I look at it WAIT_EVENT repeated twice does
not look great, so this could use "FooBarName" or equivalent:
+   # Generate the element name for the enums based on the
+   # description.  Camelcase strings like "WaitEventName"
+   # are converted to WAIT_EVENT_WAIT_EVENT_NAME.
--
Michael
#39Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#38)
Re: Autogenerate some wait events code and documentation

Hi,

On 7/9/23 9:36 AM, Michael Paquier wrote:

On Sun, Jul 09, 2023 at 09:15:34AM +0200, Drouvot, Bertrand wrote:

I also noticed that you now provide the culprit line in case of parsing
failure (thanks for that).

Yes, that's mentioned in the commit message I quickly wrote in 0002.

#
-#   "C symbol in enums" "format in the system views" "description in the docs"
+#   "format in the system views" "description in the docs"

Should we add a note here about the impact of the "format in the system views" on
the auto generated enum? (aka how it is generated based on its format)?

There is one,

Yeah there is one in generate-wait_event_types.pl. I was wondering
to add one in wait_event_names.txt too (as this is the place where
no wait events would be added if any).

but now that I look at it WAIT_EVENT repeated twice does
not look great, so this could use "FooBarName" or equivalent:

+1 for "FooBarName"

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#40Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#39)
Re: Autogenerate some wait events code and documentation

On Mon, Jul 10, 2023 at 07:05:30AM +0200, Drouvot, Bertrand wrote:

Yeah there is one in generate-wait_event_types.pl. I was wondering
to add one in wait_event_names.txt too (as this is the place where
no wait events would be added if any).

Hmm. Something like that could be done, for instance:

 #   src/backend/utils/activity/wait_event_types.h
-#      typedef enum definitions for wait events.
+#      typedef enum definitions for wait events, generated from the first
+#      field.
--
Michael
#41Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#40)
Re: Autogenerate some wait events code and documentation

On 7/10/23 7:20 AM, Michael Paquier wrote:

On Mon, Jul 10, 2023 at 07:05:30AM +0200, Drouvot, Bertrand wrote:

Yeah there is one in generate-wait_event_types.pl. I was wondering
to add one in wait_event_names.txt too (as this is the place where
no wait events would be added if any).

Hmm. Something like that could be done, for instance:

#   src/backend/utils/activity/wait_event_types.h
-#      typedef enum definitions for wait events.
+#      typedef enum definitions for wait events, generated from the first
+#      field.

Yeah, it looks a good place for it.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#42Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Michael Paquier (#36)
Re: Autogenerate some wait events code and documentation

On 2023-Jul-09, Michael Paquier wrote:

Patch 0002 introduces a set of simplifications for the format of
wait_event_names.txt:
- Removal of the first column for the enums.

I don't like this bit, because it means the .txt file is now ungreppable
as source of the enum name. Things become mysterious and people have to
track down the event name by reading the the Perl generating script.
It's annoying. I'd rather have the extra column, even if it means a
little duplicity.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"Siempre hay que alimentar a los dioses, aunque la tierra esté seca" (Orual)

#43Michael Paquier
michael@paquier.xyz
In reply to: Alvaro Herrera (#42)
Re: Autogenerate some wait events code and documentation

On Mon, Jul 10, 2023 at 09:11:36AM +0200, Alvaro Herrera wrote:

I don't like this bit, because it means the .txt file is now ungreppable
as source of the enum name. Things become mysterious and people have to
track down the event name by reading the the Perl generating script.
It's annoying. I'd rather have the extra column, even if it means a
little duplicity.

Hmm. I can see your point that we'd lose the direct relationship
between the enum and string when running a single `git grep` from the
tree, still attempting to do that does not actually lead to much
information gained? Personally, I usually grep for code when looking
for consistent information across various paths in the tree. Wait
events are very different: each enum is used in a single place in the
tree making their grep search the equivalent of looking at
wait_event_names.txt anyway?

The quotes in the second columns can be removed even with your
argument in place. That improves a bit the format.
--
Michael

#44Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#43)
Re: Autogenerate some wait events code and documentation

On 7/11/23 12:52 AM, Michael Paquier wrote:

On Mon, Jul 10, 2023 at 09:11:36AM +0200, Alvaro Herrera wrote:

I don't like this bit, because it means the .txt file is now ungreppable
as source of the enum name. Things become mysterious and people have to
track down the event name by reading the the Perl generating script.
It's annoying. I'd rather have the extra column, even if it means a
little duplicity.

Hmm. I can see your point that we'd lose the direct relationship
between the enum and string when running a single `git grep` from the
tree, still attempting to do that does not actually lead to much
information gained? Personally, I usually grep for code when looking
for consistent information across various paths in the tree. Wait
events are very different: each enum is used in a single place in the
tree making their grep search the equivalent of looking at
wait_event_names.txt anyway?

Before commit fa88928470 one could find the relationship between the enum and the name
in wait_event.c (a simple git grep would provide it).

With commit fa88928470 in place, one could find the relationship between the enum and the name
in wait_event_names.txt (a simple git grep would provide it).

With the proposal we are discussing here, once the build is done and so the pgstat_wait_event.c
file is generated then we have the same "grep" capability than pre commit fa88928470 (except that
"git grep" can't be used and one would need things like
find . -name "*.c" -exec grep -il "WAIT_EVENT_CHECKPOINTER_MAIN" {} \;)

I agree that it is less "obvious" than pre fa88928470 but still doable though.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#45Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#41)
4 attachment(s)
Re: Autogenerate some wait events code and documentation

On Mon, Jul 10, 2023 at 07:52:23AM +0200, Drouvot, Bertrand wrote:

On 7/10/23 7:20 AM, Michael Paquier wrote:

Hmm. Something like that could be done, for instance:

#   src/backend/utils/activity/wait_event_types.h
-#      typedef enum definitions for wait events.
+#      typedef enum definitions for wait events, generated from the first
+#      field.

Yeah, it looks a good place for it.

I am not sure where we are on that based on the objection from Alvaro
to not remove the first column in wait_event_names.txt about
greppability. Anyway, I am not seeing any objections behind my
suggestion to simplify the second column and remove the quotes from
the event names, either. Besides, the suggestion of Andres to improve
the error message on parsing and show the line information is
something useful in itself.

Hence, attached is a rebased patch set that separates the work into
more patches:
- 0001 removes the quotes from the second column, improving the
readability of the .txt file.
- 0002 fixes the report from Andres to improve the error message on
parsing.
- 0003 is the rename of the wait events, in preparation for...
- 0004 that removes entirely the first column (enum element names)
from wait_event_names.txt.

I would like to apply 0001 and 0002 to improve the format if there are
no objections. 0003 and 0004 are still here for discussion, as it
does not seem like a consensus has been reached for that yet. Getting
more opinions would be a good next step for the last two patches, I
assume.

So, any comments?
--
Michael

Attachments:

v2-0001-Remove-quotes-from-second-column-of-wait_event_na.patchtext/x-diff; charset=us-asciiDownload
From 4e10ef4726dc7179c02d23ec7e31f90d931b734a Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 13 Jul 2023 09:51:28 +0900
Subject: [PATCH v2 1/4] Remove quotes from second column of
 wait_event_names.txt

These are not required, as the fields quoted are single words.
---
 .../activity/generate-wait_event_types.pl     |   8 +-
 .../utils/activity/wait_event_names.txt       | 490 +++++++++---------
 2 files changed, 250 insertions(+), 248 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 75cddf6fa2..2a9e341c58 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -73,7 +73,7 @@ my @lines_sorted =
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
 	(   my $waitclassname,
 		my $waiteventenumname,
@@ -168,7 +168,9 @@ if ($gen_code)
 			$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];
+			# Apply quotes to the wait event name string.
+			printf $c "\t\t\t event_name = \"%s\";\n\t\t\t break;\n",
+			  $wev->[1];
 		}
 
 		printf $h "\n} $waitclass;\n\n";
@@ -221,7 +223,7 @@ elsif ($gen_docs)
 		{
 			printf $s "     <row>\n";
 			printf $s "      <entry><literal>%s</literal></entry>\n",
-			  substr $wev->[1], 1, -1;
+			  $wev->[1];
 			printf $s "      <entry>%s</entry>\n", substr $wev->[2], 1, -1;
 			printf $s "     </row>\n";
 		}
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 7af1a61f95..3fabad96d9 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -44,19 +44,19 @@
 
 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_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."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	"WalWriterMain"	"Waiting in main loop of WAL writer p
 
 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_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."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	"WalSenderWriteData"	"Waiting for any activity
 
 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_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."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	"XactGroupUpdate"	"Waiting for the group leader to
 
 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_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."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	"VacuumTruncate"	"Waiting to acquire an exclusive loc
 
 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_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."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	"WALWrite"	"Waiting for a write to a WAL file. Waiting for
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buffer."
+WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	"BufferPin"	"Waiting to acquire an exclusive pin on a buff
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
+WAIT_EVENT_EXTENSION	Extension	"Waiting in an extension."
 
 #
 # Wait events - LWLock
@@ -272,81 +272,81 @@ WAIT_EVENT_EXTENSION	"Extension"	"Waiting in an extension."
 
 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_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_EVENT_DOCONLY	"XactBuffer"	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	"CommitTsBuffer"	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	"SubtransBuffer"	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	"MultiXactOffsetBuffer"	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	"MultiXactMemberBuffer"	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	"NotifyBuffer"	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	"SerialBuffer"	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	"WALInsert"	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	"BufferContent"	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	"ReplicationOriginState"	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	"ReplicationSlotIO"	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	"LockFastPath"	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	"BufferMapping"	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	"LockManager"	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	"PredicateLockManager"	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	"ParallelHashJoin"	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	"ParallelQueryDSA"	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	"PerSessionDSA"	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	"PerSessionRecordType"	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	"PerSessionRecordTypmod"	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	"SharedTupleStore"	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	"SharedTidBitmap"	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	"ParallelAppend"	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	"PerXactPredicateList"	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	"PgStatsDSA"	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	"PgStatsHash"	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	"PgStatsData"	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	"LogicalRepLauncherDSA"	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replication launcher's shared hash table."
+WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
+WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
+WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
+WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
+WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
+WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
+WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait even - Lock
@@ -357,15 +357,15 @@ WAIT_EVENT_DOCONLY	"LogicalRepLauncherHash"	"Waiting to access logical replicati
 
 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."
+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."
-- 
2.40.1

v2-0002-Add-information-about-line-contents-on-parsing-fa.patchtext/x-diff; charset=us-asciiDownload
From 8a826f4b502a2b3a55b4afc59ab8b3a042e1d623 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 13 Jul 2023 09:52:37 +0900
Subject: [PATCH v2 2/4] Add information about line contents on parsing failure
 of wait_event_names.txt

The contents of the line whose parsing failed was not reported in the
error message produced by generate-wait_event_types.pl, making it harder
to debug.

Reported-by: Andres Freund
---
 src/backend/utils/activity/generate-wait_event_types.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 2a9e341c58..f63c991051 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -72,7 +72,7 @@ my @lines_sorted =
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
-	die "unable to parse wait_event_names.txt"
+	die "unable to parse wait_event_names.txt for line $line\n"
 	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
 	(   my $waitclassname,
-- 
2.40.1

v2-0003-Rename-wait-events-with-more-consistent-camelcase.patchtext/x-diff; charset=us-asciiDownload
From 4175198016bfb3e8c75ea4c54cdbc6ac393163f2 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Sun, 9 Jul 2023 13:24:54 +0900
Subject: [PATCH v2 3/4] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 3 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 39e77ef945..87b8570a42 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 3fabad96d9..c4967e274e 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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	WalSenderWaitWal	"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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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_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."
 
 
 #
-- 
2.40.1

v2-0004-Remove-column-for-enum-elements-in-wait_event_nam.patchtext/x-diff; charset=us-asciiDownload
From cef05e2a2b8aa70fa43496e3fdd6e0c5a0982e14 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 13 Jul 2023 10:14:47 +0900
Subject: [PATCH v2 4/4] Remove column for enum elements in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
enum elements for each wait event class:
- Camelcase event name used in pg_stat_activity.  There are now
unquoted.
- Description of the documentation.

The enum elements are generated from what is now the first column.
---
 .../activity/generate-wait_event_types.pl     |  24 +-
 .../utils/activity/wait_event_names.txt       | 503 +++++++++---------
 2 files changed, 266 insertions(+), 261 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f63c991051..1d2489f268 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -73,20 +73,24 @@ my @lines_sorted =
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventdescription, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  Camelcase strings like "FooBarName"
+	# are converted to WAIT_EVENT_FOO_BAR_NAME.
+	my $waiteventenumname = $waiteventdescription;
+	# Add underscores between sequences of lower-case and upper-case
+	# characters, then upper-case the whole.
+	$waiteventenumname =~ s/([a-z])([A-Z])/$1_$2/g;
+	$waiteventenumname = uc($waiteventenumname);
+	$waiteventenumname = "WAIT_EVENT_$waiteventenumname";
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index c4967e274e..20f58c5d25 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,10 +7,16 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "format in the system views" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
-#      typedef enum definitions for wait events.
+#      typedef enum definitions for wait events, generated from the first
+#      field.
 #
 #   src/backend/utils/activity/pgstat_wait_event.c
 #      C functions to get the wait event name based on the enum.
@@ -18,11 +24,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +45,19 @@
 
 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."
+ArchiverMain	"Waiting in main loop of archiver process."
+AutovacuumMain	"Waiting in main loop of autovacuum launcher process."
+BgwriterHibernate	"Waiting in background writer process, hibernating."
+BgwriterMain	"Waiting in main loop of background writer process."
+CheckpointerMain	"Waiting in main loop of checkpointer process."
+LogicalApplyMain	"Waiting in main loop of logical replication apply process."
+LogicalLauncherMain	"Waiting in main loop of logical replication launcher process."
+LogicalParallelApplyMain	"Waiting in main loop of logical replication parallel apply process."
+RecoveryWalStream	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SysloggerMain	"Waiting in main loop of syslogger process."
+WalReceiverMain	"Waiting in main loop of WAL receiver process."
+WalSenderMain	"Waiting in main loop of WAL sender process."
+WalWriterMain	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +70,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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	WalSenderWaitWal	"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."
+ClientRead	"Waiting to read data from the client."
+ClientWrite	"Waiting to write data to the client."
+GssOpenServer	"Waiting to read data from the client while establishing a GSSAPI session."
+LibpqwalreceiverConnect	"Waiting in WAL receiver to establish connection to remote server."
+LibpqwalreceiverReceive	"Waiting in WAL receiver to receive data from remote server."
+SslOpenServer	"Waiting for SSL while attempting connection."
+WalSenderWaitWal	"Waiting for WAL to be flushed in WAL sender process."
+WalSenderWriteData	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +89,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
+AppendReady	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ArchiveCleanupCommand	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ArchiveCommand	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BackendTermination	"Waiting for the termination of another backend."
+BackupWaitWalArchive	"Waiting for WAL files required for a backup to be successfully archived."
+BgworkerShutdown	"Waiting for background worker to shut down."
+BgworkerStartup	"Waiting for background worker to start up."
+BtreePage	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BufferIo	"Waiting for buffer I/O to complete."
+CheckpointDone	"Waiting for a checkpoint to complete."
+CheckpointStart	"Waiting for a checkpoint to start."
+ExecuteGather	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HashBatchAllocate	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HashBatchElect	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HashBatchLoad	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HashBuildAllocate	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HashBuildElect	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HashBuildHashInner	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HashBuildHashOuter	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HashGrowBatchesDecide	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesElect	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HashGrowBatchesFinish	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesReallocate	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HashGrowBatchesRepartition	"Waiting for other Parallel Hash participants to finish repartitioning."
+HashGrowBucketsElect	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HashGrowBucketsReallocate	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HashGrowBucketsReinsert	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LogicalApplySendData	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LogicalParallelApplyStateChange	"Waiting for a logical replication parallel apply process to change state."
+LogicalSyncData	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LogicalSyncStateChange	"Waiting for a logical replication remote server to change state."
+MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+MessageQueueSend	"Waiting to send bytes to a shared message queue."
+ParallelBitmapScan	"Waiting for parallel bitmap scan to become initialized."
+ParallelCreateIndexScan	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+ParallelFinish	"Waiting for parallel workers to finish computing."
+ProcarrayGroupUpdate	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+ProcSignalBarrier	"Waiting for a barrier event to be processed by all backends."
+Promote	"Waiting for standby promotion."
+RecoveryConflictSnapshot	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RecoveryConflictTablespace	"Waiting for recovery conflict resolution for dropping a tablespace."
+RecoveryEndCommand	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RecoveryPause	"Waiting for recovery to be resumed."
+ReplicationOriginDrop	"Waiting for a replication origin to become inactive so it can be dropped."
+ReplicationSlotDrop	"Waiting for a replication slot to become inactive so it can be dropped."
+RestoreCommand	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SafeSnapshot	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SyncRep	"Waiting for confirmation from a remote server during synchronous replication. Waiting to read or update information about the state of synchronous replication."
+WalReceiverExit	"Waiting for the WAL receiver to exit."
+WalReceiverWaitStart	"Waiting for startup process to send initial data for streaming replication."
+XactGroupUpdate	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +152,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BaseBackupThrottle	"Waiting during base backup when throttling activity."
+CheckpointWriteDelay	"Waiting between writes while performing a checkpoint."
+PgSleep	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RecoveryApplyDelay	"Waiting to apply WAL during recovery because of a delay setting."
+RecoveryRetrieveRetryInterval	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+RegisterSyncRequest	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SpinDelay	"Waiting while acquiring a contended spinlock."
+VacuumDelay	"Waiting in a cost-based vacuum delay point."
+VacuumTruncate	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +171,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
+BasebackupRead	"Waiting for base backup to read from a file."
+BasebackupSync	"Waiting for data written by a base backup to reach durable storage."
+BasebackupWrite	"Waiting for base backup to write to a file."
+BuffileRead	"Waiting for a read from a buffered file."
+BuffileWrite	"Waiting for a write to a buffered file."
+BuffileTruncate	"Waiting for a buffered file to be truncated."
+ControlFileRead	"Waiting for a read from the <filename>pg_control</filename> file."
+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."
+ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+ControlFileWrite	"Waiting for a write to the <filename>pg_control</filename> file. Waiting for a write to update the <filename>pg_control</filename> file."
+ControlFileWriteUpdate	"Waiting for a write to update the <filename>pg_control</filename> file."
+CopyFileRead	"Waiting for a read during a file copy operation."
+CopyFileWrite	"Waiting for a write during a file copy operation."
+DataFileExtend	"Waiting for a relation data file to be extended."
+DataFileFlush	"Waiting for a relation data file to reach durable storage."
+DataFileImmediateSync	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DataFilePrefetch	"Waiting for an asynchronous prefetch from a relation data file."
+DataFileRead	"Waiting for a read from a relation data file."
+DataFileSync	"Waiting for changes to a relation data file to reach durable storage."
+DataFileTruncate	"Waiting for a relation data file to be truncated."
+DataFileWrite	"Waiting for a write to a relation data file."
+DsmAllocate	"Waiting for a dynamic shared memory segment to be allocated."
+DsmFillZeroWrite	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LockFileAddtodatadirRead	"Waiting for a read while adding a line to the data directory lock file."
+LockFileAddtodatadirSync	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LockFileAddtodatadirWrite	"Waiting for a write while adding a line to the data directory lock file."
+LockFileCreateRead	"Waiting to read while creating the data directory lock file."
+LockFileCreateSync	"Waiting for data to reach durable storage while creating the data directory lock file."
+LockFileCreateWrite	"Waiting for a write while creating the data directory lock file."
+LockFileRecheckdatadirRead	"Waiting for a read during recheck of the data directory lock file."
+LogicalRewriteCheckpointSync	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LogicalRewriteMappingSync	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LogicalRewriteMappingWrite	"Waiting for a write of mapping data during a logical rewrite."
+LogicalRewriteSync	"Waiting for logical rewrite mappings to reach durable storage."
+LogicalRewriteTruncate	"Waiting for truncate of mapping data during a logical rewrite."
+LogicalRewriteWrite	"Waiting for a write of logical rewrite mappings."
+RelationMapRead	"Waiting for a read of the relation map file."
+RelationMapReplace	"Waiting for durable replacement of a relation map file."
+RelationMapWrite	"Waiting for a write to the relation map file."
+ReorderBufferRead	"Waiting for a read during reorder buffer management."
+ReorderBufferWrite	"Waiting for a write during reorder buffer management."
+ReorderLogicalMappingRead	"Waiting for a read of a logical mapping during reorder buffer management."
+ReplicationSlotRead	"Waiting for a read from a replication slot control file."
+ReplicationSlotRestoreSync	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+ReplicationSlotSync	"Waiting for a replication slot control file to reach durable storage."
+ReplicationSlotWrite	"Waiting for a write to a replication slot control file."
+SlruFlushSync	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SlruRead	"Waiting for a read of an SLRU page."
+SlruSync	"Waiting for SLRU data to reach durable storage following a page write."
+SlruWrite	"Waiting for a write of an SLRU page."
+SnapbuildRead	"Waiting for a read of a serialized historical catalog snapshot."
+SnapbuildSync	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SnapbuildWrite	"Waiting for a write of a serialized historical catalog snapshot."
+TimelineHistoryFileSync	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TimelineHistoryFileWrite	"Waiting for a write of a timeline history file received via streaming replication."
+TimelineHistoryRead	"Waiting for a read of a timeline history file."
+TimelineHistorySync	"Waiting for a newly created timeline history file to reach durable storage."
+TimelineHistoryWrite	"Waiting for a write of a newly created timeline history file."
+TwophaseFileRead	"Waiting for a read of a two phase state file."
+TwophaseFileSync	"Waiting for a two phase state file to reach durable storage."
+TwophaseFileWrite	"Waiting for a write of a two phase state file."
+VersionFileWrite	"Waiting for the version file to be written while creating a database."
+WalsenderTimelineHistoryRead	"Waiting for a read from a timeline history file during a walsender timeline command."
+WalBootstrapSync	"Waiting for WAL to reach durable storage during bootstrapping."
+WalBootstrapWrite	"Waiting for a write of a WAL page during bootstrapping."
+WalCopyRead	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WalCopySync	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WalCopyWrite	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WalInitSync	"Waiting for a newly initialized WAL file to reach durable storage."
+WalInitWrite	"Waiting for a write while initializing a new WAL file."
+WalRead	"Waiting for a read from a WAL file."
+WalSync	"Waiting for a WAL file to reach durable storage. Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalSyncMethodAssign	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalWrite	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
 
 
 #
@@ -252,7 +253,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file. Waiting for WA
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BufferPin	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +262,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_EXTENSION	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait events - LWLock
@@ -272,81 +273,81 @@ WAIT_EVENT_EXTENSION	Extension	"Waiting in an extension."
 
 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."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
 
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait even - Lock
@@ -357,15 +358,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#46Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#45)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Thu, Jul 13, 2023 at 10:26:54AM +0900, Michael Paquier wrote:

I would like to apply 0001 and 0002 to improve the format if there are
no objections. 0003 and 0004 are still here for discussion, as it
does not seem like a consensus has been reached for that yet. Getting
more opinions would be a good next step for the last two patches, I
assume.

I have looked again at 0001 and 0002 and applied them to get them out
of the way. 0003 and 0004 are rebased and attached. I'll add them to
the CF for later consideration. More opinions are welcome.
--
Michael

Attachments:

v3-0003-Rename-wait-events-with-more-consistent-camelcase.patchtext/x-diff; charset=us-asciiDownload
From e4c2ae8d0879c1839d1873522155162e49f50788 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Sun, 9 Jul 2023 13:24:54 +0900
Subject: [PATCH v3 3/4] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 3 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 39e77ef945..87b8570a42 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 3fabad96d9..c4967e274e 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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	WalSenderWaitWal	"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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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_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."
 
 
 #
-- 
2.40.1

v3-0004-Remove-column-for-enum-elements-in-wait_event_nam.patchtext/x-diff; charset=us-asciiDownload
From b6390183bdcc054df82279bb0b2991730f85a0a3 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 13 Jul 2023 10:14:47 +0900
Subject: [PATCH v3 4/4] Remove column for enum elements in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
enum elements for each wait event class:
- Camelcase event name used in pg_stat_activity.  There are now
unquoted.
- Description of the documentation.

The enum elements are generated from what is now the first column.
---
 .../activity/generate-wait_event_types.pl     |  24 +-
 .../utils/activity/wait_event_names.txt       | 503 +++++++++---------
 2 files changed, 266 insertions(+), 261 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f63c991051..1d2489f268 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -73,20 +73,24 @@ my @lines_sorted =
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventdescription, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  Camelcase strings like "FooBarName"
+	# are converted to WAIT_EVENT_FOO_BAR_NAME.
+	my $waiteventenumname = $waiteventdescription;
+	# Add underscores between sequences of lower-case and upper-case
+	# characters, then upper-case the whole.
+	$waiteventenumname =~ s/([a-z])([A-Z])/$1_$2/g;
+	$waiteventenumname = uc($waiteventenumname);
+	$waiteventenumname = "WAIT_EVENT_$waiteventenumname";
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index c4967e274e..20f58c5d25 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,10 +7,16 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "format in the system views" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
-#      typedef enum definitions for wait events.
+#      typedef enum definitions for wait events, generated from the first
+#      field.
 #
 #   src/backend/utils/activity/pgstat_wait_event.c
 #      C functions to get the wait event name based on the enum.
@@ -18,11 +24,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +45,19 @@
 
 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."
+ArchiverMain	"Waiting in main loop of archiver process."
+AutovacuumMain	"Waiting in main loop of autovacuum launcher process."
+BgwriterHibernate	"Waiting in background writer process, hibernating."
+BgwriterMain	"Waiting in main loop of background writer process."
+CheckpointerMain	"Waiting in main loop of checkpointer process."
+LogicalApplyMain	"Waiting in main loop of logical replication apply process."
+LogicalLauncherMain	"Waiting in main loop of logical replication launcher process."
+LogicalParallelApplyMain	"Waiting in main loop of logical replication parallel apply process."
+RecoveryWalStream	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SysloggerMain	"Waiting in main loop of syslogger process."
+WalReceiverMain	"Waiting in main loop of WAL receiver process."
+WalSenderMain	"Waiting in main loop of WAL sender process."
+WalWriterMain	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +70,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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	WalSenderWaitWal	"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."
+ClientRead	"Waiting to read data from the client."
+ClientWrite	"Waiting to write data to the client."
+GssOpenServer	"Waiting to read data from the client while establishing a GSSAPI session."
+LibpqwalreceiverConnect	"Waiting in WAL receiver to establish connection to remote server."
+LibpqwalreceiverReceive	"Waiting in WAL receiver to receive data from remote server."
+SslOpenServer	"Waiting for SSL while attempting connection."
+WalSenderWaitWal	"Waiting for WAL to be flushed in WAL sender process."
+WalSenderWriteData	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +89,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
+AppendReady	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ArchiveCleanupCommand	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ArchiveCommand	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BackendTermination	"Waiting for the termination of another backend."
+BackupWaitWalArchive	"Waiting for WAL files required for a backup to be successfully archived."
+BgworkerShutdown	"Waiting for background worker to shut down."
+BgworkerStartup	"Waiting for background worker to start up."
+BtreePage	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BufferIo	"Waiting for buffer I/O to complete."
+CheckpointDone	"Waiting for a checkpoint to complete."
+CheckpointStart	"Waiting for a checkpoint to start."
+ExecuteGather	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HashBatchAllocate	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HashBatchElect	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HashBatchLoad	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HashBuildAllocate	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HashBuildElect	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HashBuildHashInner	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HashBuildHashOuter	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HashGrowBatchesDecide	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesElect	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HashGrowBatchesFinish	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HashGrowBatchesReallocate	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HashGrowBatchesRepartition	"Waiting for other Parallel Hash participants to finish repartitioning."
+HashGrowBucketsElect	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HashGrowBucketsReallocate	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HashGrowBucketsReinsert	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LogicalApplySendData	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LogicalParallelApplyStateChange	"Waiting for a logical replication parallel apply process to change state."
+LogicalSyncData	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LogicalSyncStateChange	"Waiting for a logical replication remote server to change state."
+MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+MessageQueueSend	"Waiting to send bytes to a shared message queue."
+ParallelBitmapScan	"Waiting for parallel bitmap scan to become initialized."
+ParallelCreateIndexScan	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+ParallelFinish	"Waiting for parallel workers to finish computing."
+ProcarrayGroupUpdate	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+ProcSignalBarrier	"Waiting for a barrier event to be processed by all backends."
+Promote	"Waiting for standby promotion."
+RecoveryConflictSnapshot	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RecoveryConflictTablespace	"Waiting for recovery conflict resolution for dropping a tablespace."
+RecoveryEndCommand	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RecoveryPause	"Waiting for recovery to be resumed."
+ReplicationOriginDrop	"Waiting for a replication origin to become inactive so it can be dropped."
+ReplicationSlotDrop	"Waiting for a replication slot to become inactive so it can be dropped."
+RestoreCommand	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SafeSnapshot	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SyncRep	"Waiting for confirmation from a remote server during synchronous replication. Waiting to read or update information about the state of synchronous replication."
+WalReceiverExit	"Waiting for the WAL receiver to exit."
+WalReceiverWaitStart	"Waiting for startup process to send initial data for streaming replication."
+XactGroupUpdate	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +152,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BaseBackupThrottle	"Waiting during base backup when throttling activity."
+CheckpointWriteDelay	"Waiting between writes while performing a checkpoint."
+PgSleep	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RecoveryApplyDelay	"Waiting to apply WAL during recovery because of a delay setting."
+RecoveryRetrieveRetryInterval	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+RegisterSyncRequest	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SpinDelay	"Waiting while acquiring a contended spinlock."
+VacuumDelay	"Waiting in a cost-based vacuum delay point."
+VacuumTruncate	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +171,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
+BasebackupRead	"Waiting for base backup to read from a file."
+BasebackupSync	"Waiting for data written by a base backup to reach durable storage."
+BasebackupWrite	"Waiting for base backup to write to a file."
+BuffileRead	"Waiting for a read from a buffered file."
+BuffileWrite	"Waiting for a write to a buffered file."
+BuffileTruncate	"Waiting for a buffered file to be truncated."
+ControlFileRead	"Waiting for a read from the <filename>pg_control</filename> file."
+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."
+ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+ControlFileWrite	"Waiting for a write to the <filename>pg_control</filename> file. Waiting for a write to update the <filename>pg_control</filename> file."
+ControlFileWriteUpdate	"Waiting for a write to update the <filename>pg_control</filename> file."
+CopyFileRead	"Waiting for a read during a file copy operation."
+CopyFileWrite	"Waiting for a write during a file copy operation."
+DataFileExtend	"Waiting for a relation data file to be extended."
+DataFileFlush	"Waiting for a relation data file to reach durable storage."
+DataFileImmediateSync	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DataFilePrefetch	"Waiting for an asynchronous prefetch from a relation data file."
+DataFileRead	"Waiting for a read from a relation data file."
+DataFileSync	"Waiting for changes to a relation data file to reach durable storage."
+DataFileTruncate	"Waiting for a relation data file to be truncated."
+DataFileWrite	"Waiting for a write to a relation data file."
+DsmAllocate	"Waiting for a dynamic shared memory segment to be allocated."
+DsmFillZeroWrite	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LockFileAddtodatadirRead	"Waiting for a read while adding a line to the data directory lock file."
+LockFileAddtodatadirSync	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LockFileAddtodatadirWrite	"Waiting for a write while adding a line to the data directory lock file."
+LockFileCreateRead	"Waiting to read while creating the data directory lock file."
+LockFileCreateSync	"Waiting for data to reach durable storage while creating the data directory lock file."
+LockFileCreateWrite	"Waiting for a write while creating the data directory lock file."
+LockFileRecheckdatadirRead	"Waiting for a read during recheck of the data directory lock file."
+LogicalRewriteCheckpointSync	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LogicalRewriteMappingSync	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LogicalRewriteMappingWrite	"Waiting for a write of mapping data during a logical rewrite."
+LogicalRewriteSync	"Waiting for logical rewrite mappings to reach durable storage."
+LogicalRewriteTruncate	"Waiting for truncate of mapping data during a logical rewrite."
+LogicalRewriteWrite	"Waiting for a write of logical rewrite mappings."
+RelationMapRead	"Waiting for a read of the relation map file."
+RelationMapReplace	"Waiting for durable replacement of a relation map file."
+RelationMapWrite	"Waiting for a write to the relation map file."
+ReorderBufferRead	"Waiting for a read during reorder buffer management."
+ReorderBufferWrite	"Waiting for a write during reorder buffer management."
+ReorderLogicalMappingRead	"Waiting for a read of a logical mapping during reorder buffer management."
+ReplicationSlotRead	"Waiting for a read from a replication slot control file."
+ReplicationSlotRestoreSync	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+ReplicationSlotSync	"Waiting for a replication slot control file to reach durable storage."
+ReplicationSlotWrite	"Waiting for a write to a replication slot control file."
+SlruFlushSync	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SlruRead	"Waiting for a read of an SLRU page."
+SlruSync	"Waiting for SLRU data to reach durable storage following a page write."
+SlruWrite	"Waiting for a write of an SLRU page."
+SnapbuildRead	"Waiting for a read of a serialized historical catalog snapshot."
+SnapbuildSync	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SnapbuildWrite	"Waiting for a write of a serialized historical catalog snapshot."
+TimelineHistoryFileSync	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TimelineHistoryFileWrite	"Waiting for a write of a timeline history file received via streaming replication."
+TimelineHistoryRead	"Waiting for a read of a timeline history file."
+TimelineHistorySync	"Waiting for a newly created timeline history file to reach durable storage."
+TimelineHistoryWrite	"Waiting for a write of a newly created timeline history file."
+TwophaseFileRead	"Waiting for a read of a two phase state file."
+TwophaseFileSync	"Waiting for a two phase state file to reach durable storage."
+TwophaseFileWrite	"Waiting for a write of a two phase state file."
+VersionFileWrite	"Waiting for the version file to be written while creating a database."
+WalsenderTimelineHistoryRead	"Waiting for a read from a timeline history file during a walsender timeline command."
+WalBootstrapSync	"Waiting for WAL to reach durable storage during bootstrapping."
+WalBootstrapWrite	"Waiting for a write of a WAL page during bootstrapping."
+WalCopyRead	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WalCopySync	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WalCopyWrite	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WalInitSync	"Waiting for a newly initialized WAL file to reach durable storage."
+WalInitWrite	"Waiting for a write while initializing a new WAL file."
+WalRead	"Waiting for a read from a WAL file."
+WalSync	"Waiting for a WAL file to reach durable storage. Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalSyncMethodAssign	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WalWrite	"Waiting for a write to a WAL file. Waiting for WAL buffers to be written to disk."
 
 
 #
@@ -252,7 +253,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file. Waiting for WA
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BufferPin	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +262,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_EXTENSION	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait events - LWLock
@@ -272,81 +273,81 @@ WAIT_EVENT_EXTENSION	Extension	"Waiting in an extension."
 
 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."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
 
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait even - Lock
@@ -357,15 +358,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#47Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#46)
Re: Autogenerate some wait events code and documentation

Hi,

On 2023-07-14 13:49:22 +0900, Michael Paquier wrote:

I have looked again at 0001 and 0002 and applied them to get them out
of the way. 0003 and 0004 are rebased and attached. I'll add them to
the CF for later consideration. More opinions are welcome.

From b6390183bdcc054df82279bb0b2991730f85a0a3 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 13 Jul 2023 10:14:47 +0900
Subject: [PATCH v3 4/4] Remove column for enum elements in
wait_event_names.txt

This file is now made of two columns, removing the column listing the
enum elements for each wait event class:
- Camelcase event name used in pg_stat_activity. There are now
unquoted.
- Description of the documentation.

The enum elements are generated from what is now the first column.

I think the search issue is valid, so I do think going the other way is
preferrable. I.e. use just the enum value in the .txt and generate the camel
case name from that. That allows you to search the define used in code and
find a hit in the file.

I personally would still leave off the WAIT_EVENT prefix in the .txt, I think
most of us can remember to chop that off.

I don't think we need to be particularly consistent with wait events across
major versions. They're necessarily tied to how the code works, and we've
yanked that around plenty.

Greetings,

Andres Freund

#48Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#47)
Re: Autogenerate some wait events code and documentation

On Sun, Jul 16, 2023 at 12:21:20PM -0700, Andres Freund wrote:

I think the search issue is valid, so I do think going the other way is
preferrable. I.e. use just the enum value in the .txt and generate the camel
case name from that. That allows you to search the define used in code and
find a hit in the file.

I personally would still leave off the WAIT_EVENT prefix in the .txt, I think
most of us can remember to chop that off.

So you mean to switch a line that now looks like that:
WAIT_EVENT_FOO_BAR FooBar "Waiting on Foo Bar."
To that:
FOO_BAR "Waiting on Foo Bar."
Or even that:
WAIT_EVENT_FOO_BAR "Waiting on Foo Bar."

Sure, it is an improvement for any wait events that use WAIT_EVENT_
when searching them, but this adds more magic into the LWLock and Lock
areas if the same conversion is applied there. Or am I right to
assume that you'd mean to *not* do any of that for these two classes?
These can be treated as exceptions in the script when generating the
wait event names from the enum elements, of course.

I don't think we need to be particularly consistent with wait events across
major versions. They're necessarily tied to how the code works, and we've
yanked that around plenty.

IMO, it depends on the code path involved. For example, I know of
some code that relies on SyncRep to track backends waiting on a sync
reply, and that's one sensible to keep compatible. I'd be sad if
something like that breaks suddenly after a major release.
--
Michael

#49Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#48)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Mon, Jul 17, 2023 at 10:16:02AM +0900, Michael Paquier wrote:

So you mean to switch a line that now looks like that:
WAIT_EVENT_FOO_BAR FooBar "Waiting on Foo Bar."
To that:
FOO_BAR "Waiting on Foo Bar."
Or even that:
WAIT_EVENT_FOO_BAR "Waiting on Foo Bar."

Sure, it is an improvement for any wait events that use WAIT_EVENT_
when searching them, but this adds more magic into the LWLock and Lock
areas if the same conversion is applied there. Or am I right to
assume that you'd mean to *not* do any of that for these two classes?
These can be treated as exceptions in the script when generating the
wait event names from the enum elements, of course.

I have looked again at that, and switching wait_event_names.txt to use
two columns made of the typedef definitions and the docs like is not a
problem:
FOO_BAR "Waiting on Foo Bar."

WAIT_EVENT_ is appended to the typedef definitions in the script. The
wait event names like "FooBar" are generated from the enums by
splitting using their underscores and doing some lc(). Lock and
LWLock don't need to change. This way, it is easy to grep the wait
events from the source code and match them with wait_event_names.txt.

Thoughts or comments?
--
Michael

Attachments:

v3-0001-Rename-wait-events-with-more-consistent-camelcase.patchtext/x-diff; charset=us-asciiDownload
From 794f8a95ae3b9d25f3293cbf063cf70c5e8f5197 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 28 Aug 2023 14:47:13 +0900
Subject: [PATCH v3 1/2] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 3 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 253181f47a..38b042804c 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 4d74f0068e..99ed44cbc8 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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	WalSenderWaitWal	"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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
 WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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."
-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."
+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."
+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."
 
 
 #
-- 
2.40.1

v3-0002-Remove-column-for-wait-event-names-in-wait_event_.patchtext/x-diff; charset=us-asciiDownload
From e4feeaba4e7ba06315e94735eefca88d65b8e616 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 28 Aug 2023 16:54:34 +0900
Subject: [PATCH v3 2/2] Remove column for wait event names in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
descriptions for each wait event class:
- Typedef enum definition, without the prefix "WAIT_EVENT_", for
simplicity.
- Description in the documentation.

The wait event names are generated from the enum objects in camelcase, with
the underscores removed.
---
 .../activity/generate-wait_event_types.pl     |  40 +-
 .../utils/activity/wait_event_names.txt       | 502 +++++++++---------
 2 files changed, 279 insertions(+), 263 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 23eb3b1f57..e533b6d96d 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -65,29 +65,45 @@ while (<$wait_event_names>)
 	push(@lines, $section_name . "\t" . $_);
 }
 
-# Sort the lines based on the third column.
+# Sort the lines based on the second column.
 # uc() is being used to force the comparison to be case-insensitive.
 my @lines_sorted =
-  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+  sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventname, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  The C symbols are prefixed with "WAIT_EVENT_".
+	my $waiteventenumname = "WAIT_EVENT_$waiteventname";
+
+	# Build the descriptions.  There are in camel-case.
+	# LWLock and Lock classes do not need any modifications.
+	my $waiteventdescription = '';
+	if ( $waitclassname eq 'WaitEventLWLock'
+	     || $waitclassname eq 'WaitEventLock')
+	{
+		$waiteventdescription = $waiteventname;
+	}
+	else
+	{
+		my @waiteventparts = split("_", $waiteventname);
+		foreach my $waiteventpart (@waiteventparts)
+		{
+		    $waiteventdescription .= substr($waiteventpart, 0, 1) .
+			lc(substr($waiteventpart, 1, length($waiteventpart)));
+		}
+	}
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 99ed44cbc8..2a34aa0689 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,6 +7,11 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "Typedef enum definitions" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
@@ -18,11 +23,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +44,19 @@
 
 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."
+ARCHIVER_MAIN	"Waiting in main loop of archiver process."
+AUTOVACUUM_MAIN	"Waiting in main loop of autovacuum launcher process."
+BGWRITER_HIBERNATE	"Waiting in background writer process, hibernating."
+BGWRITER_MAIN	"Waiting in main loop of background writer process."
+CHECKPOINTER_MAIN	"Waiting in main loop of checkpointer process."
+LOGICAL_APPLY_MAIN	"Waiting in main loop of logical replication apply process."
+LOGICAL_LAUNCHER_MAIN	"Waiting in main loop of logical replication launcher process."
+LOGICAL_PARALLEL_APPLY_MAIN	"Waiting in main loop of logical replication parallel apply process."
+RECOVERY_WAL_STREAM	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SYSLOGGER_MAIN	"Waiting in main loop of syslogger process."
+WAL_RECEIVER_MAIN	"Waiting in main loop of WAL receiver process."
+WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
+WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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	WalSenderWaitWal	"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."
+CLIENT_READ	"Waiting to read data from the client."
+CLIENT_WRITE	"Waiting to write data to the client."
+GSS_OPEN_SERVER	"Waiting to read data from the client while establishing a GSSAPI session."
+LIBPQWALRECEIVER_CONNECT	"Waiting in WAL receiver to establish connection to remote server."
+LIBPQWALRECEIVER_RECEIVE	"Waiting in WAL receiver to receive data from remote server."
+SSL_OPEN_SERVER	"Waiting for SSL while attempting connection."
+WAL_SENDER_WAIT_WAL	"Waiting for WAL to be flushed in WAL sender process."
+WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
-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."
+APPEND_READY	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ARCHIVE_CLEANUP_COMMAND	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ARCHIVE_COMMAND	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BACKEND_TERMINATION	"Waiting for the termination of another backend."
+BACKUP_WAIT_WAL_ARCHIVE	"Waiting for WAL files required for a backup to be successfully archived."
+BGWORKER_SHUTDOWN	"Waiting for background worker to shut down."
+BGWORKER_STARTUP	"Waiting for background worker to start up."
+BTREE_PAGE	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BUFFER_IO	"Waiting for buffer I/O to complete."
+CHECKPOINT_DONE	"Waiting for a checkpoint to complete."
+CHECKPOINT_START	"Waiting for a checkpoint to start."
+EXECUTE_GATHER	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HASH_BATCH_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HASH_BATCH_ELECT	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HASH_BATCH_LOAD	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HASH_BUILD_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_ELECT	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_HASH_INNER	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HASH_BUILD_HASH_OUTER	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HASH_GROW_BATCHES_DECIDE	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_ELECT	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_FINISH	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_REALLOCATE	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_REPARTITION	"Waiting for other Parallel Hash participants to finish repartitioning."
+HASH_GROW_BUCKETS_ELECT	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HASH_GROW_BUCKETS_REALLOCATE	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HASH_GROW_BUCKETS_REINSERT	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LOGICAL_APPLY_SEND_DATA	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"Waiting for a logical replication parallel apply process to change state."
+LOGICAL_SYNC_DATA	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LOGICAL_SYNC_STATE_CHANGE	"Waiting for a logical replication remote server to change state."
+MESSAGE_QUEUE_INTERNAL	"Waiting for another process to be attached to a shared message queue."
+MESSAGE_QUEUE_PUT_MESSAGE	"Waiting to write a protocol message to a shared message queue."
+MESSAGE_QUEUE_RECEIVE	"Waiting to receive bytes from a shared message queue."
+MESSAGE_QUEUE_SEND	"Waiting to send bytes to a shared message queue."
+PARALLEL_BITMAP_SCAN	"Waiting for parallel bitmap scan to become initialized."
+PARALLEL_CREATE_INDEX_SCAN	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+PARALLEL_FINISH	"Waiting for parallel workers to finish computing."
+PROCARRAY_GROUP_UPDATE	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+PROC_SIGNAL_BARRIER	"Waiting for a barrier event to be processed by all backends."
+PROMOTE	"Waiting for standby promotion."
+RECOVERY_CONFLICT_SNAPSHOT	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RECOVERY_CONFLICT_TABLESPACE	"Waiting for recovery conflict resolution for dropping a tablespace."
+RECOVERY_END_COMMAND	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RECOVERY_PAUSE	"Waiting for recovery to be resumed."
+REPLICATION_ORIGIN_DROP	"Waiting for a replication origin to become inactive so it can be dropped."
+REPLICATION_SLOT_DROP	"Waiting for a replication slot to become inactive so it can be dropped."
+RESTORE_COMMAND	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SAFE_SNAPSHOT	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SYNC_REP	"Waiting for confirmation from a remote server during synchronous replication."
+WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
+WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
+XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BASE_BACKUP_THROTTLE	"Waiting during base backup when throttling activity."
+CHECKPOINT_WRITE_DELAY	"Waiting between writes while performing a checkpoint."
+PG_SLEEP	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RECOVERY_APPLY_DELAY	"Waiting to apply WAL during recovery because of a delay setting."
+RECOVERY_RETRIEVE_RETRY_INTERVAL	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+REGISTER_SYNC_REQUEST	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SPIN_DELAY	"Waiting while acquiring a contended spinlock."
+VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
+VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
-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."
-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."
-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."
+BASEBACKUP_READ	"Waiting for base backup to read from a file."
+BASEBACKUP_SYNC	"Waiting for data written by a base backup to reach durable storage."
+BASEBACKUP_WRITE	"Waiting for base backup to write to a file."
+BUFFILE_READ	"Waiting for a read from a buffered file."
+BUFFILE_WRITE	"Waiting for a write to a buffered file."
+BUFFILE_TRUNCATE	"Waiting for a buffered file to be truncated."
+CONTROL_FILE_READ	"Waiting for a read from the <filename>pg_control</filename> file."
+CONTROL_FILE_SYNC	"Waiting for the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_SYNC_UPDATE	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_WRITE	"Waiting for a write to the <filename>pg_control</filename> file."
+CONTROL_FILE_WRITE_UPDATE	"Waiting for a write to update the <filename>pg_control</filename> file."
+COPY_FILE_READ	"Waiting for a read during a file copy operation."
+COPY_FILE_WRITE	"Waiting for a write during a file copy operation."
+DATA_FILE_EXTEND	"Waiting for a relation data file to be extended."
+DATA_FILE_FLUSH	"Waiting for a relation data file to reach durable storage."
+DATA_FILE_IMMEDIATE_SYNC	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DATA_FILE_PREFETCH	"Waiting for an asynchronous prefetch from a relation data file."
+DATA_FILE_READ	"Waiting for a read from a relation data file."
+DATA_FILE_SYNC	"Waiting for changes to a relation data file to reach durable storage."
+DATA_FILE_TRUNCATE	"Waiting for a relation data file to be truncated."
+DATA_FILE_WRITE	"Waiting for a write to a relation data file."
+DSM_ALLOCATE	"Waiting for a dynamic shared memory segment to be allocated."
+DSM_FILL_ZERO_WRITE	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LOCK_FILE_ADDTODATADIR_READ	"Waiting for a read while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_SYNC	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_WRITE	"Waiting for a write while adding a line to the data directory lock file."
+LOCK_FILE_CREATE_READ	"Waiting to read while creating the data directory lock file."
+LOCK_FILE_CREATE_SYNC	"Waiting for data to reach durable storage while creating the data directory lock file."
+LOCK_FILE_CREATE_WRITE	"Waiting for a write while creating the data directory lock file."
+LOCK_FILE_RECHECKDATADIR_READ	"Waiting for a read during recheck of the data directory lock file."
+LOGICAL_REWRITE_CHECKPOINT_SYNC	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LOGICAL_REWRITE_MAPPING_SYNC	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LOGICAL_REWRITE_MAPPING_WRITE	"Waiting for a write of mapping data during a logical rewrite."
+LOGICAL_REWRITE_SYNC	"Waiting for logical rewrite mappings to reach durable storage."
+LOGICAL_REWRITE_TRUNCATE	"Waiting for truncate of mapping data during a logical rewrite."
+LOGICAL_REWRITE_WRITE	"Waiting for a write of logical rewrite mappings."
+RELATION_MAP_READ	"Waiting for a read of the relation map file."
+RELATION_MAP_REPLACE	"Waiting for durable replacement of a relation map file."
+RELATION_MAP_WRITE	"Waiting for a write to the relation map file."
+REORDER_BUFFER_READ	"Waiting for a read during reorder buffer management."
+REORDER_BUFFER_WRITE	"Waiting for a write during reorder buffer management."
+REORDER_LOGICAL_MAPPING_READ	"Waiting for a read of a logical mapping during reorder buffer management."
+REPLICATION_SLOT_READ	"Waiting for a read from a replication slot control file."
+REPLICATION_SLOT_RESTORE_SYNC	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+REPLICATION_SLOT_SYNC	"Waiting for a replication slot control file to reach durable storage."
+REPLICATION_SLOT_WRITE	"Waiting for a write to a replication slot control file."
+SLRU_FLUSH_SYNC	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SLRU_READ	"Waiting for a read of an SLRU page."
+SLRU_SYNC	"Waiting for SLRU data to reach durable storage following a page write."
+SLRU_WRITE	"Waiting for a write of an SLRU page."
+SNAPBUILD_READ	"Waiting for a read of a serialized historical catalog snapshot."
+SNAPBUILD_SYNC	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SNAPBUILD_WRITE	"Waiting for a write of a serialized historical catalog snapshot."
+TIMELINE_HISTORY_FILE_SYNC	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TIMELINE_HISTORY_FILE_WRITE	"Waiting for a write of a timeline history file received via streaming replication."
+TIMELINE_HISTORY_READ	"Waiting for a read of a timeline history file."
+TIMELINE_HISTORY_SYNC	"Waiting for a newly created timeline history file to reach durable storage."
+TIMELINE_HISTORY_WRITE	"Waiting for a write of a newly created timeline history file."
+TWOPHASE_FILE_READ	"Waiting for a read of a two phase state file."
+TWOPHASE_FILE_SYNC	"Waiting for a two phase state file to reach durable storage."
+TWOPHASE_FILE_WRITE	"Waiting for a write of a two phase state file."
+VERSION_FILE_WRITE	"Waiting for the version file to be written while creating a database."
+WALSENDER_TIMELINE_HISTORY_READ	"Waiting for a read from a timeline history file during a walsender timeline command."
+WAL_BOOTSTRAP_SYNC	"Waiting for WAL to reach durable storage during bootstrapping."
+WAL_BOOTSTRAP_WRITE	"Waiting for a write of a WAL page during bootstrapping."
+WAL_COPY_READ	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WAL_COPY_SYNC	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WAL_COPY_WRITE	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WAL_INIT_SYNC	"Waiting for a newly initialized WAL file to reach durable storage."
+WAL_INIT_WRITE	"Waiting for a write while initializing a new WAL file."
+WAL_READ	"Waiting for a read from a WAL file."
+WAL_SYNC	"Waiting for a WAL file to reach durable storage."
+WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAL_WRITE	"Waiting for a write to a WAL file."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file."
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait events - LWLock
@@ -272,82 +272,82 @@ WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
 
 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_EVENT_DOCONLY	WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
+WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
 
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait even - Lock
@@ -358,15 +358,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#50Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#49)
Re: Autogenerate some wait events code and documentation

Hi,

On 8/28/23 10:04 AM, Michael Paquier wrote:

On Mon, Jul 17, 2023 at 10:16:02AM +0900, Michael Paquier wrote:

So you mean to switch a line that now looks like that:
WAIT_EVENT_FOO_BAR FooBar "Waiting on Foo Bar."
To that:
FOO_BAR "Waiting on Foo Bar."
Or even that:
WAIT_EVENT_FOO_BAR "Waiting on Foo Bar."

Sure, it is an improvement for any wait events that use WAIT_EVENT_
when searching them, but this adds more magic into the LWLock and Lock
areas if the same conversion is applied there. Or am I right to
assume that you'd mean to *not* do any of that for these two classes?
These can be treated as exceptions in the script when generating the
wait event names from the enum elements, of course.

I have looked again at that, and switching wait_event_names.txt to use
two columns made of the typedef definitions and the docs like is not a
problem:
FOO_BAR "Waiting on Foo Bar."

WAIT_EVENT_ is appended to the typedef definitions in the script. The
wait event names like "FooBar" are generated from the enums by
splitting using their underscores and doing some lc(). Lock and
LWLock don't need to change. This way, it is easy to grep the wait
events from the source code and match them with wait_event_names.txt.

Thoughts or comments?

Agree that done that way one could easily grep the events from the source code and
match them with wait_event_names.txt. Then I don't think the "search" issue in the code
is still a concern with the current proposal.

FWIW, I'm getting:

$ git am v3-000*
Applying: Rename wait events with more consistent camelcase style
Applying: Remove column for wait event names in wait_event_names.txt
error: patch failed: src/backend/utils/activity/wait_event_names.txt:261
error: src/backend/utils/activity/wait_event_names.txt: patch does not apply
Patch failed at 0002 Remove column for wait event names in wait_event_names.txt

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#51Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#50)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Tue, Aug 29, 2023 at 08:17:10AM +0200, Drouvot, Bertrand wrote:

Agree that done that way one could easily grep the events from the
source code and match them with wait_event_names.txt. Then I don't
think the "search" issue in the code is still a concern with the
current proposal.

It could still be able to append WAIT_EVENT_ to the first column of
the file. I'd just rather keep it shorter.

FWIW, I'm getting:

$ git am v3-000*
Applying: Rename wait events with more consistent camelcase style
Applying: Remove column for wait event names in wait_event_names.txt
error: patch failed: src/backend/utils/activity/wait_event_names.txt:261
error: src/backend/utils/activity/wait_event_names.txt: patch does not apply
Patch failed at 0002 Remove column for wait event names in wait_event_names.txt

That may be a bug in the matrix because of bb90022, as git am can be
easily pissed. I am attaching a new patch series, but it does not
seem to matter here.

I have double-checked the docs generated, while on it, and I am not
seeing anything missing, particularly for the LWLock and Lock parts..
--
Michael

Attachments:

v4-0001-Rename-wait-events-with-more-consistent-camelcase.patchtext/x-diff; charset=us-asciiDownload
From 7e221db0fe26f9d36df90202934f4177daa86ff7 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 28 Aug 2023 14:47:13 +0900
Subject: [PATCH v4 1/2] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 3 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 253181f47a..38b042804c 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 13774254d2..0cace8f40a 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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	WalSenderWaitWal	"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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
 WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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."
-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."
+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."
+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."
 
 
 #
-- 
2.40.1

v4-0002-Remove-column-for-wait-event-names-in-wait_event_.patchtext/x-diff; charset=us-asciiDownload
From ab2edc5ed12476010de2944e8c0f399ccf9461b8 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 28 Aug 2023 16:54:34 +0900
Subject: [PATCH v4 2/2] Remove column for wait event names in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
descriptions for each wait event class:
- Typedef enum definition, without the prefix "WAIT_EVENT_", for
simplicity.
- Description in the documentation.

The wait event names are generated from the enum objects in camelcase, with
the underscores removed.
---
 .../activity/generate-wait_event_types.pl     |  40 +-
 .../utils/activity/wait_event_names.txt       | 502 +++++++++---------
 2 files changed, 279 insertions(+), 263 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 23eb3b1f57..e533b6d96d 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -65,29 +65,45 @@ while (<$wait_event_names>)
 	push(@lines, $section_name . "\t" . $_);
 }
 
-# Sort the lines based on the third column.
+# Sort the lines based on the second column.
 # uc() is being used to force the comparison to be case-insensitive.
 my @lines_sorted =
-  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+  sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventname, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  The C symbols are prefixed with "WAIT_EVENT_".
+	my $waiteventenumname = "WAIT_EVENT_$waiteventname";
+
+	# Build the descriptions.  There are in camel-case.
+	# LWLock and Lock classes do not need any modifications.
+	my $waiteventdescription = '';
+	if ( $waitclassname eq 'WaitEventLWLock'
+	     || $waitclassname eq 'WaitEventLock')
+	{
+		$waiteventdescription = $waiteventname;
+	}
+	else
+	{
+		my @waiteventparts = split("_", $waiteventname);
+		foreach my $waiteventpart (@waiteventparts)
+		{
+		    $waiteventdescription .= substr($waiteventpart, 0, 1) .
+			lc(substr($waiteventpart, 1, length($waiteventpart)));
+		}
+	}
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0cace8f40a..2642ef2537 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,6 +7,11 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "Typedef enum definitions" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
@@ -18,11 +23,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +44,19 @@
 
 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."
+ARCHIVER_MAIN	"Waiting in main loop of archiver process."
+AUTOVACUUM_MAIN	"Waiting in main loop of autovacuum launcher process."
+BGWRITER_HIBERNATE	"Waiting in background writer process, hibernating."
+BGWRITER_MAIN	"Waiting in main loop of background writer process."
+CHECKPOINTER_MAIN	"Waiting in main loop of checkpointer process."
+LOGICAL_APPLY_MAIN	"Waiting in main loop of logical replication apply process."
+LOGICAL_LAUNCHER_MAIN	"Waiting in main loop of logical replication launcher process."
+LOGICAL_PARALLEL_APPLY_MAIN	"Waiting in main loop of logical replication parallel apply process."
+RECOVERY_WAL_STREAM	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SYSLOGGER_MAIN	"Waiting in main loop of syslogger process."
+WAL_RECEIVER_MAIN	"Waiting in main loop of WAL receiver process."
+WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
+WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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	WalSenderWaitWal	"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."
+CLIENT_READ	"Waiting to read data from the client."
+CLIENT_WRITE	"Waiting to write data to the client."
+GSS_OPEN_SERVER	"Waiting to read data from the client while establishing a GSSAPI session."
+LIBPQWALRECEIVER_CONNECT	"Waiting in WAL receiver to establish connection to remote server."
+LIBPQWALRECEIVER_RECEIVE	"Waiting in WAL receiver to receive data from remote server."
+SSL_OPEN_SERVER	"Waiting for SSL while attempting connection."
+WAL_SENDER_WAIT_WAL	"Waiting for WAL to be flushed in WAL sender process."
+WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
-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."
+APPEND_READY	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ARCHIVE_CLEANUP_COMMAND	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ARCHIVE_COMMAND	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BACKEND_TERMINATION	"Waiting for the termination of another backend."
+BACKUP_WAIT_WAL_ARCHIVE	"Waiting for WAL files required for a backup to be successfully archived."
+BGWORKER_SHUTDOWN	"Waiting for background worker to shut down."
+BGWORKER_STARTUP	"Waiting for background worker to start up."
+BTREE_PAGE	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BUFFER_IO	"Waiting for buffer I/O to complete."
+CHECKPOINT_DONE	"Waiting for a checkpoint to complete."
+CHECKPOINT_START	"Waiting for a checkpoint to start."
+EXECUTE_GATHER	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HASH_BATCH_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HASH_BATCH_ELECT	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HASH_BATCH_LOAD	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HASH_BUILD_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_ELECT	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_HASH_INNER	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HASH_BUILD_HASH_OUTER	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HASH_GROW_BATCHES_DECIDE	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_ELECT	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_FINISH	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_REALLOCATE	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_REPARTITION	"Waiting for other Parallel Hash participants to finish repartitioning."
+HASH_GROW_BUCKETS_ELECT	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HASH_GROW_BUCKETS_REALLOCATE	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HASH_GROW_BUCKETS_REINSERT	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LOGICAL_APPLY_SEND_DATA	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"Waiting for a logical replication parallel apply process to change state."
+LOGICAL_SYNC_DATA	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LOGICAL_SYNC_STATE_CHANGE	"Waiting for a logical replication remote server to change state."
+MESSAGE_QUEUE_INTERNAL	"Waiting for another process to be attached to a shared message queue."
+MESSAGE_QUEUE_PUT_MESSAGE	"Waiting to write a protocol message to a shared message queue."
+MESSAGE_QUEUE_RECEIVE	"Waiting to receive bytes from a shared message queue."
+MESSAGE_QUEUE_SEND	"Waiting to send bytes to a shared message queue."
+PARALLEL_BITMAP_SCAN	"Waiting for parallel bitmap scan to become initialized."
+PARALLEL_CREATE_INDEX_SCAN	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+PARALLEL_FINISH	"Waiting for parallel workers to finish computing."
+PROCARRAY_GROUP_UPDATE	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+PROC_SIGNAL_BARRIER	"Waiting for a barrier event to be processed by all backends."
+PROMOTE	"Waiting for standby promotion."
+RECOVERY_CONFLICT_SNAPSHOT	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RECOVERY_CONFLICT_TABLESPACE	"Waiting for recovery conflict resolution for dropping a tablespace."
+RECOVERY_END_COMMAND	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RECOVERY_PAUSE	"Waiting for recovery to be resumed."
+REPLICATION_ORIGIN_DROP	"Waiting for a replication origin to become inactive so it can be dropped."
+REPLICATION_SLOT_DROP	"Waiting for a replication slot to become inactive so it can be dropped."
+RESTORE_COMMAND	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SAFE_SNAPSHOT	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SYNC_REP	"Waiting for confirmation from a remote server during synchronous replication."
+WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
+WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
+XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BASE_BACKUP_THROTTLE	"Waiting during base backup when throttling activity."
+CHECKPOINT_WRITE_DELAY	"Waiting between writes while performing a checkpoint."
+PG_SLEEP	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RECOVERY_APPLY_DELAY	"Waiting to apply WAL during recovery because of a delay setting."
+RECOVERY_RETRIEVE_RETRY_INTERVAL	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+REGISTER_SYNC_REQUEST	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SPIN_DELAY	"Waiting while acquiring a contended spinlock."
+VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
+VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
-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."
-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."
-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."
+BASEBACKUP_READ	"Waiting for base backup to read from a file."
+BASEBACKUP_SYNC	"Waiting for data written by a base backup to reach durable storage."
+BASEBACKUP_WRITE	"Waiting for base backup to write to a file."
+BUFFILE_READ	"Waiting for a read from a buffered file."
+BUFFILE_WRITE	"Waiting for a write to a buffered file."
+BUFFILE_TRUNCATE	"Waiting for a buffered file to be truncated."
+CONTROL_FILE_READ	"Waiting for a read from the <filename>pg_control</filename> file."
+CONTROL_FILE_SYNC	"Waiting for the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_SYNC_UPDATE	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_WRITE	"Waiting for a write to the <filename>pg_control</filename> file."
+CONTROL_FILE_WRITE_UPDATE	"Waiting for a write to update the <filename>pg_control</filename> file."
+COPY_FILE_READ	"Waiting for a read during a file copy operation."
+COPY_FILE_WRITE	"Waiting for a write during a file copy operation."
+DATA_FILE_EXTEND	"Waiting for a relation data file to be extended."
+DATA_FILE_FLUSH	"Waiting for a relation data file to reach durable storage."
+DATA_FILE_IMMEDIATE_SYNC	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DATA_FILE_PREFETCH	"Waiting for an asynchronous prefetch from a relation data file."
+DATA_FILE_READ	"Waiting for a read from a relation data file."
+DATA_FILE_SYNC	"Waiting for changes to a relation data file to reach durable storage."
+DATA_FILE_TRUNCATE	"Waiting for a relation data file to be truncated."
+DATA_FILE_WRITE	"Waiting for a write to a relation data file."
+DSM_ALLOCATE	"Waiting for a dynamic shared memory segment to be allocated."
+DSM_FILL_ZERO_WRITE	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LOCK_FILE_ADDTODATADIR_READ	"Waiting for a read while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_SYNC	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_WRITE	"Waiting for a write while adding a line to the data directory lock file."
+LOCK_FILE_CREATE_READ	"Waiting to read while creating the data directory lock file."
+LOCK_FILE_CREATE_SYNC	"Waiting for data to reach durable storage while creating the data directory lock file."
+LOCK_FILE_CREATE_WRITE	"Waiting for a write while creating the data directory lock file."
+LOCK_FILE_RECHECKDATADIR_READ	"Waiting for a read during recheck of the data directory lock file."
+LOGICAL_REWRITE_CHECKPOINT_SYNC	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LOGICAL_REWRITE_MAPPING_SYNC	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LOGICAL_REWRITE_MAPPING_WRITE	"Waiting for a write of mapping data during a logical rewrite."
+LOGICAL_REWRITE_SYNC	"Waiting for logical rewrite mappings to reach durable storage."
+LOGICAL_REWRITE_TRUNCATE	"Waiting for truncate of mapping data during a logical rewrite."
+LOGICAL_REWRITE_WRITE	"Waiting for a write of logical rewrite mappings."
+RELATION_MAP_READ	"Waiting for a read of the relation map file."
+RELATION_MAP_REPLACE	"Waiting for durable replacement of a relation map file."
+RELATION_MAP_WRITE	"Waiting for a write to the relation map file."
+REORDER_BUFFER_READ	"Waiting for a read during reorder buffer management."
+REORDER_BUFFER_WRITE	"Waiting for a write during reorder buffer management."
+REORDER_LOGICAL_MAPPING_READ	"Waiting for a read of a logical mapping during reorder buffer management."
+REPLICATION_SLOT_READ	"Waiting for a read from a replication slot control file."
+REPLICATION_SLOT_RESTORE_SYNC	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+REPLICATION_SLOT_SYNC	"Waiting for a replication slot control file to reach durable storage."
+REPLICATION_SLOT_WRITE	"Waiting for a write to a replication slot control file."
+SLRU_FLUSH_SYNC	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SLRU_READ	"Waiting for a read of an SLRU page."
+SLRU_SYNC	"Waiting for SLRU data to reach durable storage following a page write."
+SLRU_WRITE	"Waiting for a write of an SLRU page."
+SNAPBUILD_READ	"Waiting for a read of a serialized historical catalog snapshot."
+SNAPBUILD_SYNC	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SNAPBUILD_WRITE	"Waiting for a write of a serialized historical catalog snapshot."
+TIMELINE_HISTORY_FILE_SYNC	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TIMELINE_HISTORY_FILE_WRITE	"Waiting for a write of a timeline history file received via streaming replication."
+TIMELINE_HISTORY_READ	"Waiting for a read of a timeline history file."
+TIMELINE_HISTORY_SYNC	"Waiting for a newly created timeline history file to reach durable storage."
+TIMELINE_HISTORY_WRITE	"Waiting for a write of a newly created timeline history file."
+TWOPHASE_FILE_READ	"Waiting for a read of a two phase state file."
+TWOPHASE_FILE_SYNC	"Waiting for a two phase state file to reach durable storage."
+TWOPHASE_FILE_WRITE	"Waiting for a write of a two phase state file."
+VERSION_FILE_WRITE	"Waiting for the version file to be written while creating a database."
+WALSENDER_TIMELINE_HISTORY_READ	"Waiting for a read from a timeline history file during a walsender timeline command."
+WAL_BOOTSTRAP_SYNC	"Waiting for WAL to reach durable storage during bootstrapping."
+WAL_BOOTSTRAP_WRITE	"Waiting for a write of a WAL page during bootstrapping."
+WAL_COPY_READ	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WAL_COPY_SYNC	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WAL_COPY_WRITE	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WAL_INIT_SYNC	"Waiting for a newly initialized WAL file to reach durable storage."
+WAL_INIT_WRITE	"Waiting for a write while initializing a new WAL file."
+WAL_READ	"Waiting for a read from a WAL file."
+WAL_SYNC	"Waiting for a WAL file to reach durable storage."
+WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAL_WRITE	"Waiting for a write to a WAL file."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file."
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait Events - LWLock
@@ -272,82 +272,82 @@ WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
 
 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_EVENT_DOCONLY	WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
+WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
 
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait Events - Lock
@@ -358,15 +358,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#52Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Michael Paquier (#51)
Re: Autogenerate some wait events code and documentation

On 2023-Aug-29, Michael Paquier wrote:

On Tue, Aug 29, 2023 at 08:17:10AM +0200, Drouvot, Bertrand wrote:

Agree that done that way one could easily grep the events from the
source code and match them with wait_event_names.txt. Then I don't
think the "search" issue in the code is still a concern with the
current proposal.

It could still be able to append WAIT_EVENT_ to the first column of
the file. I'd just rather keep it shorter.

Yeah, I have a mild preference for keeping the prefix, but it's mild
because I also imagine that if somebody doesn't see the full symbol name
when grepping they will think to remove the prefix. So only -0.1.

I think the DOCONLY stuff should be better documented; they make no
sense without looking at the commit message for fa88928470b5.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/

#53Michael Paquier
michael@paquier.xyz
In reply to: Alvaro Herrera (#52)
Re: Autogenerate some wait events code and documentation

On Tue, Aug 29, 2023 at 02:21:48PM +0200, Alvaro Herrera wrote:

Yeah, I have a mild preference for keeping the prefix, but it's mild
because I also imagine that if somebody doesn't see the full symbol name
when grepping they will think to remove the prefix. So only -0.1.

So, are you fine with the patch as presented? Or are there other
things you'd like to see changed in the format?

I think the DOCONLY stuff should be better documented; they make no
sense without looking at the commit message for fa88928470b5.

Good point. However, with 0002 in place these are gone.
--
Michael

#54Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#51)
Re: Autogenerate some wait events code and documentation

Hi,

On 8/29/23 8:41 AM, Michael Paquier wrote:

On Tue, Aug 29, 2023 at 08:17:10AM +0200, Drouvot, Bertrand wrote:
That may be a bug in the matrix because of bb90022, as git am can be
easily pissed.

git am does not complain anymore.

+       # Generate the element name for the enums based on the
+       # description.  The C symbols are prefixed with "WAIT_EVENT_".

Nit: 2 whitespaces before "The C"

# Build the descriptions. There are in camel-case.
# LWLock and Lock classes do not need any modifications.

Nit: 2 whitespaces before "There are in camel"

+       my $waiteventdescription = '';
+       if (   $waitclassname eq 'WaitEventLWLock'

Nit: Too many whitespace after the "if (" ?? (I guess pgperltidy would
fix it).

I have double-checked the docs generated, while on it, and I am not
seeing anything missing, particularly for the LWLock and Lock parts..

I did compare the output of select * from pg_wait_events order by 1,2 and
ignored the case (with and without the patch series).

Then, the only diff is:

< Client,WalSenderWaitWal,Waiting for WAL to be flushed in WAL sender process
---

Client,WalSenderWaitForWAL,Waiting for WAL to be flushed in WAL sender process

That said, it looks good to me.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#55Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#54)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Mon, Sep 04, 2023 at 02:14:58PM +0200, Drouvot, Bertrand wrote:

# Build the descriptions. There are in camel-case.
# LWLock and Lock classes do not need any modifications.

Nit: 2 whitespaces before "There are in camel"

The whitespaces are intentional, the typo in the first line is not.

+       my $waiteventdescription = '';
+       if (   $waitclassname eq 'WaitEventLWLock'

Nit: Too many whitespace after the "if (" ?? (I guess pgperltidy would
fix it).

Here, perltidy is indeed complaining, but it is adding a few
whitespaces.

Then, the only diff is:

< Client,WalSenderWaitWal,Waiting for WAL to be flushed in WAL sender process
---

Client,WalSenderWaitForWAL,Waiting for WAL to be flushed in WAL sender process

That said, it looks good to me.

Ah, good catch. I did not think about cross-checking the data in the
new view before and after the patch set. This rename needs to happen
in 0001.

Please find v5 attached. How does that look?
--
Michael

Attachments:

v5-0001-Rename-wait-events-with-more-consistent-camelcase.patchtext/x-diff; charset=us-asciiDownload
From 878ecc7a13ef9086ec3dc0cc70bff1f5d8a22eea Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 5 Sep 2023 14:32:37 +0900
Subject: [PATCH v5 1/2] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/replication/walsender.c           |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 4 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 253181f47a..38b042804c 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 46e48492ac..e250b0567e 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1654,7 +1654,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 		if (pq_is_send_pending())
 			wakeEvents |= WL_SOCKET_WRITEABLE;
 
-		WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_WAIT_WAL);
+		WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_WAIT_FOR_WAL);
 	}
 
 	/* reactivate latch so WalSndLoop knows to continue */
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 13774254d2..5287ad5f63 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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_FOR_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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
 WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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."
-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."
+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."
+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."
 
 
 #
-- 
2.40.1

v5-0002-Remove-column-for-wait-event-names-in-wait_event_.patchtext/x-diff; charset=us-asciiDownload
From 04ccd023ed376cc606848cada54837afe67bdf7d Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 5 Sep 2023 14:39:58 +0900
Subject: [PATCH v5 2/2] Remove column for wait event names in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
descriptions for each wait event class:
- Typedef enum definition, without the prefix "WAIT_EVENT_", for
simplicity.
- Description in the documentation.

The wait event names are generated from the enum objects in camelcase, with
the underscores removed.
---
 .../activity/generate-wait_event_types.pl     |  40 +-
 .../utils/activity/wait_event_names.txt       | 502 +++++++++---------
 2 files changed, 279 insertions(+), 263 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 23eb3b1f57..046be2cb70 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -65,29 +65,45 @@ while (<$wait_event_names>)
 	push(@lines, $section_name . "\t" . $_);
 }
 
-# Sort the lines based on the third column.
+# Sort the lines based on the second column.
 # uc() is being used to force the comparison to be case-insensitive.
 my @lines_sorted =
-  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+  sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventname, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  The C symbols are prefixed with "WAIT_EVENT_".
+	my $waiteventenumname = "WAIT_EVENT_$waiteventname";
+
+	# Build the descriptions.  These are in camel-case.
+	# LWLock and Lock classes do not need any modifications.
+	my $waiteventdescription = '';
+	if (   $waitclassname eq 'WaitEventLWLock'
+		|| $waitclassname eq 'WaitEventLock')
+	{
+		$waiteventdescription = $waiteventname;
+	}
+	else
+	{
+		my @waiteventparts = split("_", $waiteventname);
+		foreach my $waiteventpart (@waiteventparts)
+		{
+			$waiteventdescription .= substr($waiteventpart, 0, 1)
+			  . lc(substr($waiteventpart, 1, length($waiteventpart)));
+		}
+	}
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 5287ad5f63..638551a348 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,6 +7,11 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "Typedef enum definitions" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
@@ -18,11 +23,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +44,19 @@
 
 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."
+ARCHIVER_MAIN	"Waiting in main loop of archiver process."
+AUTOVACUUM_MAIN	"Waiting in main loop of autovacuum launcher process."
+BGWRITER_HIBERNATE	"Waiting in background writer process, hibernating."
+BGWRITER_MAIN	"Waiting in main loop of background writer process."
+CHECKPOINTER_MAIN	"Waiting in main loop of checkpointer process."
+LOGICAL_APPLY_MAIN	"Waiting in main loop of logical replication apply process."
+LOGICAL_LAUNCHER_MAIN	"Waiting in main loop of logical replication launcher process."
+LOGICAL_PARALLEL_APPLY_MAIN	"Waiting in main loop of logical replication parallel apply process."
+RECOVERY_WAL_STREAM	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SYSLOGGER_MAIN	"Waiting in main loop of syslogger process."
+WAL_RECEIVER_MAIN	"Waiting in main loop of WAL receiver process."
+WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
+WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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_FOR_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."
+CLIENT_READ	"Waiting to read data from the client."
+CLIENT_WRITE	"Waiting to write data to the client."
+GSS_OPEN_SERVER	"Waiting to read data from the client while establishing a GSSAPI session."
+LIBPQWALRECEIVER_CONNECT	"Waiting in WAL receiver to establish connection to remote server."
+LIBPQWALRECEIVER_RECEIVE	"Waiting in WAL receiver to receive data from remote server."
+SSL_OPEN_SERVER	"Waiting for SSL while attempting connection."
+WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
+WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
-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."
+APPEND_READY	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ARCHIVE_CLEANUP_COMMAND	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ARCHIVE_COMMAND	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BACKEND_TERMINATION	"Waiting for the termination of another backend."
+BACKUP_WAIT_WAL_ARCHIVE	"Waiting for WAL files required for a backup to be successfully archived."
+BGWORKER_SHUTDOWN	"Waiting for background worker to shut down."
+BGWORKER_STARTUP	"Waiting for background worker to start up."
+BTREE_PAGE	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BUFFER_IO	"Waiting for buffer I/O to complete."
+CHECKPOINT_DONE	"Waiting for a checkpoint to complete."
+CHECKPOINT_START	"Waiting for a checkpoint to start."
+EXECUTE_GATHER	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HASH_BATCH_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HASH_BATCH_ELECT	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HASH_BATCH_LOAD	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HASH_BUILD_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_ELECT	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_HASH_INNER	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HASH_BUILD_HASH_OUTER	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HASH_GROW_BATCHES_DECIDE	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_ELECT	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_FINISH	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_REALLOCATE	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_REPARTITION	"Waiting for other Parallel Hash participants to finish repartitioning."
+HASH_GROW_BUCKETS_ELECT	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HASH_GROW_BUCKETS_REALLOCATE	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HASH_GROW_BUCKETS_REINSERT	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LOGICAL_APPLY_SEND_DATA	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"Waiting for a logical replication parallel apply process to change state."
+LOGICAL_SYNC_DATA	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LOGICAL_SYNC_STATE_CHANGE	"Waiting for a logical replication remote server to change state."
+MESSAGE_QUEUE_INTERNAL	"Waiting for another process to be attached to a shared message queue."
+MESSAGE_QUEUE_PUT_MESSAGE	"Waiting to write a protocol message to a shared message queue."
+MESSAGE_QUEUE_RECEIVE	"Waiting to receive bytes from a shared message queue."
+MESSAGE_QUEUE_SEND	"Waiting to send bytes to a shared message queue."
+PARALLEL_BITMAP_SCAN	"Waiting for parallel bitmap scan to become initialized."
+PARALLEL_CREATE_INDEX_SCAN	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+PARALLEL_FINISH	"Waiting for parallel workers to finish computing."
+PROCARRAY_GROUP_UPDATE	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+PROC_SIGNAL_BARRIER	"Waiting for a barrier event to be processed by all backends."
+PROMOTE	"Waiting for standby promotion."
+RECOVERY_CONFLICT_SNAPSHOT	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RECOVERY_CONFLICT_TABLESPACE	"Waiting for recovery conflict resolution for dropping a tablespace."
+RECOVERY_END_COMMAND	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RECOVERY_PAUSE	"Waiting for recovery to be resumed."
+REPLICATION_ORIGIN_DROP	"Waiting for a replication origin to become inactive so it can be dropped."
+REPLICATION_SLOT_DROP	"Waiting for a replication slot to become inactive so it can be dropped."
+RESTORE_COMMAND	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SAFE_SNAPSHOT	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SYNC_REP	"Waiting for confirmation from a remote server during synchronous replication."
+WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
+WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
+XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BASE_BACKUP_THROTTLE	"Waiting during base backup when throttling activity."
+CHECKPOINT_WRITE_DELAY	"Waiting between writes while performing a checkpoint."
+PG_SLEEP	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RECOVERY_APPLY_DELAY	"Waiting to apply WAL during recovery because of a delay setting."
+RECOVERY_RETRIEVE_RETRY_INTERVAL	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+REGISTER_SYNC_REQUEST	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SPIN_DELAY	"Waiting while acquiring a contended spinlock."
+VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
+VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
-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."
-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."
-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."
+BASEBACKUP_READ	"Waiting for base backup to read from a file."
+BASEBACKUP_SYNC	"Waiting for data written by a base backup to reach durable storage."
+BASEBACKUP_WRITE	"Waiting for base backup to write to a file."
+BUFFILE_READ	"Waiting for a read from a buffered file."
+BUFFILE_WRITE	"Waiting for a write to a buffered file."
+BUFFILE_TRUNCATE	"Waiting for a buffered file to be truncated."
+CONTROL_FILE_READ	"Waiting for a read from the <filename>pg_control</filename> file."
+CONTROL_FILE_SYNC	"Waiting for the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_SYNC_UPDATE	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_WRITE	"Waiting for a write to the <filename>pg_control</filename> file."
+CONTROL_FILE_WRITE_UPDATE	"Waiting for a write to update the <filename>pg_control</filename> file."
+COPY_FILE_READ	"Waiting for a read during a file copy operation."
+COPY_FILE_WRITE	"Waiting for a write during a file copy operation."
+DATA_FILE_EXTEND	"Waiting for a relation data file to be extended."
+DATA_FILE_FLUSH	"Waiting for a relation data file to reach durable storage."
+DATA_FILE_IMMEDIATE_SYNC	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DATA_FILE_PREFETCH	"Waiting for an asynchronous prefetch from a relation data file."
+DATA_FILE_READ	"Waiting for a read from a relation data file."
+DATA_FILE_SYNC	"Waiting for changes to a relation data file to reach durable storage."
+DATA_FILE_TRUNCATE	"Waiting for a relation data file to be truncated."
+DATA_FILE_WRITE	"Waiting for a write to a relation data file."
+DSM_ALLOCATE	"Waiting for a dynamic shared memory segment to be allocated."
+DSM_FILL_ZERO_WRITE	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LOCK_FILE_ADDTODATADIR_READ	"Waiting for a read while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_SYNC	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_WRITE	"Waiting for a write while adding a line to the data directory lock file."
+LOCK_FILE_CREATE_READ	"Waiting to read while creating the data directory lock file."
+LOCK_FILE_CREATE_SYNC	"Waiting for data to reach durable storage while creating the data directory lock file."
+LOCK_FILE_CREATE_WRITE	"Waiting for a write while creating the data directory lock file."
+LOCK_FILE_RECHECKDATADIR_READ	"Waiting for a read during recheck of the data directory lock file."
+LOGICAL_REWRITE_CHECKPOINT_SYNC	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LOGICAL_REWRITE_MAPPING_SYNC	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LOGICAL_REWRITE_MAPPING_WRITE	"Waiting for a write of mapping data during a logical rewrite."
+LOGICAL_REWRITE_SYNC	"Waiting for logical rewrite mappings to reach durable storage."
+LOGICAL_REWRITE_TRUNCATE	"Waiting for truncate of mapping data during a logical rewrite."
+LOGICAL_REWRITE_WRITE	"Waiting for a write of logical rewrite mappings."
+RELATION_MAP_READ	"Waiting for a read of the relation map file."
+RELATION_MAP_REPLACE	"Waiting for durable replacement of a relation map file."
+RELATION_MAP_WRITE	"Waiting for a write to the relation map file."
+REORDER_BUFFER_READ	"Waiting for a read during reorder buffer management."
+REORDER_BUFFER_WRITE	"Waiting for a write during reorder buffer management."
+REORDER_LOGICAL_MAPPING_READ	"Waiting for a read of a logical mapping during reorder buffer management."
+REPLICATION_SLOT_READ	"Waiting for a read from a replication slot control file."
+REPLICATION_SLOT_RESTORE_SYNC	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+REPLICATION_SLOT_SYNC	"Waiting for a replication slot control file to reach durable storage."
+REPLICATION_SLOT_WRITE	"Waiting for a write to a replication slot control file."
+SLRU_FLUSH_SYNC	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SLRU_READ	"Waiting for a read of an SLRU page."
+SLRU_SYNC	"Waiting for SLRU data to reach durable storage following a page write."
+SLRU_WRITE	"Waiting for a write of an SLRU page."
+SNAPBUILD_READ	"Waiting for a read of a serialized historical catalog snapshot."
+SNAPBUILD_SYNC	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SNAPBUILD_WRITE	"Waiting for a write of a serialized historical catalog snapshot."
+TIMELINE_HISTORY_FILE_SYNC	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TIMELINE_HISTORY_FILE_WRITE	"Waiting for a write of a timeline history file received via streaming replication."
+TIMELINE_HISTORY_READ	"Waiting for a read of a timeline history file."
+TIMELINE_HISTORY_SYNC	"Waiting for a newly created timeline history file to reach durable storage."
+TIMELINE_HISTORY_WRITE	"Waiting for a write of a newly created timeline history file."
+TWOPHASE_FILE_READ	"Waiting for a read of a two phase state file."
+TWOPHASE_FILE_SYNC	"Waiting for a two phase state file to reach durable storage."
+TWOPHASE_FILE_WRITE	"Waiting for a write of a two phase state file."
+VERSION_FILE_WRITE	"Waiting for the version file to be written while creating a database."
+WALSENDER_TIMELINE_HISTORY_READ	"Waiting for a read from a timeline history file during a walsender timeline command."
+WAL_BOOTSTRAP_SYNC	"Waiting for WAL to reach durable storage during bootstrapping."
+WAL_BOOTSTRAP_WRITE	"Waiting for a write of a WAL page during bootstrapping."
+WAL_COPY_READ	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WAL_COPY_SYNC	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WAL_COPY_WRITE	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WAL_INIT_SYNC	"Waiting for a newly initialized WAL file to reach durable storage."
+WAL_INIT_WRITE	"Waiting for a write while initializing a new WAL file."
+WAL_READ	"Waiting for a read from a WAL file."
+WAL_SYNC	"Waiting for a WAL file to reach durable storage."
+WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAL_WRITE	"Waiting for a write to a WAL file."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file."
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait Events - LWLock
@@ -272,82 +272,82 @@ WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
 
 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_EVENT_DOCONLY	WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+OldSnapshotTimeMap	"Waiting to read or update old snapshot control information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
+WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
 
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information  about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait Events - Lock
@@ -358,15 +358,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.40.1

#56Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#55)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On 9/5/23 7:44 AM, Michael Paquier wrote:

On Mon, Sep 04, 2023 at 02:14:58PM +0200, Drouvot, Bertrand wrote:

# Build the descriptions. There are in camel-case.
# LWLock and Lock classes do not need any modifications.

Nit: 2 whitespaces before "There are in camel"

The whitespaces are intentional,

Oh ok, out of curiosity, why are 2 whitespaces intentional?

Then, the only diff is:

< Client,WalSenderWaitWal,Waiting for WAL to be flushed in WAL sender process
---

Client,WalSenderWaitForWAL,Waiting for WAL to be flushed in WAL sender process

That said, it looks good to me.

Ah, good catch. I did not think about cross-checking the data in the
new view before and after the patch set. This rename needs to happen
in 0001.

Please find v5 attached. How does that look?

Thanks!

That looks good. I just noticed that v5 did re-introduce the "issue" that
was fixed in 00e49233a9.

Also, v5 needs a rebase due to f691f5b80a.

Attaching v6 taking care of the 2 points mentioned above.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v6-0001-Rename-wait-events-with-more-consistent-camelcase.patchtext/plain; charset=UTF-8; name=v6-0001-Rename-wait-events-with-more-consistent-camelcase.patchDownload
From 6a94fc1a00ae784b12e15f498a5afba4020377f9 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 5 Sep 2023 14:32:37 +0900
Subject: [PATCH v6 1/2] Rename wait events with more consistent camelcase
 style

This will help in the introduction of more simplifications with the
generation of wait event data using wait_event_names.txt.  The event
names used the same case-insensitive characters, hence applying lower()
or upper() to the monitoring queries allows the detection of the same
events as before this change.
---
 src/backend/libpq/pqmq.c                      |  2 +-
 src/backend/replication/walsender.c           |  2 +-
 src/backend/storage/ipc/shm_mq.c              |  6 +-
 .../utils/activity/wait_event_names.txt       | 90 +++++++++----------
 4 files changed, 50 insertions(+), 50 deletions(-)
   3.2% src/backend/storage/ipc/
  93.3% src/backend/utils/activity/
   3.3% src/backend/

diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 253181f47a..38b042804c 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -182,7 +182,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
 			break;
 
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_PUT_MESSAGE);
+						 WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE);
 		ResetLatch(MyLatch);
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 46e48492ac..e250b0567e 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1654,7 +1654,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 		if (pq_is_send_pending())
 			wakeEvents |= WL_SOCKET_WRITEABLE;
 
-		WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_WAIT_WAL);
+		WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_WAIT_FOR_WAL);
 	}
 
 	/* reactivate latch so WalSndLoop knows to continue */
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index d134a09a19..06d6b73527 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1017,7 +1017,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
 			 * cheaper than setting one that has been reset.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_MQ_SEND);
+							 WAIT_EVENT_MESSAGE_QUEUE_SEND);
 
 			/* Reset the latch so we don't spin. */
 			ResetLatch(MyLatch);
@@ -1163,7 +1163,7 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
 		 * setting one that has been reset.
 		 */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_RECEIVE);
+						 WAIT_EVENT_MESSAGE_QUEUE_RECEIVE);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
@@ -1252,7 +1252,7 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
 
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_MQ_INTERNAL);
+						 WAIT_EVENT_MESSAGE_QUEUE_INTERNAL);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 06a1a3df9b..ca28d9e764 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -45,15 +45,15 @@
 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_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_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."
@@ -71,11 +71,11 @@ 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_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_FOR_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."
 
 
@@ -93,10 +93,10 @@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND	ArchiveCleanupCommand	"Waiting for <xref link
 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_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_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."
@@ -119,14 +119,14 @@ WAIT_EVENT_LOGICAL_APPLY_SEND_DATA	LogicalApplySendData	"Waiting for a logical r
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
+WAIT_EVENT_MESSAGE_QUEUE_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_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."
@@ -170,12 +170,12 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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_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."
 WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE	ControlFileSyncUpdate	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
@@ -191,15 +191,15 @@ WAIT_EVENT_DATA_FILE_READ	DataFileRead	"Waiting for a read from a relation data
 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_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_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."
@@ -216,10 +216,10 @@ WAIT_EVENT_REPLICATION_SLOT_READ	ReplicationSlotRead	"Waiting for a read from a
 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_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."
@@ -232,18 +232,18 @@ WAIT_EVENT_TWOPHASE_FILE_READ	TwophaseFileRead	"Waiting for a read of a two phas
 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."
-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."
+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."
+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."
 
 
 #
-- 
2.34.1

v6-0002-Remove-column-for-wait-event-names-in-wait_event_.patchtext/plain; charset=UTF-8; name=v6-0002-Remove-column-for-wait-event-names-in-wait_event_.patchDownload
From 6e32a44cf27ddde43445a67a2b3f5e2adad6170c Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 5 Sep 2023 14:39:58 +0900
Subject: [PATCH v6 2/2] Remove column for wait event names in
 wait_event_names.txt

This file is now made of two columns, removing the column listing the
descriptions for each wait event class:
- Typedef enum definition, without the prefix "WAIT_EVENT_", for
simplicity.
- Description in the documentation.

The wait event names are generated from the enum objects in camelcase, with
the underscores removed.
---
 .../activity/generate-wait_event_types.pl     |  40 +-
 .../utils/activity/wait_event_names.txt       | 502 +++++++++---------
 2 files changed, 279 insertions(+), 263 deletions(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 23eb3b1f57..046be2cb70 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -65,29 +65,45 @@ while (<$wait_event_names>)
 	push(@lines, $section_name . "\t" . $_);
 }
 
-# Sort the lines based on the third column.
+# Sort the lines based on the second column.
 # uc() is being used to force the comparison to be case-insensitive.
 my @lines_sorted =
-  sort { uc((split(/\t/, $a))[2]) cmp uc((split(/\t/, $b))[2]) } @lines;
+  sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
 	die "unable to parse wait_event_names.txt for line $line\n"
-	  unless $line =~ /^(\w+)\t+(\w+)\t+(\w+)\t+("\w.*\.")$/;
+	  unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/;
 
-	(   my $waitclassname,
-		my $waiteventenumname,
-		my $waiteventdescription,
-		my $waitevendocsentence) = split(/\t/, $line);
+	(my $waitclassname, my $waiteventname, my $waitevendocsentence) =
+	  split(/\t/, $line);
 
+	# Generate the element name for the enums based on the
+	# description.  The C symbols are prefixed with "WAIT_EVENT_".
+	my $waiteventenumname = "WAIT_EVENT_$waiteventname";
+
+	# Build the descriptions.  These are in camel-case.
+	# LWLock and Lock classes do not need any modifications.
+	my $waiteventdescription = '';
+	if (   $waitclassname eq 'WaitEventLWLock'
+		|| $waitclassname eq 'WaitEventLock')
+	{
+		$waiteventdescription = $waiteventname;
+	}
+	else
+	{
+		my @waiteventparts = split("_", $waiteventname);
+		foreach my $waiteventpart (@waiteventparts)
+		{
+			$waiteventdescription .= substr($waiteventpart, 0, 1)
+			  . lc(substr($waiteventpart, 1, length($waiteventpart)));
+		}
+	}
+
+	# Store the event into the list for each class.
 	my @waiteventlist =
 	  [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ];
-	my $trimmedwaiteventname = $waiteventenumname;
-	$trimmedwaiteventname =~ s/^WAIT_EVENT_//;
-
-	die "wait event names must start with 'WAIT_EVENT_'"
-	  if ($trimmedwaiteventname eq $waiteventenumname);
 	push(@{ $hashwe{$waitclassname} }, @waiteventlist);
 }
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index ca28d9e764..9c5fdeb3ca 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -7,6 +7,11 @@
 # This list serves as the basis for generating source and documentation files
 # related to wait events.
 #
+# This file defines one wait event per line, with the following
+# tab-separated fields:
+#
+#   "Typedef enum definitions" "description in the docs"
+#
 # The files generated from this one are:
 #
 #   src/backend/utils/activity/wait_event_types.h
@@ -18,11 +23,6 @@
 #   src/backend/utils/activity/wait_event_types.sgml
 #      SGML tables of wait events for inclusion in the documentation.
 #
-# This file defines one wait event per line, with the 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.
 #
@@ -44,19 +44,19 @@
 
 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."
+ARCHIVER_MAIN	"Waiting in main loop of archiver process."
+AUTOVACUUM_MAIN	"Waiting in main loop of autovacuum launcher process."
+BGWRITER_HIBERNATE	"Waiting in background writer process, hibernating."
+BGWRITER_MAIN	"Waiting in main loop of background writer process."
+CHECKPOINTER_MAIN	"Waiting in main loop of checkpointer process."
+LOGICAL_APPLY_MAIN	"Waiting in main loop of logical replication apply process."
+LOGICAL_LAUNCHER_MAIN	"Waiting in main loop of logical replication launcher process."
+LOGICAL_PARALLEL_APPLY_MAIN	"Waiting in main loop of logical replication parallel apply process."
+RECOVERY_WAL_STREAM	"Waiting in main loop of startup process for WAL to arrive, during streaming recovery."
+SYSLOGGER_MAIN	"Waiting in main loop of syslogger process."
+WAL_RECEIVER_MAIN	"Waiting in main loop of WAL receiver process."
+WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
+WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
 
 #
@@ -69,14 +69,14 @@ WAIT_EVENT_WAL_WRITER_MAIN	WalWriterMain	"Waiting in main loop of WAL writer pro
 
 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_FOR_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."
+CLIENT_READ	"Waiting to read data from the client."
+CLIENT_WRITE	"Waiting to write data to the client."
+GSS_OPEN_SERVER	"Waiting to read data from the client while establishing a GSSAPI session."
+LIBPQWALRECEIVER_CONNECT	"Waiting in WAL receiver to establish connection to remote server."
+LIBPQWALRECEIVER_RECEIVE	"Waiting in WAL receiver to receive data from remote server."
+SSL_OPEN_SERVER	"Waiting for SSL while attempting connection."
+WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
+WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
 
 #
@@ -88,59 +88,59 @@ WAIT_EVENT_WAL_SENDER_WRITE_DATA	WalSenderWriteData	"Waiting for any activity wh
 
 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_MESSAGE_QUEUE_INTERNAL	MessageQueueInternal	"Waiting for another process to be attached to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_PUT_MESSAGE	MessageQueuePutMessage	"Waiting to write a protocol message to a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_RECEIVE	MessageQueueReceive	"Waiting to receive bytes from a shared message queue."
-WAIT_EVENT_MESSAGE_QUEUE_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."
-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."
+APPEND_READY	"Waiting for subplan nodes of an <literal>Append</literal> plan node to be ready."
+ARCHIVE_CLEANUP_COMMAND	"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+ARCHIVE_COMMAND	"Waiting for <xref linkend="guc-archive-command"/> to complete."
+BACKEND_TERMINATION	"Waiting for the termination of another backend."
+BACKUP_WAIT_WAL_ARCHIVE	"Waiting for WAL files required for a backup to be successfully archived."
+BGWORKER_SHUTDOWN	"Waiting for background worker to shut down."
+BGWORKER_STARTUP	"Waiting for background worker to start up."
+BTREE_PAGE	"Waiting for the page number needed to continue a parallel B-tree scan to become available."
+BUFFER_IO	"Waiting for buffer I/O to complete."
+CHECKPOINT_DONE	"Waiting for a checkpoint to complete."
+CHECKPOINT_START	"Waiting for a checkpoint to start."
+EXECUTE_GATHER	"Waiting for activity from a child process while executing a <literal>Gather</literal> plan node."
+HASH_BATCH_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate a hash table."
+HASH_BATCH_ELECT	"Waiting to elect a Parallel Hash participant to allocate a hash table."
+HASH_BATCH_LOAD	"Waiting for other Parallel Hash participants to finish loading a hash table."
+HASH_BUILD_ALLOCATE	"Waiting for an elected Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_ELECT	"Waiting to elect a Parallel Hash participant to allocate the initial hash table."
+HASH_BUILD_HASH_INNER	"Waiting for other Parallel Hash participants to finish hashing the inner relation."
+HASH_BUILD_HASH_OUTER	"Waiting for other Parallel Hash participants to finish partitioning the outer relation."
+HASH_GROW_BATCHES_DECIDE	"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_ELECT	"Waiting to elect a Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_FINISH	"Waiting for an elected Parallel Hash participant to decide on future batch growth."
+HASH_GROW_BATCHES_REALLOCATE	"Waiting for an elected Parallel Hash participant to allocate more batches."
+HASH_GROW_BATCHES_REPARTITION	"Waiting for other Parallel Hash participants to finish repartitioning."
+HASH_GROW_BUCKETS_ELECT	"Waiting to elect a Parallel Hash participant to allocate more buckets."
+HASH_GROW_BUCKETS_REALLOCATE	"Waiting for an elected Parallel Hash participant to finish allocating more buckets."
+HASH_GROW_BUCKETS_REINSERT	"Waiting for other Parallel Hash participants to finish inserting tuples into new buckets."
+LOGICAL_APPLY_SEND_DATA	"Waiting for a logical replication leader apply process to send data to a parallel apply process."
+LOGICAL_PARALLEL_APPLY_STATE_CHANGE	"Waiting for a logical replication parallel apply process to change state."
+LOGICAL_SYNC_DATA	"Waiting for a logical replication remote server to send data for initial table synchronization."
+LOGICAL_SYNC_STATE_CHANGE	"Waiting for a logical replication remote server to change state."
+MESSAGE_QUEUE_INTERNAL	"Waiting for another process to be attached to a shared message queue."
+MESSAGE_QUEUE_PUT_MESSAGE	"Waiting to write a protocol message to a shared message queue."
+MESSAGE_QUEUE_RECEIVE	"Waiting to receive bytes from a shared message queue."
+MESSAGE_QUEUE_SEND	"Waiting to send bytes to a shared message queue."
+PARALLEL_BITMAP_SCAN	"Waiting for parallel bitmap scan to become initialized."
+PARALLEL_CREATE_INDEX_SCAN	"Waiting for parallel <command>CREATE INDEX</command> workers to finish heap scan."
+PARALLEL_FINISH	"Waiting for parallel workers to finish computing."
+PROCARRAY_GROUP_UPDATE	"Waiting for the group leader to clear the transaction ID at end of a parallel operation."
+PROC_SIGNAL_BARRIER	"Waiting for a barrier event to be processed by all backends."
+PROMOTE	"Waiting for standby promotion."
+RECOVERY_CONFLICT_SNAPSHOT	"Waiting for recovery conflict resolution for a vacuum cleanup."
+RECOVERY_CONFLICT_TABLESPACE	"Waiting for recovery conflict resolution for dropping a tablespace."
+RECOVERY_END_COMMAND	"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+RECOVERY_PAUSE	"Waiting for recovery to be resumed."
+REPLICATION_ORIGIN_DROP	"Waiting for a replication origin to become inactive so it can be dropped."
+REPLICATION_SLOT_DROP	"Waiting for a replication slot to become inactive so it can be dropped."
+RESTORE_COMMAND	"Waiting for <xref linkend="guc-restore-command"/> to complete."
+SAFE_SNAPSHOT	"Waiting to obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> transaction."
+SYNC_REP	"Waiting for confirmation from a remote server during synchronous replication."
+WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
+WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
+XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
 
 #
@@ -151,15 +151,15 @@ WAIT_EVENT_XACT_GROUP_UPDATE	XactGroupUpdate	"Waiting for the group leader to up
 
 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."
+BASE_BACKUP_THROTTLE	"Waiting during base backup when throttling activity."
+CHECKPOINT_WRITE_DELAY	"Waiting between writes while performing a checkpoint."
+PG_SLEEP	"Waiting due to a call to <function>pg_sleep</function> or a sibling function."
+RECOVERY_APPLY_DELAY	"Waiting to apply WAL during recovery because of a delay setting."
+RECOVERY_RETRIEVE_RETRY_INTERVAL	"Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
+REGISTER_SYNC_REQUEST	"Waiting while sending synchronization requests to the checkpointer, because the request queue is full."
+SPIN_DELAY	"Waiting while acquiring a contended spinlock."
+VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
+VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 
 
 #
@@ -170,80 +170,80 @@ WAIT_EVENT_VACUUM_TRUNCATE	VacuumTruncate	"Waiting to acquire an exclusive lock
 
 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."
-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."
-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."
-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."
+BASEBACKUP_READ	"Waiting for base backup to read from a file."
+BASEBACKUP_SYNC	"Waiting for data written by a base backup to reach durable storage."
+BASEBACKUP_WRITE	"Waiting for base backup to write to a file."
+BUFFILE_READ	"Waiting for a read from a buffered file."
+BUFFILE_WRITE	"Waiting for a write to a buffered file."
+BUFFILE_TRUNCATE	"Waiting for a buffered file to be truncated."
+CONTROL_FILE_READ	"Waiting for a read from the <filename>pg_control</filename> file."
+CONTROL_FILE_SYNC	"Waiting for the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_SYNC_UPDATE	"Waiting for an update to the <filename>pg_control</filename> file to reach durable storage."
+CONTROL_FILE_WRITE	"Waiting for a write to the <filename>pg_control</filename> file."
+CONTROL_FILE_WRITE_UPDATE	"Waiting for a write to update the <filename>pg_control</filename> file."
+COPY_FILE_READ	"Waiting for a read during a file copy operation."
+COPY_FILE_WRITE	"Waiting for a write during a file copy operation."
+DATA_FILE_EXTEND	"Waiting for a relation data file to be extended."
+DATA_FILE_FLUSH	"Waiting for a relation data file to reach durable storage."
+DATA_FILE_IMMEDIATE_SYNC	"Waiting for an immediate synchronization of a relation data file to durable storage."
+DATA_FILE_PREFETCH	"Waiting for an asynchronous prefetch from a relation data file."
+DATA_FILE_READ	"Waiting for a read from a relation data file."
+DATA_FILE_SYNC	"Waiting for changes to a relation data file to reach durable storage."
+DATA_FILE_TRUNCATE	"Waiting for a relation data file to be truncated."
+DATA_FILE_WRITE	"Waiting for a write to a relation data file."
+DSM_ALLOCATE	"Waiting for a dynamic shared memory segment to be allocated."
+DSM_FILL_ZERO_WRITE	"Waiting to fill a dynamic shared memory backing file with zeroes."
+LOCK_FILE_ADDTODATADIR_READ	"Waiting for a read while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_SYNC	"Waiting for data to reach durable storage while adding a line to the data directory lock file."
+LOCK_FILE_ADDTODATADIR_WRITE	"Waiting for a write while adding a line to the data directory lock file."
+LOCK_FILE_CREATE_READ	"Waiting to read while creating the data directory lock file."
+LOCK_FILE_CREATE_SYNC	"Waiting for data to reach durable storage while creating the data directory lock file."
+LOCK_FILE_CREATE_WRITE	"Waiting for a write while creating the data directory lock file."
+LOCK_FILE_RECHECKDATADIR_READ	"Waiting for a read during recheck of the data directory lock file."
+LOGICAL_REWRITE_CHECKPOINT_SYNC	"Waiting for logical rewrite mappings to reach durable storage during a checkpoint."
+LOGICAL_REWRITE_MAPPING_SYNC	"Waiting for mapping data to reach durable storage during a logical rewrite."
+LOGICAL_REWRITE_MAPPING_WRITE	"Waiting for a write of mapping data during a logical rewrite."
+LOGICAL_REWRITE_SYNC	"Waiting for logical rewrite mappings to reach durable storage."
+LOGICAL_REWRITE_TRUNCATE	"Waiting for truncate of mapping data during a logical rewrite."
+LOGICAL_REWRITE_WRITE	"Waiting for a write of logical rewrite mappings."
+RELATION_MAP_READ	"Waiting for a read of the relation map file."
+RELATION_MAP_REPLACE	"Waiting for durable replacement of a relation map file."
+RELATION_MAP_WRITE	"Waiting for a write to the relation map file."
+REORDER_BUFFER_READ	"Waiting for a read during reorder buffer management."
+REORDER_BUFFER_WRITE	"Waiting for a write during reorder buffer management."
+REORDER_LOGICAL_MAPPING_READ	"Waiting for a read of a logical mapping during reorder buffer management."
+REPLICATION_SLOT_READ	"Waiting for a read from a replication slot control file."
+REPLICATION_SLOT_RESTORE_SYNC	"Waiting for a replication slot control file to reach durable storage while restoring it to memory."
+REPLICATION_SLOT_SYNC	"Waiting for a replication slot control file to reach durable storage."
+REPLICATION_SLOT_WRITE	"Waiting for a write to a replication slot control file."
+SLRU_FLUSH_SYNC	"Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown."
+SLRU_READ	"Waiting for a read of an SLRU page."
+SLRU_SYNC	"Waiting for SLRU data to reach durable storage following a page write."
+SLRU_WRITE	"Waiting for a write of an SLRU page."
+SNAPBUILD_READ	"Waiting for a read of a serialized historical catalog snapshot."
+SNAPBUILD_SYNC	"Waiting for a serialized historical catalog snapshot to reach durable storage."
+SNAPBUILD_WRITE	"Waiting for a write of a serialized historical catalog snapshot."
+TIMELINE_HISTORY_FILE_SYNC	"Waiting for a timeline history file received via streaming replication to reach durable storage."
+TIMELINE_HISTORY_FILE_WRITE	"Waiting for a write of a timeline history file received via streaming replication."
+TIMELINE_HISTORY_READ	"Waiting for a read of a timeline history file."
+TIMELINE_HISTORY_SYNC	"Waiting for a newly created timeline history file to reach durable storage."
+TIMELINE_HISTORY_WRITE	"Waiting for a write of a newly created timeline history file."
+TWOPHASE_FILE_READ	"Waiting for a read of a two phase state file."
+TWOPHASE_FILE_SYNC	"Waiting for a two phase state file to reach durable storage."
+TWOPHASE_FILE_WRITE	"Waiting for a write of a two phase state file."
+VERSION_FILE_WRITE	"Waiting for the version file to be written while creating a database."
+WALSENDER_TIMELINE_HISTORY_READ	"Waiting for a read from a timeline history file during a walsender timeline command."
+WAL_BOOTSTRAP_SYNC	"Waiting for WAL to reach durable storage during bootstrapping."
+WAL_BOOTSTRAP_WRITE	"Waiting for a write of a WAL page during bootstrapping."
+WAL_COPY_READ	"Waiting for a read when creating a new WAL segment by copying an existing one."
+WAL_COPY_SYNC	"Waiting for a new WAL segment created by copying an existing one to reach durable storage."
+WAL_COPY_WRITE	"Waiting for a write when creating a new WAL segment by copying an existing one."
+WAL_INIT_SYNC	"Waiting for a newly initialized WAL file to reach durable storage."
+WAL_INIT_WRITE	"Waiting for a write while initializing a new WAL file."
+WAL_READ	"Waiting for a read from a WAL file."
+WAL_SYNC	"Waiting for a WAL file to reach durable storage."
+WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
+WAL_WRITE	"Waiting for a write to a WAL file."
 
 
 #
@@ -252,7 +252,7 @@ WAIT_EVENT_WAL_WRITE	WalWrite	"Waiting for a write to a WAL file."
 
 Section: ClassName - WaitEventBufferPin
 
-WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer."
+BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
 
 #
@@ -261,7 +261,7 @@ WAIT_EVENT_BUFFER_PIN	BufferPin	"Waiting to acquire an exclusive pin on a buffer
 
 Section: ClassName - WaitEventExtension
 
-WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
+Extension	"Waiting in an extension."
 
 #
 # Wait Events - LWLock
@@ -272,81 +272,81 @@ WAIT_EVENT_DOCONLY	Extension	"Waiting in an extension."
 
 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	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_EVENT_DOCONLY	WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
-
-WAIT_EVENT_DOCONLY	XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
-WAIT_EVENT_DOCONLY	CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
-WAIT_EVENT_DOCONLY	SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
-WAIT_EVENT_DOCONLY	MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
-WAIT_EVENT_DOCONLY	NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
-WAIT_EVENT_DOCONLY	SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
-WAIT_EVENT_DOCONLY	WALInsert	"Waiting to insert WAL data into a memory buffer."
-WAIT_EVENT_DOCONLY	BufferContent	"Waiting to access a data page in memory."
-WAIT_EVENT_DOCONLY	ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
-WAIT_EVENT_DOCONLY	ReplicationSlotIO	"Waiting for I/O on a replication slot."
-WAIT_EVENT_DOCONLY	LockFastPath	"Waiting to read or update a process' fast-path lock information."
-WAIT_EVENT_DOCONLY	BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
-WAIT_EVENT_DOCONLY	LockManager	"Waiting to read or update information about <quote>heavyweight</quote> locks."
-WAIT_EVENT_DOCONLY	PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
-WAIT_EVENT_DOCONLY	ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
-WAIT_EVENT_DOCONLY	ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
-WAIT_EVENT_DOCONLY	PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
-WAIT_EVENT_DOCONLY	PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
-WAIT_EVENT_DOCONLY	SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
-WAIT_EVENT_DOCONLY	SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
-WAIT_EVENT_DOCONLY	ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
-WAIT_EVENT_DOCONLY	PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
-WAIT_EVENT_DOCONLY	PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
-WAIT_EVENT_DOCONLY	PgStatsHash	"Waiting for stats shared memory hash table access."
-WAIT_EVENT_DOCONLY	PgStatsData	"Waiting for shared memory stats data access."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
-WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
+ShmemIndex	"Waiting to find or allocate space in shared memory."
+OidGen	"Waiting to allocate a new OID."
+XidGen	"Waiting to allocate a new transaction ID."
+ProcArray	"Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID)."
+SInvalRead	"Waiting to retrieve messages from the shared catalog invalidation queue."
+SInvalWrite	"Waiting to add a message to the shared catalog invalidation queue."
+WALBufMapping	"Waiting to replace a page in WAL buffers."
+WALWrite	"Waiting for WAL buffers to be written to disk."
+ControlFile	"Waiting to read or update the <filename>pg_control</filename> file or create a new WAL file."
+XactSLRU	"Waiting to access the transaction status SLRU cache."
+SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
+MultiXactGen	"Waiting to read or update shared multixact state."
+MultiXactOffsetSLRU	"Waiting to access the multixact offset SLRU cache."
+MultiXactMemberSLRU	"Waiting to access the multixact member SLRU cache."
+RelCacheInit	"Waiting to read or update a <filename>pg_internal.init</filename> relation cache initialization file."
+CheckpointerComm	"Waiting to manage fsync requests."
+TwoPhaseState	"Waiting to read or update the state of prepared transactions."
+TablespaceCreate	"Waiting to create or drop a tablespace."
+BtreeVacuum	"Waiting to read or update vacuum-related information for a B-tree index."
+AddinShmemInit	"Waiting to manage an extension's space allocation in shared memory."
+Autovacuum	"Waiting to read or update the current state of autovacuum workers."
+AutovacuumSchedule	"Waiting to ensure that a table selected for autovacuum still needs vacuuming."
+SyncScan	"Waiting to select the starting location of a synchronized table scan."
+RelationMapping	"Waiting to read or update a <filename>pg_filenode.map</filename> file (used to track the filenode assignments of certain system catalogs)."
+NotifySLRU	"Waiting to access the <command>NOTIFY</command> message SLRU cache."
+NotifyQueue	"Waiting to read or update <command>NOTIFY</command> messages."
+SerializableXactHash	"Waiting to read or update information about serializable transactions."
+SerializableFinishedList	"Waiting to access the list of finished serializable transactions."
+SerializablePredicateList	"Waiting to access the list of predicate locks held by serializable transactions."
+SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
+SyncRep	"Waiting to read or update information about the state of synchronous replication."
+BackgroundWorker	"Waiting to read or update background worker state."
+DynamicSharedMemoryControl	"Waiting to read or update dynamic shared memory allocation information."
+AutoFile	"Waiting to update the <filename>postgresql.auto.conf</filename> file."
+ReplicationSlotAllocation	"Waiting to allocate or free a replication slot."
+ReplicationSlotControl	"Waiting to read or update replication slot state."
+CommitTsSLRU	"Waiting to access the commit timestamp SLRU cache."
+CommitTs	"Waiting to read or update the last value set for a transaction commit timestamp."
+ReplicationOrigin	"Waiting to create, drop or use a replication origin."
+MultiXactTruncation	"Waiting to read or truncate multixact information."
+LogicalRepWorker	"Waiting to read or update the state of logical replication workers."
+XactTruncation	"Waiting to execute <function>pg_xact_status</function> or update the oldest transaction ID available to it."
+WrapLimitsVacuum	"Waiting to update limits on transaction id and multixact consumption."
+NotifyQueueTail	"Waiting to update limit on <command>NOTIFY</command> message storage."
+WaitEventExtension	"Waiting to read or update custom wait events information for extensions."
+
+XactBuffer	"Waiting for I/O on a transaction status SLRU buffer."
+CommitTsBuffer	"Waiting for I/O on a commit timestamp SLRU buffer."
+SubtransBuffer	"Waiting for I/O on a sub-transaction SLRU buffer."
+MultiXactOffsetBuffer	"Waiting for I/O on a multixact offset SLRU buffer."
+MultiXactMemberBuffer	"Waiting for I/O on a multixact member SLRU buffer."
+NotifyBuffer	"Waiting for I/O on a <command>NOTIFY</command> message SLRU buffer."
+SerialBuffer	"Waiting for I/O on a serializable transaction conflict SLRU buffer."
+WALInsert	"Waiting to insert WAL data into a memory buffer."
+BufferContent	"Waiting to access a data page in memory."
+ReplicationOriginState	"Waiting to read or update the progress of one replication origin."
+ReplicationSlotIO	"Waiting for I/O on a replication slot."
+LockFastPath	"Waiting to read or update a process' fast-path lock information."
+BufferMapping	"Waiting to associate a data block with a buffer in the buffer pool."
+LockManager	"Waiting to read or update information about <quote>heavyweight</quote> locks."
+PredicateLockManager	"Waiting to access predicate lock information used by serializable transactions."
+ParallelHashJoin	"Waiting to synchronize workers during Parallel Hash Join plan execution."
+ParallelQueryDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionDSA	"Waiting for parallel query dynamic shared memory allocation."
+PerSessionRecordType	"Waiting to access a parallel query's information about composite types."
+PerSessionRecordTypmod	"Waiting to access a parallel query's information about type modifiers that identify anonymous record types."
+SharedTupleStore	"Waiting to access a shared tuple store during parallel query."
+SharedTidBitmap	"Waiting to access a shared TID bitmap during a parallel bitmap index scan."
+ParallelAppend	"Waiting to choose the next subplan during Parallel Append plan execution."
+PerXactPredicateList	"Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query."
+PgStatsDSA	"Waiting for stats dynamic shared memory allocator access."
+PgStatsHash	"Waiting for stats shared memory hash table access."
+PgStatsData	"Waiting for shared memory stats data access."
+LogicalRepLauncherDSA	"Waiting to access logical replication launcher's dynamic shared memory allocator."
+LogicalRepLauncherHash	"Waiting to access logical replication launcher's shared hash table."
 
 #
 # Wait Events - Lock
@@ -357,15 +357,15 @@ WAIT_EVENT_DOCONLY	LogicalRepLauncherHash	"Waiting to access logical replication
 
 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."
+relation	"Waiting to acquire a lock on a relation."
+extend	"Waiting to extend a relation."
+frozenid	"Waiting to update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield> and <structname>pg_database</structname>.<structfield>datminmxid</structfield>."
+page	"Waiting to acquire a lock on a page of a relation."
+tuple	"Waiting to acquire a lock on a tuple."
+transactionid	"Waiting for a transaction to finish."
+virtualxid	"Waiting to acquire a virtual transaction ID lock; see <xref linkend="transaction-id"/>."
+spectoken	"Waiting to acquire a speculative insertion lock."
+object	"Waiting to acquire a lock on a non-relation database object."
+userlock	"Waiting to acquire a user lock."
+advisory	"Waiting to acquire an advisory user lock."
+applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
-- 
2.34.1

#57Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#56)
Re: Autogenerate some wait events code and documentation

On Tue, Sep 05, 2023 at 11:06:36AM +0200, Drouvot, Bertrand wrote:

Oh ok, out of curiosity, why are 2 whitespaces intentional?

That depends on the individual who write the code, but I recall that
this is some old-school style from the 70's and/or the 80's when
typing machines were still something. I'm just used to this style
after the end of a sentence in a comment.

That looks good. I just noticed that v5 did re-introduce the "issue" that
was fixed in 00e49233a9.

Also, v5 needs a rebase due to f691f5b80a.

Attaching v6 taking care of the 2 points mentioned above.

Dammit, thanks. These successive rebases are a bit annoying.. The
data produced is consistent, and the new contents can be grepped, so I
think that I am just going to apply both patches and move on to other
topics.
--
Michael

#58Erik Wienhold
ewie@ewie.name
In reply to: Michael Paquier (#57)
Re: Autogenerate some wait events code and documentation

On 05/09/2023 13:50 CEST Michael Paquier <michael@paquier.xyz> wrote:

On Tue, Sep 05, 2023 at 11:06:36AM +0200, Drouvot, Bertrand wrote:

Oh ok, out of curiosity, why are 2 whitespaces intentional?

That depends on the individual who write the code, but I recall that
this is some old-school style from the 70's and/or the 80's when
typing machines were still something. I'm just used to this style
after the end of a sentence in a comment.

FYI: https://en.wikipedia.org/wiki/Sentence_spacing

--
Erik

#59Michael Paquier
michael@paquier.xyz
In reply to: Drouvot, Bertrand (#56)
Re: Autogenerate some wait events code and documentation

On Tue, Sep 05, 2023 at 11:06:36AM +0200, Drouvot, Bertrand wrote:

Also, v5 needs a rebase due to f691f5b80a.

Attaching v6 taking care of the 2 points mentioned above.

Thanks. This time I have correctly checked the consistency of the
data produced across all these commits using pg_wait_events, and
that's OK. So applied both.
--
Michael

#60Michael Paquier
michael@paquier.xyz
In reply to: Erik Wienhold (#58)
Re: Autogenerate some wait events code and documentation

On Wed, Sep 06, 2023 at 04:20:23AM +0200, Erik Wienhold wrote:

FYI: https://en.wikipedia.org/wiki/Sentence_spacing

That was an interesting read. Thanks.
--
Michael

#61Drouvot, Bertrand
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#60)
Re: Autogenerate some wait events code and documentation

Hi,

On 9/6/23 5:44 AM, Michael Paquier wrote:

On Wed, Sep 06, 2023 at 04:20:23AM +0200, Erik Wienhold wrote:

FYI: https://en.wikipedia.org/wiki/Sentence_spacing

That was an interesting read. Thanks.

+1, thanks!

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

#62Noah Misch
noah@leadboat.com
In reply to: Michael Paquier (#31)
Re: Autogenerate some wait events code and documentation

On Wed, Jul 05, 2023 at 10:57:19AM +0900, Michael Paquier wrote:

I have applied it.

I like the new developer experience of adding a wait event. After release of
v17, how should we approach back-patching an event, like was done in commits
8fa4a1a 1396b5c 78c0f85? Each of those commits put the new event at the end
of its released-branch wait_event.h enum. In v17,
generate-wait_event_types.pl sorts events to position them. Adding an event
will renumber others, which can make an extension report the wrong event until
recompiled. Extensions citus, pg_bulkload, and vector refer to static events.
If a back-patch added WAIT_EVENT_MESSAGE_QUEUE_SOMETHING_NEW, an old-build
pg_bulkload report of WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN would show up in
pg_stat_activity as WAIT_EVENT_PARALLEL_BITMAP_SCAN. (WAIT_EVENT_EXTENSION is
not part of a generated enum, fortunately.) Some options:

1. Don't back-patch wait events to v17+. Use the closest existing event.
2. Let wait_event_names.txt back-patches control the enum order. For example,
a line could have an annotation that controls its position relative to the
auto-sorted lines. For another example, the generator could stop sorting.
3. Accept the renumbering, because the consequence isn't that horrible.

Option (3) is worse than (1), but I don't have a recommendation between (1)
and (2). I tend to like (1), a concern being the ease of accidental
violations. If we had the ABI compliance checking that
/messages/by-id/flat/CAH2-Wzk7tvgLXzOZ8a22aF-gmO5gHojWTYRvAk5ZgOvTrcEQeg@mail.gmail.com
explored, (1) would be plenty safe. Should anything change here, or not?

#63Michael Paquier
michael@paquier.xyz
In reply to: Noah Misch (#62)
Re: Autogenerate some wait events code and documentation

On Sun, Mar 17, 2024 at 11:31:14AM -0700, Noah Misch wrote:

I like the new developer experience of adding a wait event. After release of
v17, how should we approach back-patching an event, like was done in commits
8fa4a1a 1396b5c 78c0f85? Each of those commits put the new event at the end
of its released-branch wait_event.h enum. In v17,
generate-wait_event_types.pl sorts events to position them.

Indeed, that would be a bad idea.

Adding an event
will renumber others, which can make an extension report the wrong event until
recompiled. Extensions citus, pg_bulkload, and vector refer to static events.
If a back-patch added WAIT_EVENT_MESSAGE_QUEUE_SOMETHING_NEW, an old-build
pg_bulkload report of WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN would show up in
pg_stat_activity as WAIT_EVENT_PARALLEL_BITMAP_SCAN. (WAIT_EVENT_EXTENSION is
not part of a generated enum, fortunately.) Some options:

1. Don't back-patch wait events to v17+. Use the closest existing event.
2. Let wait_event_names.txt back-patches control the enum order. For example,
a line could have an annotation that controls its position relative to the
auto-sorted lines. For another example, the generator could stop sorting.
3. Accept the renumbering, because the consequence isn't that horrible.

Option (3) is worse than (1), but I don't have a recommendation between (1)
and (2). I tend to like (1), a concern being the ease of accidental
violations. If we had the ABI compliance checking that
/messages/by-id/flat/CAH2-Wzk7tvgLXzOZ8a22aF-gmO5gHojWTYRvAk5ZgOvTrcEQeg@mail.gmail.com
explored, (1) would be plenty safe. Should anything change here, or not?

(1) would be annoying, we have backpatched scaling problems in the
past even if that does not happen often. And in some cases I can
understand why one would want to add a new wait event to track that
a patch does what is expected of it. (2) to stop the automated
sorting would bring back the problems that this thread has spent time
to solve: people tend to not add wait events correctly, so I would
suspect issues on HEAD. I've seen that too many times on older
branches.

I see an option (4), similar to your (2) without the per-line
annotation: add a new magic keyword like the existing "Section" that
is used in the first lines of generate-wait_event_types.pl where we
generate tab-separated lines with the section name as prefix of each
line. So I can think of something like:
Section: ClassName - WaitEventFoo
FOO_1 "Waiting in foo1"
FOO_2 "Waiting in foo2"
Backpatch:
BAR_1 "Waiting in bar1"
BAR_2 "Waiting in bar2"

Then force the ordering for the docs and keep the elements in the
backpatch section at the end of the enums in the order in the txt.
One thing that could make sense is to enforce that "Backpatch" is at
the end of a section, meaning that we would need a second keyword like
a "Section: EndBackpatch" or something like that. That's not strictly
necessary IMO as the format of the txt is easy to follow.
--
Michael

#64Noah Misch
noah@leadboat.com
In reply to: Michael Paquier (#63)
Re: Autogenerate some wait events code and documentation

On Mon, Mar 18, 2024 at 08:02:24AM +0900, Michael Paquier wrote:

1. Don't back-patch wait events to v17+. Use the closest existing event.
2. Let wait_event_names.txt back-patches control the enum order. For example,
a line could have an annotation that controls its position relative to the
auto-sorted lines. For another example, the generator could stop sorting.
3. Accept the renumbering, because the consequence isn't that horrible.

I see an option (4), similar to your (2) without the per-line
annotation: add a new magic keyword like the existing "Section" that
is used in the first lines of generate-wait_event_types.pl where we
generate tab-separated lines with the section name as prefix of each
line. So I can think of something like:
Section: ClassName - WaitEventFoo
FOO_1 "Waiting in foo1"
FOO_2 "Waiting in foo2"
Backpatch:
BAR_1 "Waiting in bar1"
BAR_2 "Waiting in bar2"

Then force the ordering for the docs and keep the elements in the
backpatch section at the end of the enums in the order in the txt.
One thing that could make sense is to enforce that "Backpatch" is at
the end of a section, meaning that we would need a second keyword like
a "Section: EndBackpatch" or something like that. That's not strictly
necessary IMO as the format of the txt is easy to follow.

Works for me, with or without the trailing keyword line.

#65Bertrand Drouvot
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#63)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On Mon, Mar 18, 2024 at 08:02:24AM +0900, Michael Paquier wrote:

On Sun, Mar 17, 2024 at 11:31:14AM -0700, Noah Misch wrote:

Adding an event
will renumber others, which can make an extension report the wrong event until
recompiled. Extensions citus, pg_bulkload, and vector refer to static events.
If a back-patch added WAIT_EVENT_MESSAGE_QUEUE_SOMETHING_NEW, an old-build
pg_bulkload report of WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN would show up in
pg_stat_activity as WAIT_EVENT_PARALLEL_BITMAP_SCAN. (WAIT_EVENT_EXTENSION is
not part of a generated enum, fortunately.)

Nice catch, thanks!

I see an option (4), similar to your (2) without the per-line
annotation: add a new magic keyword like the existing "Section" that
is used in the first lines of generate-wait_event_types.pl where we
generate tab-separated lines with the section name as prefix of each
line. So I can think of something like:
Section: ClassName - WaitEventFoo
FOO_1 "Waiting in foo1"
FOO_2 "Waiting in foo2"
Backpatch:
BAR_1 "Waiting in bar1"
BAR_2 "Waiting in bar2"

Then force the ordering for the docs and keep the elements in the
backpatch section at the end of the enums in the order in the txt.

Yeah I think that's a good idea.

One thing that could make sense is to enforce that "Backpatch" is at
the end of a section, meaning that we would need a second keyword like
a "Section: EndBackpatch" or something like that. That's not strictly
necessary IMO as the format of the txt is easy to follow.

I gave it a try in the POC patch attached. I did not use a "EndBackpatch"
section to keep the perl script as simple a possible though (but documented the
expectation instead).

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v1-0001-Add-a-Backpatch-section-in-wait_event_names.txt.patchtext/x-diff; charset=us-asciiDownload
From f93412201df9fa9156cee0b2492a25ac89ff0921 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Mon, 18 Mar 2024 08:34:19 +0000
Subject: [PATCH v1] Add a "Backpatch" section in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "Backpatch"
section added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 26 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 10 +++++--
 2 files changed, 33 insertions(+), 3 deletions(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..d129d94889 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @backpatch_lines;
 my @lines;
+my $backpatch = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,26 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$backpatch = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# Are we dealing with backpatch wait events?
+	if (/^Backpatch:$/)
+	{
+		$backpatch = 1;
+		next;
+	}
+
+	# Backpatch wait events won't be sorted during code generation
+	if ($gen_code && $backpatch)
+	{
+		push(@backpatch_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +88,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code then concat @lines_sorted and @backpatch_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @backpatch_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index c08e00d1d6..62c835df2e 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -24,7 +24,12 @@
 #      SGML tables of wait events for inclusion in the documentation.
 #
 # When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched to a version < 17 then
+# put it under a "Backpatch" delimiter at the end of the related ClassName
+# section.
+# Ensure that the wait events under the "Backpatch" delimiter are placed in the
+# same order as in the pre 17 wait_event_types.h (see VERSION_FILE_SYNC as an
+# example).
 #
 # WaitEventLWLock and WaitEventLock have their own C code for their wait event
 # enums and function names.  Hence, for these, only the SGML documentation is
@@ -239,7 +244,6 @@ TIMELINE_HISTORY_WRITE	"Waiting for a write of a newly created timeline history
 TWOPHASE_FILE_READ	"Waiting for a read of a two phase state file."
 TWOPHASE_FILE_SYNC	"Waiting for a two phase state file to reach durable storage."
 TWOPHASE_FILE_WRITE	"Waiting for a write of a two phase state file."
-VERSION_FILE_SYNC	"Waiting for the version file to reach durable storage while creating a database."
 VERSION_FILE_WRITE	"Waiting for the version file to be written while creating a database."
 WALSENDER_TIMELINE_HISTORY_READ	"Waiting for a read from a timeline history file during a walsender timeline command."
 WAL_BOOTSTRAP_SYNC	"Waiting for WAL to reach durable storage during bootstrapping."
@@ -256,6 +260,8 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+Backpatch:
+VERSION_FILE_SYNC	"Waiting for the version file to reach durable storage while creating a database."
 
 #
 # Wait Events - Buffer Pin
-- 
2.34.1

#66Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Michael Paquier (#49)
Re: Autogenerate some wait events code and documentation

On 2023-Aug-28, Michael Paquier wrote:

I have looked again at that, and switching wait_event_names.txt to use
two columns made of the typedef definitions and the docs like is not a
problem:
FOO_BAR "Waiting on Foo Bar."

WAIT_EVENT_ is appended to the typedef definitions in the script. The
wait event names like "FooBar" are generated from the enums by
splitting using their underscores and doing some lc(). Lock and
LWLock don't need to change. This way, it is easy to grep the wait
events from the source code and match them with wait_event_names.txt.

FTR I had a rather unpleasant time last week upon finding a wait event
named PgSleep. If you grep for that, there are no matches at all; and I
spent ten minutes (for real) trying to figure out where that was coming
from, until I remembered this thread.

Now you have to guess that not only random lowercasing is happening, but
also underscore removal. This is not a good developer experience and I
think we should rethink this choice. It would be infinitely more
usable, and not one bit more difficult, to make these lines be

WAIT_EVENT_FOO_BAR FooBar "Waiting on Foo Bar."

then there is no guessing involved.

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"The important things in the world are problems with society that we don't
understand at all. The machines will become more complicated but they won't
be more complicated than the societies that run them." (Freeman Dyson)

#67Noah Misch
noah@leadboat.com
In reply to: Bertrand Drouvot (#65)
Re: Autogenerate some wait events code and documentation

On Mon, Mar 18, 2024 at 09:04:44AM +0000, Bertrand Drouvot wrote:

--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -24,7 +24,12 @@
#      SGML tables of wait events for inclusion in the documentation.
#
# When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched to a version < 17 then
+# put it under a "Backpatch" delimiter at the end of the related ClassName
+# section.

Back-patch from v17 to pre-v17 won't use this, because v16 has hand-maintained
enums. It's back-patch v18->v17 or v22->v17 where this will come up.

+# Ensure that the wait events under the "Backpatch" delimiter are placed in the
+# same order as in the pre 17 wait_event_types.h (see VERSION_FILE_SYNC as an
+# example).

I expect the normal practice will be to put the entry in its natural position
in git master, then put it in the backpatch section for any other branch. In
other words, the backpatch regions are always empty in git master, and the
non-backpatch regions change in master only.

#68Bertrand Drouvot
bertranddrouvot.pg@gmail.com
In reply to: Noah Misch (#67)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On Mon, Mar 18, 2024 at 08:49:34AM -0700, Noah Misch wrote:

On Mon, Mar 18, 2024 at 09:04:44AM +0000, Bertrand Drouvot wrote:

--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -24,7 +24,12 @@
#      SGML tables of wait events for inclusion in the documentation.
#
# When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched to a version < 17 then
+# put it under a "Backpatch" delimiter at the end of the related ClassName
+# section.

Back-patch from v17 to pre-v17 won't use this, because v16 has hand-maintained
enums. It's back-patch v18->v17 or v22->v17 where this will come up.

Thanks for looking at it!
Oh right, the comment is wrong, re-worded in v2 attached.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v2-0001-Add-Backpatch-regions-in-wait_event_names.txt.patchtext/x-diff; charset=us-asciiDownload
From 868d97a853c45639685198c9090cedd77dc4b9af Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Mon, 18 Mar 2024 08:34:19 +0000
Subject: [PATCH v2] Add "Backpatch" regions in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "Backpatch"
region added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 26 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 19 +++++++++++++-
 2 files changed, 43 insertions(+), 2 deletions(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..d129d94889 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @backpatch_lines;
 my @lines;
+my $backpatch = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,26 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$backpatch = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# Are we dealing with backpatch wait events?
+	if (/^Backpatch:$/)
+	{
+		$backpatch = 1;
+		next;
+	}
+
+	# Backpatch wait events won't be sorted during code generation
+	if ($gen_code && $backpatch)
+	{
+		push(@backpatch_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +88,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code then concat @lines_sorted and @backpatch_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @backpatch_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index c08e00d1d6..b6303a0fdb 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -24,7 +24,11 @@
 #      SGML tables of wait events for inclusion in the documentation.
 #
 # When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched from master to a version
+# >= 17 then put it under a "Backpatch:" delimiter at the end of the related
+# ClassName section (on the non master branches) or at its natural position on
+# the master branch.
+# Ensure that the backpatch regions are always empty on the master branch.
 #
 # WaitEventLWLock and WaitEventLock have their own C code for their wait event
 # enums and function names.  Hence, for these, only the SGML documentation is
@@ -61,6 +65,7 @@ WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
 WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
+Backpatch:
 
 #
 # Wait Events - Client
@@ -82,6 +87,7 @@ WAIT_FOR_STANDBY_CONFIRMATION	"Waiting for WAL to be received and flushed by the
 WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
 WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
+Backpatch:
 
 #
 # Wait Events - IPC
@@ -149,6 +155,7 @@ WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for st
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
+Backpatch:
 
 #
 # Wait Events - Timeout
@@ -169,6 +176,7 @@ VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
 VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 WAL_SUMMARIZER_ERROR	"Waiting after a WAL summarizer error."
 
+Backpatch:
 
 #
 # Wait Events - IO
@@ -256,6 +264,7 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+Backpatch:
 
 #
 # Wait Events - Buffer Pin
@@ -265,6 +274,7 @@ Section: ClassName - WaitEventBufferPin
 
 BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
+Backpatch:
 
 #
 # Wait Events - Extension
@@ -274,6 +284,8 @@ Section: ClassName - WaitEventExtension
 
 Extension	"Waiting in an extension."
 
+Backpatch:
+
 #
 # Wait Events - LWLock
 #
@@ -330,6 +342,8 @@ DSMRegistry	"Waiting to read or update the dynamic shared memory registry."
 InjectionPoint	"Waiting to read or update information related to injection points."
 SerialControl	"Waiting to read or update shared <filename>pg_serial</filename> state."
 
+# Don't create a Backpatch region here.
+
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
 #
@@ -377,6 +391,7 @@ SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
 SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
 XactSLRU	"Waiting to access the transaction status SLRU cache."
 
+# Don't create a Backpatch region here.
 
 #
 # Wait Events - Lock
@@ -399,3 +414,5 @@ object	"Waiting to acquire a lock on a non-relation database object."
 userlock	"Waiting to acquire a user lock."
 advisory	"Waiting to acquire an advisory user lock."
 applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
+
+Backpatch:
-- 
2.34.1

#69Michael Paquier
michael@paquier.xyz
In reply to: Noah Misch (#67)
Re: Autogenerate some wait events code and documentation

On Mon, Mar 18, 2024 at 08:49:34AM -0700, Noah Misch wrote:

On Mon, Mar 18, 2024 at 09:04:44AM +0000, Bertrand Drouvot wrote:

+# Ensure that the wait events under the "Backpatch" delimiter are placed in the
+# same order as in the pre 17 wait_event_types.h (see VERSION_FILE_SYNC as an
+# example).

I expect the normal practice will be to put the entry in its natural position
in git master, then put it in the backpatch section for any other branch. In
other words, the backpatch regions are always empty in git master, and the
non-backpatch regions change in master only.

Yes, I'd expect the same experience. And it is very important to
document that properly in the txt file. I don't see a need to specify
any version numbers as well, that's less burden when bumping the major
version number on the master branch every year.
--
Michael

#70Michael Paquier
michael@paquier.xyz
In reply to: Alvaro Herrera (#66)
Re: Autogenerate some wait events code and documentation

On Mon, Mar 18, 2024 at 10:24:00AM +0100, Alvaro Herrera wrote:

FTR I had a rather unpleasant time last week upon finding a wait event
named PgSleep. If you grep for that, there are no matches at all; and I
spent ten minutes (for real) trying to figure out where that was coming
from, until I remembered this thread.

Now you have to guess that not only random lowercasing is happening, but
also underscore removal. This is not a good developer experience and I
think we should rethink this choice. It would be infinitely more
usable, and not one bit more difficult, to make these lines be

WAIT_EVENT_FOO_BAR FooBar "Waiting on Foo Bar."

then there is no guessing involved.

This has already gone through a couple of adjustments in 59cbf60c0f2b
and 183a60a628fe. The latter has led to the elimination of one column
in the txt file, as a reply to the same kind of comments about the
format of this file:
/messages/by-id/20230705215939.ulnfbr4zavb2x7ri@awork3.anarazel.de

FWIW, I still like better what we have currently, where it is possible
to grep the enum values in the source code.
--
Michael

#71Michael Paquier
michael@paquier.xyz
In reply to: Bertrand Drouvot (#68)
Re: Autogenerate some wait events code and documentation

On Mon, Mar 18, 2024 at 05:57:02PM +0000, Bertrand Drouvot wrote:

Thanks for looking at it!
Oh right, the comment is wrong, re-worded in v2 attached.

I've added a couple of fake events in my txt file, and this results in
an ordering of the wait events in the docs while the backpatched wait
events are added at the end of the enums, based on their order in the
txt file.

 # When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched from master to a version
+# >= 17 then put it under a "Backpatch:" delimiter at the end of the related
+# ClassName section (on the non master branches) or at its natural position on
+# the master branch.
+# Ensure that the backpatch regions are always empty on the master branch.

I'd recommend to not mention a version number at all, as this would
need a manual refresh each time a new stable branch is forked.

Your solution is simpler than what I finished in mind when looking at
the code yesterday, with the addition of a second array that's pushed
to be at the end of the "sorted" lines ordered by the second column.
That does the job.

(Note that I'll go silent for some time; I'll handle this thread when
I get back as this is not urgent.)
--
Michael

#72Bertrand Drouvot
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#71)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On Tue, Mar 19, 2024 at 09:59:35AM +0900, Michael Paquier wrote:

On Mon, Mar 18, 2024 at 05:57:02PM +0000, Bertrand Drouvot wrote:

Thanks for looking at it!
Oh right, the comment is wrong, re-worded in v2 attached.

I've added a couple of fake events in my txt file, and this results in
an ordering of the wait events in the docs while the backpatched wait
events are added at the end of the enums, based on their order in the
txt file.

Thanks for testing!

# When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. If the wait event is backpatched from master to a version
+# >= 17 then put it under a "Backpatch:" delimiter at the end of the related
+# ClassName section (on the non master branches) or at its natural position on
+# the master branch.
+# Ensure that the backpatch regions are always empty on the master branch.

I'd recommend to not mention a version number at all, as this would
need a manual refresh each time a new stable branch is forked.

I'm not sure as v2 used the "version >= 17" wording which I think would not need
manual refresh each time a new stable branch is forked.

But to avoid any doubt, I'm following your recommendation in v3 attached (then
only mentioning the "master branch" and "any other branch").

Your solution is simpler than what I finished in mind when looking at
the code yesterday, with the addition of a second array that's pushed
to be at the end of the "sorted" lines ordered by the second column.
That does the job.

Yeah.

(Note that I'll go silent for some time; I'll handle this thread when
I get back as this is not urgent.)

Right and enjoy!

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v3-0001-Add-Backpatch-regions-in-wait_event_names.txt.patchtext/x-diff; charset=us-asciiDownload
From 8755162399faa070cbcb56bb4687f1ca1df6b4b1 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Mon, 18 Mar 2024 08:34:19 +0000
Subject: [PATCH v3] Add "Backpatch" regions in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "Backpatch"
region added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 26 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 18 ++++++++++++-
 2 files changed, 42 insertions(+), 2 deletions(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..d129d94889 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @backpatch_lines;
 my @lines;
+my $backpatch = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,26 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$backpatch = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# Are we dealing with backpatch wait events?
+	if (/^Backpatch:$/)
+	{
+		$backpatch = 1;
+		next;
+	}
+
+	# Backpatch wait events won't be sorted during code generation
+	if ($gen_code && $backpatch)
+	{
+		push(@backpatch_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +88,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code then concat @lines_sorted and @backpatch_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @backpatch_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index c08e00d1d6..0c4788fe77 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -24,7 +24,10 @@
 #      SGML tables of wait events for inclusion in the documentation.
 #
 # When adding a new wait event, make sure it is placed in the appropriate
-# ClassName section.
+# ClassName section. Put it in its natural position in the master branch, and
+# then put it in the "Backpatch:" region for any other branch (should the wait
+# event be backpatched).
+# Ensure that the backpatch regions are always empty on the master branch.
 #
 # WaitEventLWLock and WaitEventLock have their own C code for their wait event
 # enums and function names.  Hence, for these, only the SGML documentation is
@@ -61,6 +64,7 @@ WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
 WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
+Backpatch:
 
 #
 # Wait Events - Client
@@ -82,6 +86,7 @@ WAIT_FOR_STANDBY_CONFIRMATION	"Waiting for WAL to be received and flushed by the
 WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
 WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
+Backpatch:
 
 #
 # Wait Events - IPC
@@ -149,6 +154,7 @@ WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for st
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
+Backpatch:
 
 #
 # Wait Events - Timeout
@@ -169,6 +175,7 @@ VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
 VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 WAL_SUMMARIZER_ERROR	"Waiting after a WAL summarizer error."
 
+Backpatch:
 
 #
 # Wait Events - IO
@@ -256,6 +263,7 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+Backpatch:
 
 #
 # Wait Events - Buffer Pin
@@ -265,6 +273,7 @@ Section: ClassName - WaitEventBufferPin
 
 BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
+Backpatch:
 
 #
 # Wait Events - Extension
@@ -274,6 +283,8 @@ Section: ClassName - WaitEventExtension
 
 Extension	"Waiting in an extension."
 
+Backpatch:
+
 #
 # Wait Events - LWLock
 #
@@ -330,6 +341,8 @@ DSMRegistry	"Waiting to read or update the dynamic shared memory registry."
 InjectionPoint	"Waiting to read or update information related to injection points."
 SerialControl	"Waiting to read or update shared <filename>pg_serial</filename> state."
 
+# Don't create a Backpatch region here.
+
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
 #
@@ -377,6 +390,7 @@ SerialSLRU	"Waiting to access the serializable transaction conflict SLRU cache."
 SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
 XactSLRU	"Waiting to access the transaction status SLRU cache."
 
+# Don't create a Backpatch region here.
 
 #
 # Wait Events - Lock
@@ -399,3 +413,5 @@ object	"Waiting to acquire a lock on a non-relation database object."
 userlock	"Waiting to acquire a user lock."
 advisory	"Waiting to acquire an advisory user lock."
 applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
+
+Backpatch:
-- 
2.34.1

#73Michael Paquier
michael@paquier.xyz
In reply to: Bertrand Drouvot (#72)
2 attachment(s)
Re: Autogenerate some wait events code and documentation

On Tue, Mar 19, 2024 at 07:34:09AM +0000, Bertrand Drouvot wrote:

I'm not sure as v2 used the "version >= 17" wording which I think would not need
manual refresh each time a new stable branch is forked.

But to avoid any doubt, I'm following your recommendation in v3 attached (then
only mentioning the "master branch" and "any other branch").

I don't see why we could not be more generic, TBH. Note that the
Backpatch region should be empty not only the master branch but also
on stable and unreleased branches (aka REL_XX_STABLE branches from
their fork from master to their .0 release). I have reworded the
whole, mentioning ABI compatibility, as well.

The position of the Backpatch regions were a bit incorrect (extra one
in LWLock, and the one in Lock was not needed).

We could be stricter with the order of the elements in
pgstat_wait_event.c and wait_event_funcs_data.c, but there's no
consequence feature-wise and I cannot get excited about the extra
complexity this creates in generate-wait_event_types.pl between the
enum generation and the rest.

Is "Backpatch" the best choice we have, though? It speaks by itself
but I was thinking about something different, like "Stable". Other
ideas or objections are welcome. My naming sense is usually not that
good, so there's that.

0001 is the patch with my tweaks. 0002 includes some dummy test data
I've used to validate the whole.
--
Michael

Attachments:

v3-0001-Add-Backpatch-regions-in-wait_event_names.txt.patchtext/x-diff; charset=us-asciiDownload
From 7579d48b61ca17f7114b517ab88aabf30c99b64d Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 4 Apr 2024 15:34:37 +0900
Subject: [PATCH v3 1/2] Add "Backpatch" regions in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "Backpatch"
region added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 27 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 20 +++++++++++++-
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..456a00b86a 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @backpatch_lines;
 my @lines;
+my $backpatch = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,27 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$backpatch = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# Backpatch region, preserving ABI compatibility of the code
+	# generated.  Any wait events listed in this part of the file
+	# will not be sorted during the code generation.
+	if (/^Backpatch:$/)
+	{
+		$backpatch = 1;
+		next;
+	}
+
+	if ($gen_code && $backpatch)
+	{
+		push(@backpatch_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +89,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code, concat @lines_sorted and then @backpatch_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @backpatch_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0d288d6b3d..5afa4d4839 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -26,6 +26,12 @@
 # When adding a new wait event, make sure it is placed in the appropriate
 # ClassName section.
 #
+# Wait events added in stable branches should be appended to the lists in
+# the "Backpatch:" region of their related ClassName section to preserve
+# ABI compatibility of the C code generated from this file's data, respecting
+# the order of any wait event already listed there.  The "Backpatch:" regions
+# should remain empty on the master branch and on unreleased branches.
+#
 # 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.
@@ -61,6 +67,7 @@ WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
 WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
+Backpatch:
 
 #
 # Wait Events - Client
@@ -81,8 +88,10 @@ SSL_OPEN_SERVER	"Waiting for SSL while attempting connection."
 WAIT_FOR_STANDBY_CONFIRMATION	"Waiting for WAL to be received and flushed by the physical standby."
 WAIT_FOR_WAL_REPLAY	"Waiting for a replay of the particular WAL position on the physical standby."
 WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
-WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
+WAL_SENDER_WRITE_ZZZ	"Waiting for wal sender write ZZ."
+WAL_SENDER_WRITE_DATA	"Waiting for wal sender write data."
 
+Backpatch:
 
 #
 # Wait Events - IPC
@@ -150,6 +159,7 @@ WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for st
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
+Backpatch:
 
 #
 # Wait Events - Timeout
@@ -170,6 +180,7 @@ VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
 VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 WAL_SUMMARIZER_ERROR	"Waiting after a WAL summarizer error."
 
+Backpatch:
 
 #
 # Wait Events - IO
@@ -257,6 +268,7 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+Backpatch:
 
 #
 # Wait Events - Buffer Pin
@@ -266,6 +278,7 @@ Section: ClassName - WaitEventBufferPin
 
 BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
+Backpatch:
 
 #
 # Wait Events - Extension
@@ -275,6 +288,8 @@ Section: ClassName - WaitEventExtension
 
 Extension	"Waiting in an extension."
 
+Backpatch:
+
 #
 # Wait Events - LWLock
 #
@@ -379,6 +394,7 @@ SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
 XactSLRU	"Waiting to access the transaction status SLRU cache."
 ParallelVacuumDSA	"Waiting for parallel vacuum dynamic shared memory allocation."
 
+# No "Backpatch" region here as code is generated automatically.
 
 #
 # Wait Events - Lock
@@ -401,3 +417,5 @@ object	"Waiting to acquire a lock on a non-relation database object."
 userlock	"Waiting to acquire a user lock."
 advisory	"Waiting to acquire an advisory user lock."
 applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
+
+# No "Backpatch" region here as code is generated automatically.
-- 
2.43.0

v3-0002-Add-some-dummy-tests.patchtext/x-diff; charset=us-asciiDownload
From 05565c750d0f20ce12ebb579f4789ab1d275eab6 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 4 Apr 2024 15:35:27 +0900
Subject: [PATCH v3 2/2] Add some dummy tests

---
 src/backend/utils/activity/wait_event_names.txt | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 5afa4d4839..8abc22981a 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -68,6 +68,11 @@ WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
 Backpatch:
+2_WAL_SENDER_WRITE_FO	"Waiting for fo."
+2_FOO_BAR_3	"Popo bar 3."
+2_FOO_BAR_2	"Popo bar 2."
+2_ZZZ	"Waiting in zzz."
+2_XXX	"Waiting in XXX."
 
 #
 # Wait Events - Client
@@ -92,6 +97,11 @@ WAL_SENDER_WRITE_ZZZ	"Waiting for wal sender write ZZ."
 WAL_SENDER_WRITE_DATA	"Waiting for wal sender write data."
 
 Backpatch:
+WAL_SENDER_WRITE_FOO	"Waiting for wal sender write foo."
+FOO_BAR_3	"Waiting for foo bar 3."
+FOO_BAR_2	"Waiting for foo bar 2."
+ZZZ	"Waiting for zzz."
+XXX	"Waiting for XXX."
 
 #
 # Wait Events - IPC
-- 
2.43.0

#74Bertrand Drouvot
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#73)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On Thu, Apr 04, 2024 at 03:50:21PM +0900, Michael Paquier wrote:

On Tue, Mar 19, 2024 at 07:34:09AM +0000, Bertrand Drouvot wrote:

I'm not sure as v2 used the "version >= 17" wording which I think would not need
manual refresh each time a new stable branch is forked.

But to avoid any doubt, I'm following your recommendation in v3 attached (then
only mentioning the "master branch" and "any other branch").

I don't see why we could not be more generic, TBH. Note that the
Backpatch region should be empty not only the master branch but also
on stable and unreleased branches (aka REL_XX_STABLE branches from
their fork from master to their .0 release). I have reworded the
whole, mentioning ABI compatibility, as well.

Yeah, agree. I do prefer your wording.

The position of the Backpatch regions were a bit incorrect (extra one
in LWLock, and the one in Lock was not needed).

oops, thanks for the fixes!

We could be stricter with the order of the elements in
pgstat_wait_event.c and wait_event_funcs_data.c, but there's no
consequence feature-wise and I cannot get excited about the extra
complexity this creates in generate-wait_event_types.pl between the
enum generation and the rest.

Yeah, and I think generate-wait_event_types.pl is already complex enough.
So better to add only the strict necessary in it IMHO.

Is "Backpatch" the best choice we have, though? It speaks by itself
but I was thinking about something different, like "Stable". Other
ideas or objections are welcome. My naming sense is usually not that
good, so there's that.

I think "Stable" is more confusing because the section should also be empty until
the .0 is released.

That said, what about "ABI_compatibility"? (that would also match the comment
added in wait_event_names.txt). Attached v4 making use of the ABI_compatibility
proposal.

0001 is the patch with my tweaks.

Thanks!

+# No "Backpatch" region here as code is generated automatically.

What about "....region here as has its own C code" (that would be more consistent
with the comment in the "header" for the file). Done that way in v4.

It looks like WAL_SENDER_WRITE_ZZZ was also added in it (I guess for testing
purpose, so I removed it in v4).

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v4-0001-Add-ABI_compatibility-regions-in-wait_event_names.patchtext/x-diff; charset=us-asciiDownload
From 4a69b8adb9bef2a5c7f7bec061d0bdda95ad9e24 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 4 Apr 2024 15:34:37 +0900
Subject: [PATCH v4] Add "ABI_compatibility" regions in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "ABI_compatibility"
region added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 27 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 17 ++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..9768406db5 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @abi_compatibility_lines;
 my @lines;
+my $abi_compatibility = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,27 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$abi_compatibility = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# ABI_compatibility region, preserving ABI compatibility of the code
+	# generated.  Any wait events listed in this part of the file
+	# will not be sorted during the code generation.
+	if (/^ABI_compatibility:$/)
+	{
+		$abi_compatibility = 1;
+		next;
+	}
+
+	if ($gen_code && $abi_compatibility)
+	{
+		push(@abi_compatibility_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +89,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code, concat @lines_sorted and then @abi_compatibility_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @abi_compatibility_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0d288d6b3d..fbb5dae5ea 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -26,6 +26,12 @@
 # When adding a new wait event, make sure it is placed in the appropriate
 # ClassName section.
 #
+# Wait events added in stable branches should be appended to the lists in
+# the "ABI_compatibility:" region of their related ClassName section to preserve
+# ABI compatibility of the C code generated from this file's data, respecting
+# the order of any wait event already listed there.  The "ABI_compatibility:"
+# regions should remain empty on the master branch and on unreleased branches.
+#
 # 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.
@@ -61,6 +67,7 @@ WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
 WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
+ABI_compatibility:
 
 #
 # Wait Events - Client
@@ -83,6 +90,7 @@ WAIT_FOR_WAL_REPLAY	"Waiting for a replay of the particular WAL position on the
 WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
 WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
+ABI_compatibility:
 
 #
 # Wait Events - IPC
@@ -150,6 +158,7 @@ WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for st
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
+ABI_compatibility:
 
 #
 # Wait Events - Timeout
@@ -170,6 +179,7 @@ VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
 VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 WAL_SUMMARIZER_ERROR	"Waiting after a WAL summarizer error."
 
+ABI_compatibility:
 
 #
 # Wait Events - IO
@@ -257,6 +267,7 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+ABI_compatibility:
 
 #
 # Wait Events - Buffer Pin
@@ -266,6 +277,7 @@ Section: ClassName - WaitEventBufferPin
 
 BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
+ABI_compatibility:
 
 #
 # Wait Events - Extension
@@ -275,6 +287,8 @@ Section: ClassName - WaitEventExtension
 
 Extension	"Waiting in an extension."
 
+ABI_compatibility:
+
 #
 # Wait Events - LWLock
 #
@@ -379,6 +393,7 @@ SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
 XactSLRU	"Waiting to access the transaction status SLRU cache."
 ParallelVacuumDSA	"Waiting for parallel vacuum dynamic shared memory allocation."
 
+# No "ABI_compatibility" region here as has its own C code.
 
 #
 # Wait Events - Lock
@@ -401,3 +416,5 @@ object	"Waiting to acquire a lock on a non-relation database object."
 userlock	"Waiting to acquire a user lock."
 advisory	"Waiting to acquire an advisory user lock."
 applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
+
+# No "ABI_compatibility" region here as has its own C code.
-- 
2.34.1

#75Michael Paquier
michael@paquier.xyz
In reply to: Bertrand Drouvot (#74)
Re: Autogenerate some wait events code and documentation

On Thu, Apr 04, 2024 at 09:28:36AM +0000, Bertrand Drouvot wrote:

On Thu, Apr 04, 2024 at 03:50:21PM +0900, Michael Paquier wrote:

Is "Backpatch" the best choice we have, though? It speaks by itself
but I was thinking about something different, like "Stable". Other
ideas or objections are welcome. My naming sense is usually not that
good, so there's that.

I think "Stable" is more confusing because the section should also be empty until
the .0 is released.

Okay.

That said, what about "ABI_compatibility"? (that would also match the comment
added in wait_event_names.txt). Attached v4 making use of the ABI_compatibility
proposal.

I'm OK with that. If somebody comes up wiht a better name than that,
this could always be changed again.

+# No "Backpatch" region here as code is generated automatically.

What about "....region here as has its own C code" (that would be more consistent
with the comment in the "header" for the file). Done that way in v4.

I'd add a "as -this section- has its own C code", for clarity. This
just looked a bit strange here.

It looks like WAL_SENDER_WRITE_ZZZ was also added in it (I guess for testing
purpose, so I removed it in v4).

That's a good brain fade. Thanks.
--
Michael

#76Bertrand Drouvot
bertranddrouvot.pg@gmail.com
In reply to: Michael Paquier (#75)
1 attachment(s)
Re: Autogenerate some wait events code and documentation

Hi,

On Thu, Apr 04, 2024 at 07:14:47PM +0900, Michael Paquier wrote:

On Thu, Apr 04, 2024 at 09:28:36AM +0000, Bertrand Drouvot wrote:

+# No "Backpatch" region here as code is generated automatically.

What about "....region here as has its own C code" (that would be more consistent
with the comment in the "header" for the file). Done that way in v4.

I'd add a "as -this section- has its own C code", for clarity. This
just looked a bit strange here.

Sounds good, done that way in v5 attached.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

Attachments:

v5-0001-Add-ABI_compatibility-regions-in-wait_event_names.patchtext/x-diff; charset=us-asciiDownload
From 1e24cdb02360147363495122fbfe79c2758ae4e8 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 4 Apr 2024 15:34:37 +0900
Subject: [PATCH v5] Add "ABI_compatibility" regions in wait_event_names.txt

When backpatching, adding an event will renumber others, which can make an
extension report the wrong event until recompiled. This is due to the fact that
generate-wait_event_types.pl sorts events to position them. The "ABI_compatibility"
region added here ensures no ordering is done for the wait events found after
this delimiter.
---
 .../activity/generate-wait_event_types.pl     | 27 ++++++++++++++++++-
 .../utils/activity/wait_event_names.txt       | 17 ++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
 100.0% src/backend/utils/activity/

diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index f1adf0e8e7..9768406db5 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -38,7 +38,9 @@ die "Not possible to specify --docs and --code simultaneously"
 
 open my $wait_event_names, '<', $ARGV[0] or die;
 
+my @abi_compatibility_lines;
 my @lines;
+my $abi_compatibility = 0;
 my $section_name;
 my $note;
 my $note_name;
@@ -59,10 +61,27 @@ while (<$wait_event_names>)
 	{
 		$section_name = $_;
 		$section_name =~ s/^.*- //;
+		$abi_compatibility = 0;
 		next;
 	}
 
-	push(@lines, $section_name . "\t" . $_);
+	# ABI_compatibility region, preserving ABI compatibility of the code
+	# generated.  Any wait events listed in this part of the file
+	# will not be sorted during the code generation.
+	if (/^ABI_compatibility:$/)
+	{
+		$abi_compatibility = 1;
+		next;
+	}
+
+	if ($gen_code && $abi_compatibility)
+	{
+		push(@abi_compatibility_lines, $section_name . "\t" . $_);
+	}
+	else
+	{
+		push(@lines, $section_name . "\t" . $_);
+	}
 }
 
 # Sort the lines based on the second column.
@@ -70,6 +89,12 @@ while (<$wait_event_names>)
 my @lines_sorted =
   sort { uc((split(/\t/, $a))[1]) cmp uc((split(/\t/, $b))[1]) } @lines;
 
+# If we are generating code, concat @lines_sorted and then @abi_compatibility_lines.
+if ($gen_code)
+{
+	push(@lines_sorted, @abi_compatibility_lines);
+}
+
 # Read the sorted lines and populate the hash table
 foreach my $line (@lines_sorted)
 {
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0d288d6b3d..5169be238c 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -26,6 +26,12 @@
 # When adding a new wait event, make sure it is placed in the appropriate
 # ClassName section.
 #
+# Wait events added in stable branches should be appended to the lists in
+# the "ABI_compatibility:" region of their related ClassName section to preserve
+# ABI compatibility of the C code generated from this file's data, respecting
+# the order of any wait event already listed there.  The "ABI_compatibility:"
+# regions should remain empty on the master branch and on unreleased branches.
+#
 # 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.
@@ -61,6 +67,7 @@ WAL_SENDER_MAIN	"Waiting in main loop of WAL sender process."
 WAL_SUMMARIZER_WAL	"Waiting in WAL summarizer for more WAL to be generated."
 WAL_WRITER_MAIN	"Waiting in main loop of WAL writer process."
 
+ABI_compatibility:
 
 #
 # Wait Events - Client
@@ -83,6 +90,7 @@ WAIT_FOR_WAL_REPLAY	"Waiting for a replay of the particular WAL position on the
 WAL_SENDER_WAIT_FOR_WAL	"Waiting for WAL to be flushed in WAL sender process."
 WAL_SENDER_WRITE_DATA	"Waiting for any activity when processing replies from WAL receiver in WAL sender process."
 
+ABI_compatibility:
 
 #
 # Wait Events - IPC
@@ -150,6 +158,7 @@ WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for st
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at end of a parallel operation."
 
+ABI_compatibility:
 
 #
 # Wait Events - Timeout
@@ -170,6 +179,7 @@ VACUUM_DELAY	"Waiting in a cost-based vacuum delay point."
 VACUUM_TRUNCATE	"Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed."
 WAL_SUMMARIZER_ERROR	"Waiting after a WAL summarizer error."
 
+ABI_compatibility:
 
 #
 # Wait Events - IO
@@ -257,6 +267,7 @@ WAL_SYNC	"Waiting for a WAL file to reach durable storage."
 WAL_SYNC_METHOD_ASSIGN	"Waiting for data to reach durable storage while assigning a new WAL sync method."
 WAL_WRITE	"Waiting for a write to a WAL file."
 
+ABI_compatibility:
 
 #
 # Wait Events - Buffer Pin
@@ -266,6 +277,7 @@ Section: ClassName - WaitEventBufferPin
 
 BUFFER_PIN	"Waiting to acquire an exclusive pin on a buffer."
 
+ABI_compatibility:
 
 #
 # Wait Events - Extension
@@ -275,6 +287,8 @@ Section: ClassName - WaitEventExtension
 
 Extension	"Waiting in an extension."
 
+ABI_compatibility:
+
 #
 # Wait Events - LWLock
 #
@@ -379,6 +393,7 @@ SubtransSLRU	"Waiting to access the sub-transaction SLRU cache."
 XactSLRU	"Waiting to access the transaction status SLRU cache."
 ParallelVacuumDSA	"Waiting for parallel vacuum dynamic shared memory allocation."
 
+# No "ABI_compatibility" region here as WaitEventLWLock has its own C code.
 
 #
 # Wait Events - Lock
@@ -401,3 +416,5 @@ object	"Waiting to acquire a lock on a non-relation database object."
 userlock	"Waiting to acquire a user lock."
 advisory	"Waiting to acquire an advisory user lock."
 applytransaction	"Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber."
+
+# No "ABI_compatibility" region here as WaitEventLock has its own C code.
-- 
2.34.1

#77Michael Paquier
michael@paquier.xyz
In reply to: Bertrand Drouvot (#76)
Re: Autogenerate some wait events code and documentation

On Thu, Apr 04, 2024 at 11:56:36AM +0000, Bertrand Drouvot wrote:

On Thu, Apr 04, 2024 at 07:14:47PM +0900, Michael Paquier wrote:

I'd add a "as -this section- has its own C code", for clarity. This
just looked a bit strange here.

Sounds good, done that way in v5 attached.

If there's a better suggestion than "ABI_compatibility" as keyword for
this part of the file, this could always be changed later. For now,
I've applied what you have here after tweaking a bit more the
comments.
--
Michael