1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-31 17:02:12 +03:00

Change custom wait events to use dynamic shared hash tables

Currently, the names of the custom wait event must be registered for
each backend, requiring all these to link to the shared memory area of
an extension, even if these are not loaded with
shared_preload_libraries.

This patch relaxes the constraints related to this infrastructure by
storing the wait events and their names in two dynamic hash tables in
shared memory.  This has the advantage to simplify the registration of
custom wait events to a single routine call that returns an event ID
ready for consumption:
uint32 WaitEventExtensionNew(const char *wait_event_name);

The caller of this routine can then cache locally the ID returned, to be
used for pgstat_report_wait_start(), WaitLatch() or a similar routine.

The implementation uses two hash tables: one with a key based on the
event name to avoid duplicates and a second using the event ID as key
for event lookups, like on pg_stat_activity.  These tables can hold a
minimum of 16 entries, and a maximum of 128 entries, which should be plenty
enough.

The code changes done in worker_spi show how things are simplified (most
of the code removed in this commit comes from there):
- worker_spi_init() is gone.
- No more shared memory hooks required (size requested and
initialization).
- The custom wait event ID is cached in the process that needs to set
it, with one single call to WaitEventExtensionNew() to retrieve it.

Per suggestion from Andres Freund.

Author: Masahiro Ikeda, with a few tweaks from me.
Discussion: https://postgr.es/m/20230801032349.aaiuvhtrcvvcwzcx@awork3.anarazel.de
This commit is contained in:
Michael Paquier
2023-08-14 14:47:27 +09:00
parent 2a8b40e368
commit af720b4c50
10 changed files with 165 additions and 238 deletions

View File

@@ -1121,9 +1121,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
<literal>LWLock</literal> types
to the list shown in <xref linkend="wait-event-extension-table"/> and
<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>Extension</literal> or <literal>LWLock</literal> wait
event might be reported as just
of <literal>LWLock</literal> assigned by an extension will not be
available in all server processes; It might be reported as just
<quote><literal>extension</literal></quote> rather than the
extension-assigned name.
</para>

View File

@@ -3454,33 +3454,15 @@ if (!ptr)
</sect2>
<sect2 id="xfunc-addin-wait-events">
<title>Shared Memory and Custom Wait Events</title>
<title>Custom Wait Events</title>
<para>
Add-ins can define custom wait events under the wait event type
<literal>Extension</literal>. The add-in's shared library must be
preloaded by specifying it in <literal>shared_preload_libraries</literal>,
and register a <literal>shmem_request_hook</literal> and a
<literal>shmem_startup_hook</literal> in its
<function>_PG_init</function> function.
<literal>shmem_request_hook</literal> can request a shared memory size
to be later used at startup by calling:
<literal>Extension</literal> by calling:
<programlisting>
void RequestAddinShmemSpace(int size)
</programlisting>
</para>
<para>
<literal>shmem_startup_hook</literal> can allocate in shared memory
custom wait events by calling while holding the LWLock
<function>AddinShmemInitLock</function> to avoid any race conditions:
<programlisting>
uint32 WaitEventExtensionNew(void)
</programlisting>
Next, each process needs to associate the wait event allocated previously
to a user-facing custom string, which is something done by calling:
<programlisting>
void WaitEventExtensionRegisterName(uint32 wait_event_info, const char *wait_event_name)
uint32 WaitEventExtensionNew(const char *wait_event_name)
</programlisting>
The wait event is associated to a user-facing custom string.
An example can be found in <filename>src/test/modules/worker_spi</filename>
in the PostgreSQL source tree.
</para>