From 5916f5442c53769ea98a292aa71f14e687fa7543 Mon Sep 17 00:00:00 2001 From: Jakub Wartak Date: Thu, 8 Jan 2026 14:34:53 +0100 Subject: [PATCH v4 4/6] Expose meaning of new per-wait wait_event_arg through pg_wait_events and docs Add description of meaning to the core wait_event_names.txt as 4-th column. Alter generate-wait_event_types.pl script so that it can generate proper structure(s) that are used by SGML documentation and pg_wait_events view. Author: Jakub Wartak Reviewed-by: Discussion: https://www.postgresql.org/message-id/flat/CAKZiRmyKcTaeSGzMYDN6aRR-BwYGPeZbzDRKvGkJhxAghfb4LQ%40mail.gmail.com --- .../activity/generate-wait_event_types.pl | 29 ++++++++++++++----- src/backend/utils/activity/wait_event_funcs.c | 8 +++-- .../utils/activity/wait_event_names.txt | 16 +++++----- src/include/catalog/pg_proc.dat | 4 +-- src/test/regress/expected/rules.out | 5 ++-- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl index 938ca47f868..067d0d7ba4a 100644 --- a/src/backend/utils/activity/generate-wait_event_types.pl +++ b/src/backend/utils/activity/generate-wait_event_types.pl @@ -97,10 +97,11 @@ if ($gen_code) foreach my $line (@lines_sorted) { die "unable to parse wait_event_names.txt for line $line\n" - unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*\.")$/; + unless $line =~ /^(\w+)\t+(\w+)\t+("\w.*?")(?:\t+("\w.*"))?$/; - (my $waitclassname, my $waiteventname, my $waitevendocsentence) = - ($1, $2, $3); + (my $waitclassname, my $waiteventname, my $waitevendocsentence, my $waiteventargdesc) = + ($1, $2, $3, $4); + $waiteventargdesc = "" if !defined($waiteventargdesc); # Generate the element name for the enums based on the # description. The C symbols are prefixed with "WAIT_EVENT_". @@ -126,7 +127,7 @@ foreach my $line (@lines_sorted) # Store the event into the list for each class. my @waiteventlist = - [ $waiteventenumname, $waiteventdescription, $waitevendocsentence ]; + [ $waiteventenumname, $waiteventdescription, $waitevendocsentence, $waiteventargdesc ]; push(@{ $hashwe{$waitclassname} }, @waiteventlist); } @@ -257,8 +258,11 @@ if ($gen_code) foreach my $wev (@{ $hashwe{$waitclass} }) { my $new_desc = substr $wev->[2], 1, -2; + my $waiteventargdesc = $wev->[3]; + # Escape single quotes. $new_desc =~ s/'/\\'/g; + $waiteventargdesc =~ s/"//g; # Replace the "quote" markups by real ones. $new_desc =~ s/(.*?)<\/quote>/\\"$1\\"/g; @@ -279,9 +283,9 @@ if ($gen_code) $new_desc =~ s/; see.*$//; # Build one element of the C structure holding the - # wait event info, as of (type, name, description). - printf $wc "\t{\"%s\", \"%s\", \"%s\"},\n", $last, $wev->[1], - $new_desc; + # wait event info, as of (type, name, description, waiteventargdesc). + printf $wc "\t{\"%s\", \"%s\", \"%s\", \"%s\"},\n", $last, $wev->[1], + $new_desc, $waiteventargdesc; } } @@ -315,22 +319,31 @@ elsif ($gen_docs) printf $s " Wait Events of Type <literal>%s</literal>\n", ucfirst($lastlc); - printf $s " \n"; + printf $s " \n"; printf $s " \n"; printf $s " \n"; printf $s " $last Wait Event\n"; printf $s " Description\n"; + printf $s " wait_event_arg description (optional)\n"; printf $s " \n"; printf $s " \n\n"; printf $s " \n"; foreach my $wev (@{ $hashwe{$waitclass} }) { + my $waiteventargdesc = $wev->[3]; + if (defined($waiteventargdesc)) { + $waiteventargdesc =~ s/\"//g; + } else { + $waiteventargdesc = ""; + } + printf $s " \n"; printf $s " %s\n", $wev->[1]; printf $s " %s\n", substr $wev->[2], 1, -1; + printf $s " %s\n", $waiteventargdesc; printf $s " \n"; } diff --git a/src/backend/utils/activity/wait_event_funcs.c b/src/backend/utils/activity/wait_event_funcs.c index fa10a80b088..5a33e9dae78 100644 --- a/src/backend/utils/activity/wait_event_funcs.c +++ b/src/backend/utils/activity/wait_event_funcs.c @@ -27,13 +27,14 @@ static const struct const char *type; const char *name; const char *description; + const char *waiteventargdesc; } waitEventData[] = { #include "utils/wait_event_funcs_data.c" /* end of list */ - {NULL, NULL, NULL} + {NULL, NULL, NULL, NULL} }; @@ -45,7 +46,7 @@ static const struct Datum pg_get_wait_events(PG_FUNCTION_ARGS) { -#define PG_GET_WAIT_EVENTS_COLS 3 +#define PG_GET_WAIT_EVENTS_COLS 4 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; char **waiteventnames; int nbwaitevents; @@ -62,6 +63,7 @@ pg_get_wait_events(PG_FUNCTION_ARGS) values[0] = CStringGetTextDatum(waitEventData[idx].type); values[1] = CStringGetTextDatum(waitEventData[idx].name); values[2] = CStringGetTextDatum(waitEventData[idx].description); + values[3] = CStringGetTextDatum(waitEventData[idx].waiteventargdesc); tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } @@ -86,6 +88,7 @@ pg_get_wait_events(PG_FUNCTION_ARGS) waiteventnames[idx]); values[2] = CStringGetTextDatum(buf.data); + nulls[3] = true; tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } @@ -110,6 +113,7 @@ pg_get_wait_events(PG_FUNCTION_ARGS) waiteventnames[idx]); values[2] = CStringGetTextDatum(buf.data); + nulls[3] = true; tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index cdb76832805..5438e048f0b 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -8,9 +8,9 @@ # related to wait events. # # This file defines one wait event per line, with the following -# tab-separated fields: +# tab-separated fields (the wait_event_arg description is optional): # -# "Typedef enum definitions" "description in the docs" +# "Typedef enum definitions" "desc in the docs" "desc of the wait_event_arg"" # # The files generated from this one are: # @@ -158,7 +158,7 @@ REPLICATION_ORIGIN_DROP "Waiting for a replication origin to become inactive so REPLICATION_SLOT_DROP "Waiting for a replication slot to become inactive so it can be dropped." RESTORE_COMMAND "Waiting for to complete." SAFE_SNAPSHOT "Waiting to obtain a valid snapshot for a READ ONLY DEFERRABLE transaction." -SYNC_REP "Waiting for confirmation from a remote server during synchronous replication." +SYNC_REP "Waiting for confirmation from a remote server during synchronous replication." "PID of the slowest walsender." 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." WAL_SUMMARY_READY "Waiting for a new WAL summary to be generated." @@ -177,7 +177,7 @@ Section: ClassName - WaitEventTimeout BASE_BACKUP_THROTTLE "Waiting during base backup when throttling activity." CHECKPOINT_WRITE_DELAY "Waiting between writes while performing a checkpoint." COMMIT_DELAY "Waiting for commit delay before WAL flush." -PG_SLEEP "Waiting due to a call to pg_sleep or a sibling function." +PG_SLEEP "Waiting due to a call to pg_sleep or a sibling function." "how many seconds to sleep for." 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 (pg_wal, archive or stream)." REGISTER_SYNC_REQUEST "Waiting while sending synchronization requests to the checkpointer, because the request queue is full." @@ -248,10 +248,10 @@ 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." +SLRU_FLUSH_SYNC "Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown." "SlruType: unknown(0), notify(1), clog(2), subtrans(3), committs(4), multixactoffset (5), multixactmembers(6), serialializable(7)" +SLRU_READ "Waiting for a read of an SLRU page." "SlruType: unknown(0), notify(1), clog(2), subtrans(3), committs(4), multixactoffset (5), multixactmembers(6), serialializable(7)" +SLRU_SYNC "Waiting for SLRU data to reach durable storage following a page write." "SlruType: unknown(0), notify(1), clog(2), subtrans(3), committs(4), multixactoffset (5), multixactmembers(6), serialializable(7)" +SLRU_WRITE "Waiting for a write of an SLRU page." "SlruType: unknown(0), notify(1), clog(2), subtrans(3), committs(4), multixactoffset (5), multixactmembers(6), serialializable(7)" 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." diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a1974a6b53d..e336be58652 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5669,8 +5669,8 @@ { oid => '6318', descr => 'describe wait events', proname => 'pg_get_wait_events', procost => '10', prorows => '250', proretset => 't', provolatile => 'v', prorettype => 'record', - proargtypes => '', proallargtypes => '{text,text,text}', - proargmodes => '{o,o,o}', proargnames => '{type,name,description}', + proargtypes => '', proallargtypes => '{text,text,text,text}', + proargmodes => '{o,o,o,o}', proargnames => '{type,name,description,waiteventarg_description}', prosrc => 'pg_get_wait_events' }, { oid => '3318', descr => 'statistics: information about progress of backends running maintenance command', diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 90dc1131c81..f641ab4df50 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2796,8 +2796,9 @@ pg_views| SELECT n.nspname AS schemaname, WHERE (c.relkind = 'v'::"char"); pg_wait_events| SELECT type, name, - description - FROM pg_get_wait_events() pg_get_wait_events(type, name, description); + description, + waiteventarg_description + FROM pg_get_wait_events() pg_get_wait_events(type, name, description, waiteventarg_description); SELECT tablename, rulename, definition FROM pg_rules WHERE schemaname = 'pg_catalog' ORDER BY tablename, rulename; -- 2.43.0