Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w9GLW-001Iun-0c for pgsql-hackers@arkaria.postgresql.org; Sun, 05 Apr 2026 05:48:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w9GLU-001ipC-0L for pgsql-hackers@arkaria.postgresql.org; Sun, 05 Apr 2026 05:48:28 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w9GLT-001ip4-1y for pgsql-hackers@lists.postgresql.org; Sun, 05 Apr 2026 05:48:28 +0000 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w9GLR-00000000dQg-3lUZ for pgsql-hackers@postgresql.org; Sun, 05 Apr 2026 05:48:27 +0000 Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-43cf7683a28so1737166f8f.2 for ; Sat, 04 Apr 2026 22:48:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775368103; cv=none; d=google.com; s=arc-20240605; b=P/1FJSAuoV4oDAeV1Cjhx81Yz/MRxS+LxN/nEy/7OGuJIOqG0Z5hcHpER40XBOqMo5 4+cxbyp7p7z3sSwCRv+zbW8Nnvj4pr6/bhFVkJAag4lW8N795z0U32q4DrJCXTXDC+IB ZXd5jYxnl7mqzxoeCceTaM8AiZWos8u5nLpEVN4z0ZRLeI/5GGivqx+vXwIN9zozgP+3 Oaz/BJ4WGdZwIB1h3MrNY0qFoyVkPoFYaCBRMxcYJQ64W8Ka/r+pNkdv66m/f5ddT0Mc +W6079jNvvYkrprAwOFReFYBKKyRE3y0Kfyz/TbHIwxJ+Exq6wJxxx/VOTqe4i786ukq zQvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=oOwl8Unwa+YtWkliW73/emDJIol+nKuqDJI1D6FUuEU=; fh=QCFfbMm6CHXYXXYDX3r60U2rppvsKLtjtWqzDYblHJE=; b=BbH2emkzrMORjSojLV7n206sby7mpYJIv/XvnXQ6kITJVnvYRPuUVZiX/ffKrPZGZa ZoIdPQy4oUnuZ2etQgyupHBaoddSp7lOhhPlQkfb4fq2x2v62kEjHZ0y3izz5LT+97h+ inTXmmcVrpgkYkHw1tsunDq0VjA8at9k0/B7FWyPO7NoQIK7iyfagq4+1figB3JfnY7o aS5hziNr121tjqtm1JBibXAx1Gi/kuZHNf8mHri6WRvah05wQYRpH9zwRu0OBn8aJN7+ pmU0bYRfEsQWb13D2iElcl3h6/8S3QqBpTrXikdb5hAnRzmnpgn1IhLQV5Y7gmU/jRvZ vZJQ==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775368103; x=1775972903; darn=postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=oOwl8Unwa+YtWkliW73/emDJIol+nKuqDJI1D6FUuEU=; b=h2eehAwdN4zuNhKuSeT3zyjLa9AsLxcGk02eA73IdZlOQcO1GVNfGlMBh3YcTqfLsd pKcQipW5RwnbeBnOUfmP5n2uE4sQcA/gFA0n58qFrRVnJeKnskVG7dq4+wy+z0mdh9sn 44dP74aTIZO5X0fd+hHMlCPD029PG626LFYq59RH8ixHIM2HfluWZmlWpopsSYiaWkQA kgFP/XKOJQUBKp7n6padtg0q+GahhVEGsYUO4Y8KeTAlgrc0ijI/d7UsVNlC8hNaS+z0 /SMGhEqUgAc9vW91AKS8JxaUFh0I4LKdk9wftROY8TVXQZwXnBz3hNEX6bQTWTaTEDk3 aHkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775368103; x=1775972903; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=oOwl8Unwa+YtWkliW73/emDJIol+nKuqDJI1D6FUuEU=; b=hj05yh+amfsUK7X/XE/loheHbtLxzzNFMLPfw9u9vQcaFUoKydRoHwnq3Wa075NoAp zLke/7oHvG5GPbfn4vXssWg1UTE1+Cg580ACizFACsT4lSKGhE91ICLXbI6YFxSalSsV WWY067/cSZI0YJ7jAR6hh3cPf+v6cfXuZMb3xeNwuZXZLojjfY0YDmb7G21BfLmQ5mhi iTy2wC7IgPObmeuhQNtxkN3s6dcleAJKNyWh91iQpvsvuBmMdQYzPbtxfkPzDKsnRRHe qA6Rj+nlwhG+tyNvcdSv6cZ2lXMft4GK6t7yRRuIcLoLfviuCW2RfuOo92B9diXnps0F 2k8Q== X-Forwarded-Encrypted: i=1; AJvYcCU4yG4ECXUNvsSPKD2IGylcoUGvcwIuvJZDyCy91prV/jxAhfMIRnaGEAL3jQW19w5EQuMliJWOhdX0qjg6@postgresql.org X-Gm-Message-State: AOJu0YwERgSCblxypZbMyzC6ZJ5UxRkZvlcv7VhYu7NIfJk9SBDRXtf7 wXhl/dPka2Nmdj4ktNRUL7x1Ifz0uC9+ICKtRJNCOb9Cci3ZljTnbzoQIKOkC36EVMhM5BO7F3z 1FWlRolDGhHdR0grmpm/8As4iKd+yTfg= X-Gm-Gg: AeBDieuzp4GB52/rvZNnCMorCu5gv7NnXCHFhTrVwCSo81b4nKnM2pfXFYHFF4edrG0 tYQaD9w+9h7X1pLR83VJEQ/5rBmg39uff1SGaAb29JE7MCE6IgnFts7RZwpoNvQBzXs5Jd77ABN tsfIVR1Q20b8iGh7XE2RxvBqc2wcN2XqDpOcADopVAlHOxD8/pMMcSEHSDj059vQFq/jKV0RqOc 1/+EExeKDp0tF1PgBa2hRHZa+UCQdXV+3me6NmKnU+RNxzWTAHr/Tf2RuNMKpdbnSWyOMgrA5Y1 OOpD31NiCDBfl1V5zNqj0F7O0johkac5DAig9XQJFAdWI96xW6jq X-Received: by 2002:a5d:5d0f:0:b0:43b:498f:dcf0 with SMTP id ffacd0b85a97d-43d2926a052mr11799766f8f.9.1775368103150; Sat, 04 Apr 2026 22:48:23 -0700 (PDT) MIME-Version: 1.0 References: <113724ab-0028-493f-9605-6e8570f0939f@iki.fi> <791c3f18-f4de-4d84-ac6b-c7ccc074dd38@iki.fi> <9d919bd9-94dd-4bda-8ccf-ebced4178c53@iki.fi> <7d3ba240-9350-4dfc-bbe1-be6584aee236@iki.fi> <1c3a07a7-158d-4800-927c-2641c73277d8@iki.fi> In-Reply-To: <1c3a07a7-158d-4800-927c-2641c73277d8@iki.fi> From: Ashutosh Bapat Date: Sun, 5 Apr 2026 11:18:10 +0530 X-Gm-Features: AQROBzB4wO0EnkS1bIBDZRg-rHMH3vcHK05ET3zaztJ9kn3FT7hOR8vqR332uMY Message-ID: Subject: Re: Better shared data structure management and resizable shared data structures To: Heikki Linnakangas Cc: Matthias van de Meent , Robert Haas , Andres Freund , pgsql-hackers , chaturvedipalak1911@gmail.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sat, Apr 4, 2026 at 11:02=E2=80=AFPM Heikki Linnakangas wrote: > > On 04/04/2026 15:00, Matthias van de Meent wrote: > > On Sat, 4 Apr 2026 at 02:45, Heikki Linnakangas wrote= : > >>>> I don't understand the use of ShmemStructDesc. They generally/always > >>>> are private to request_fn(), and their fields are used exclusively > >>>> inside the shmem mechanisms, with no reads of its fields that can't > >>>> already be deduced from context. Why do we need that struct > >>>> everywhere? > >>> > >>> My resizable shared memory structure patches use it as a handle to th= e > >>> structure to be resized. > >> > >> Right. And hash tables and SLRUs use a desc-like object already, so fo= r > >> symmetry it feels natural to have it for plain structs too. > >> I wonder if we should make it optional though, for the common case tha= t > >> you have no intention of doing anything more with the shmem region tha= t > >> you'd need a desc for. I'm thinking you could just pass NULL for the > >> desc pointer: > >> > >> ShmemRequestStruct(NULL, > >> .name =3D "pg_stat_statements", > >> .size =3D sizeof(pgssSharedState), > >> .ptr =3D (void **) &pgss, > >> }; > > > > That would help, though I'd still wonder why we'd have separate Opts > > and Desc structs. IIUC, they generally carry (exactly) the same data. > > > > Maybe moving it into a `.handle` or `.desc` field in Shmem*Opts could > > make that part of the code a bit cleaner; as it'd further clarify that > > it's very much an optional field. > > Yeah. OTOH, I'd like to separate the options from what's effectively a > return value. But maybe you're right and it's nevertheless better that wa= y. > > Some options on this: > > a) What's in the patch now > > static ShmemStructDesc pgssSharedStateDesc; > > ShmemRequestStruct(&pgssSharedStateDesc, > .name =3D "pg_stat_statements", > .size =3D sizeof(pgssSharedState), > .ptr =3D (void **) &pgss); > > b) Allow passing NULL for the desc > > ShmemRequestStruct(NULL, > .name =3D "pg_stat_statements", > .size =3D sizeof(pgssSharedState), > .ptr =3D (void **) &pgss); > > c) Return the Desc as a return value > > static ShmemStructDesc *pgssSharedStateDesc; > > pgssSharedStateDesc =3D > ShmemRequestStruct(.name =3D "pg_stat_statements", > .size =3D sizeof(pgssSharedState), > .ptr =3D (void **) &pgss); > > In option c) you can just throw away the result if you don't need it. I > kind of like this as a notational thing. However it has some downsides: > > This changes the return value to be a pointer. I'm thinking that > ShmemRequestStruct() palloc's the descriptor struct in TopMemoryContext. > This is a little ugly because the descriptor struct is leaked if the > caller throws it away. It's not a lot of memory, but still. > > I'm also not sure how well this fits in with the SLRU code. On 'master', > you already have SlruCtlData which is like the "desc" struct. Would we > turn that into a pointer too, adding one indirection to all the SLRU > calls. It's probably fine from a performance point of view, but it feels > like it's going in the wrong direction. > > d) Make it part of Opts, as you suggested > > static ShmemStructDesc pgssSharedStateDesc; > > ShmemRequestStruct(.name =3D "pg_stat_statements", > .size =3D sizeof(pgssSharedState), > .ptr =3D (void **) &pgss, > .desc =3D &pgssSharedStateDesc); > > In the attached new version, though, I stepped back and decided to > remove the whole ShmemStructDesc after all. I still think having a > handle like that is a good idea, and the follow-up patches for resizing > need it. However, with option d) it can easily be added later. With > option d), it seems silly to have it be part of the patch now, when the > desc struct doesn't really do anything. SLRU's still have a similar > SlruDesc struct, however. For SLRUs it's essentially the same as the old > SlruCtlData struct before these patches. > > The Desc structs were being used for one thing though: I used the 'size' > from the Desc struct in ProcGlobalShmemInit() to get the allocated size > of each shmem area. The size computation there is complicated enough > that I'd rather not repeat it, and avoiding the repeated size > calculation was the raison d'=C3=AAtre for these patches. I replaced it w= ith > global variables to hold the sizes from the ShmemRequest() step to > ShmemInit(). But that would be one case where having the desc would > already be useful. Then again, I'm not sure we want to expose the 'size' > in the descriptor like that anyway, because as soon as we make shmem > regions resizable, we might not be able to keep the size in the > descriptor up-to-date. The size of these structs won't change, but we > might not want to expose the information because it would be confusing > for other structs where it can change to show outdated information. > > On a related note, when we add back the ".desc" concept later, is > ".desc" a good name, or ".handle" as you also suggested? More widely, do > we call the concept and the struct a "handle" or "descriptor" or what? > Or if we follow the precedence with the existing SlruCtlData struct, it > could be ".ctl". I'm not a fan of the "Ctl" naming though, because we > already have a lot of structs with "Ctl" in the name and it's not always > clear whether a "Ctl" struct refers to the shared memory parts or the > handle to it. Now that the "desc" structs are not part of these patches > anymore, however, we can punt on that decision. Resizing patches can do without Desc, they use name has the handle instead. I was not comfortable with current state of Desc either because they are not opaque as I had pointed out earlier. A caller can scribble on them. There is not need to decide on the handle decision right now, even for resizing patches. If we decide to add a handle, I would like it to be opaque. I thought about using ShmemIndexEnt * itself as the opaque pointer; we shouldn't expose it to the users of shmem.c that it's ShmemIndexEnt * though. There is downside that we are giving a much riskier handle in the shmem.c users' hands - they can now corrupt shared memory itself. We could encapsulate the ShmemIndexEntry * like how HTAB encapsulates HASHHDR if needed. Advantage of this approach is that ShmemResizeStruct() or any shmem.c API accepting the handle doesn't need to perform a ShmemIndex lookup. Just ideas, nothing required right now. > > On 02/04/2026 09:58, Ashutosh Bapat wrote: > >> > >> I renamed it to AttachOrInitShmemIndexEntry, and the args to 'may_init= ' > >> and 'may_attach'. But more importantly I added comments to explain the > >> different usages. Hope that helps.. > > > > The explanation in the prologue looks good. But the function is still > > confusing. Instead of if ... else fi ... chain, I feel organizing this > > as below would make it more readable. (this was part of one of my > > earlier edit patches). > > if (found) > > ... > > else > > { > > if (!may_init) > > error > > if (!index_entry) > > error > > > > ... rest of the code to initialize and attach > > } > > > > But other than that I don't have any other brilliant ideas. > > I did another refactoring in this area: I split > AttachOrInitShmemIndexEntry() into separate AttachShmemIndexEntry() and > InitShmemIndexEntry functions again. There's a little bit of repetition > that way, but IMO it makes it much clearer overall. > Yes. I will post my resizable shmem structures patch in a separate email in this thread but continue to review your patches. --=20 Best Wishes, Ashutosh Bapat