pg.ddx.io pgsql-hackers@postgresql.org mailing list archive
help / color / mirror / Atom feed From: Nathan Bossart <nathandbossart@gmail.com>
To: Robert Haas <robertmhaas@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: pgsql: Teach DSM registry to ERROR if attaching to an uninitialized ent
Date: Mon, 24 Nov 2025 13:03:06 -0600
Message-ID: <aSSr6j3JzeLcqOWo@nathan> (raw )
In-Reply-To: <aSSlqWwLVuXMmN-o@nathan >
References: <E1vJHUk-006I7r-37@gemulon.postgresql.org >
<CA+TgmoZGFzLJpYANBG9yDyoakVm-P2Acdker-Y+DHvPWfvBE5w@mail.gmail.com >
<aR89_9oYFHNtUTFa@nathan >
<CA+TgmoZCHER55cGmnL_svMjH=k-S0w29ih+ym_+=t032TSsOFA@mail.gmail.com >
<aR-fqzfZYSd3TVKa@nathan >
<CA+TgmoZsxbVhoxNGTWSd6=vHvyoqOSDNXJZabBZx+St8uPduLQ@mail.gmail.com >
<aSIR4Z4U887f_KcQ@nathan >
<aSSlqWwLVuXMmN-o@nathan >
On Mon, Nov 24, 2025 at 12:36:25PM -0600, Nathan Bossart wrote:
> On Sat, Nov 22, 2025 at 01:41:21PM -0600, Nathan Bossart wrote:
>> I'll give what you suggested a try. It seems reasonable enough.
>
> Here is a mostly-untested first try.
I think 0002 was more complicated than necessary. Here's a second try.
--
nathan
Attachments: download all (2 files, .tar.gz)
v2-0001-Revert-Teach-DSM-registry-to-ERROR-if-attaching-t.patch (text/plain, 3.7K) download
From 55956903a8339c754ba96ff0f52ddb38f7ae184b Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 24 Nov 2025 11:03:52 -0600
Subject: [PATCH v2 1/2] Revert "Teach DSM registry to ERROR if attaching to an
uninitialized entry."
This reverts commit 1165a933aab1355757a43cfd9193b6cce06f573b.
---
src/backend/storage/ipc/dsm_registry.c | 34 +++-----------------------
1 file changed, 4 insertions(+), 30 deletions(-)
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index 7eba8a8cffb..a926b9c3f32 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -93,7 +93,6 @@ typedef struct DSMRegistryEntry
{
char name[NAMEDATALEN];
DSMREntryType type;
- bool initialized;
union
{
NamedDSMState dsm;
@@ -217,7 +216,6 @@ GetNamedDSMSegment(const char *name, size_t size,
dsm_segment *seg;
entry->type = DSMR_ENTRY_TYPE_DSM;
- entry->initialized = false;
/* Initialize the segment. */
seg = dsm_create(size, 0);
@@ -230,21 +228,13 @@ GetNamedDSMSegment(const char *name, size_t size,
if (init_callback)
(*init_callback) (ret);
-
- entry->initialized = true;
}
else if (entry->type != DSMR_ENTRY_TYPE_DSM)
ereport(ERROR,
- (errmsg("requested DSM segment \"%s\" does not match type of existing entry",
- name)));
- else if (!entry->initialized)
- ereport(ERROR,
- (errmsg("requested DSM segment \"%s\" failed initialization",
- name)));
+ (errmsg("requested DSM segment does not match type of existing entry")));
else if (entry->dsm.size != size)
ereport(ERROR,
- (errmsg("requested DSM segment \"%s\" does not match size of existing entry",
- name)));
+ (errmsg("requested DSM segment size does not match size of existing segment")));
else
{
NamedDSMState *state = &entry->dsm;
@@ -307,7 +297,6 @@ GetNamedDSA(const char *name, bool *found)
NamedDSAState *state = &entry->dsa;
entry->type = DSMR_ENTRY_TYPE_DSA;
- entry->initialized = false;
/* Initialize the LWLock tranche for the DSA. */
state->tranche = LWLockNewTrancheId(name);
@@ -319,17 +308,10 @@ GetNamedDSA(const char *name, bool *found)
/* Store handle for other backends to use. */
state->handle = dsa_get_handle(ret);
-
- entry->initialized = true;
}
else if (entry->type != DSMR_ENTRY_TYPE_DSA)
ereport(ERROR,
- (errmsg("requested DSA \"%s\" does not match type of existing entry",
- name)));
- else if (!entry->initialized)
- ereport(ERROR,
- (errmsg("requested DSA \"%s\" failed initialization",
- name)));
+ (errmsg("requested DSA does not match type of existing entry")));
else
{
NamedDSAState *state = &entry->dsa;
@@ -390,7 +372,6 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
dsa_area *dsa;
entry->type = DSMR_ENTRY_TYPE_DSH;
- entry->initialized = false;
/* Initialize the LWLock tranche for the hash table. */
dsh_state->tranche = LWLockNewTrancheId(name);
@@ -408,17 +389,10 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
/* Store handles for other backends to use. */
dsh_state->dsa_handle = dsa_get_handle(dsa);
dsh_state->dsh_handle = dshash_get_hash_table_handle(ret);
-
- entry->initialized = true;
}
else if (entry->type != DSMR_ENTRY_TYPE_DSH)
ereport(ERROR,
- (errmsg("requested DSHash \"%s\" does not match type of existing entry",
- name)));
- else if (!entry->initialized)
- ereport(ERROR,
- (errmsg("requested DSHash \"%s\" failed initialization",
- name)));
+ (errmsg("requested DSHash does not match type of existing entry")));
else
{
NamedDSHState *dsh_state = &entry->dsh;
--
2.39.5 (Apple Git-154)
v2-0002-handle-ERRORs-in-DSM-registry-functions.patch (text/plain, 4.8K) download
From 3529f2e17b85537198d8a6fa783ca9c0b0522547 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 24 Nov 2025 12:28:23 -0600
Subject: [PATCH v2 2/2] handle ERRORs in DSM registry functions
---
src/backend/storage/ipc/dsm_registry.c | 85 +++++++++++++++++++++++---
1 file changed, 75 insertions(+), 10 deletions(-)
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index a926b9c3f32..bae67d15add 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -155,9 +155,10 @@ init_dsm_registry(void)
{
/* Initialize dynamic shared hash table for registry. */
dsm_registry_dsa = dsa_create(LWTRANCHE_DSM_REGISTRY_DSA);
+ dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL);
+
dsa_pin(dsm_registry_dsa);
dsa_pin_mapping(dsm_registry_dsa);
- dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL);
/* Store handles in shared memory for other backends to use. */
DSMRegistryCtx->dsah = dsa_get_handle(dsm_registry_dsa);
@@ -218,16 +219,24 @@ GetNamedDSMSegment(const char *name, size_t size,
entry->type = DSMR_ENTRY_TYPE_DSM;
/* Initialize the segment. */
- seg = dsm_create(size, 0);
+ PG_TRY();
+ {
+ seg = dsm_create(size, 0);
+ ret = dsm_segment_address(seg);
+ if (init_callback)
+ (*init_callback) (ret);
+ }
+ PG_CATCH();
+ {
+ dshash_delete_entry(dsm_registry_table, entry);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
dsm_pin_segment(seg);
dsm_pin_mapping(seg);
state->handle = dsm_segment_handle(seg);
state->size = size;
- ret = dsm_segment_address(seg);
-
- if (init_callback)
- (*init_callback) (ret);
}
else if (entry->type != DSMR_ENTRY_TYPE_DSM)
ereport(ERROR,
@@ -297,12 +306,23 @@ GetNamedDSA(const char *name, bool *found)
NamedDSAState *state = &entry->dsa;
entry->type = DSMR_ENTRY_TYPE_DSA;
+ state->handle = DSA_HANDLE_INVALID;
/* Initialize the LWLock tranche for the DSA. */
- state->tranche = LWLockNewTrancheId(name);
+ PG_TRY();
+ {
+ state->tranche = LWLockNewTrancheId(name);
+ }
+ PG_CATCH();
+ {
+ dshash_delete_entry(dsm_registry_table, entry);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
/* Initialize the DSA. */
ret = dsa_create(state->tranche);
+
dsa_pin(ret);
dsa_pin_mapping(ret);
@@ -312,6 +332,19 @@ GetNamedDSA(const char *name, bool *found)
else if (entry->type != DSMR_ENTRY_TYPE_DSA)
ereport(ERROR,
(errmsg("requested DSA does not match type of existing entry")));
+ else if (entry->dsa.handle == DSA_HANDLE_INVALID)
+ {
+ NamedDSAState *state = &entry->dsa;
+
+ /* Initialize the DSA. */
+ ret = dsa_create(state->tranche);
+
+ dsa_pin(ret);
+ dsa_pin_mapping(ret);
+
+ /* Store handle for other backends to use. */
+ state->handle = dsa_get_handle(ret);
+ }
else
{
NamedDSAState *state = &entry->dsa;
@@ -372,20 +405,31 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
dsa_area *dsa;
entry->type = DSMR_ENTRY_TYPE_DSH;
+ dsh_state->dsa_handle = DSA_HANDLE_INVALID;
/* Initialize the LWLock tranche for the hash table. */
- dsh_state->tranche = LWLockNewTrancheId(name);
+ PG_TRY();
+ {
+ dsh_state->tranche = LWLockNewTrancheId(name);
+ }
+ PG_CATCH();
+ {
+ dshash_delete_entry(dsm_registry_table, entry);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
/* Initialize the DSA for the hash table. */
dsa = dsa_create(dsh_state->tranche);
- dsa_pin(dsa);
- dsa_pin_mapping(dsa);
/* Initialize the dshash table. */
memcpy(¶ms_copy, params, sizeof(dshash_parameters));
params_copy.tranche_id = dsh_state->tranche;
ret = dshash_create(dsa, ¶ms_copy, NULL);
+ dsa_pin(dsa);
+ dsa_pin_mapping(dsa);
+
/* Store handles for other backends to use. */
dsh_state->dsa_handle = dsa_get_handle(dsa);
dsh_state->dsh_handle = dshash_get_hash_table_handle(ret);
@@ -393,6 +437,27 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
else if (entry->type != DSMR_ENTRY_TYPE_DSH)
ereport(ERROR,
(errmsg("requested DSHash does not match type of existing entry")));
+ else if (entry->dsh.dsa_handle == DSA_HANDLE_INVALID)
+ {
+ NamedDSHState *dsh_state = &entry->dsh;
+ dshash_parameters params_copy;
+ dsa_area *dsa;
+
+ /* Initialize the DSA for the hash table. */
+ dsa = dsa_create(dsh_state->tranche);
+
+ /* Initialize the dshash table. */
+ memcpy(¶ms_copy, params, sizeof(dshash_parameters));
+ params_copy.tranche_id = dsh_state->tranche;
+ ret = dshash_create(dsa, ¶ms_copy, NULL);
+
+ dsa_pin(dsa);
+ dsa_pin_mapping(dsa);
+
+ /* Store handles for other backends to use. */
+ dsh_state->dsa_handle = dsa_get_handle(dsa);
+ dsh_state->dsh_handle = dshash_get_hash_table_handle(ret);
+ }
else
{
NamedDSHState *dsh_state = &entry->dsh;
--
2.39.5 (Apple Git-154)
view thread (19+ messages) latest in thread
Message-ID: <aSSr6j3JzeLcqOWo@nathan>
Permalink: ../aSSr6j3JzeLcqOWo@nathan/
Also on: postgresql.org/message-id/aSSr6j3JzeLcqOWo@nathan
copy link · copy postgr.es · copy git am
reply Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: nathandbossart@gmail.com, robertmhaas@gmail.com, pgsql-hackers@lists.postgresql.org
Subject: Re: pgsql: Teach DSM registry to ERROR if attaching to an uninitialized ent
In-Reply-To: <aSSr6j3JzeLcqOWo@nathan>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox