public inbox for [email protected]
help / color / mirror / Atom feed[PATCH 1/3] bootstrap: convert Typ to a List*
3+ messages / 3 participants
[nested] [flat]
* [PATCH 1/3] bootstrap: convert Typ to a List*
@ 2020-11-20 02:48 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 3+ messages in thread
From: Justin Pryzby @ 2020-11-20 02:48 UTC (permalink / raw)
---
src/backend/bootstrap/bootstrap.c | 69 ++++++++++++++-----------------
1 file changed, 31 insertions(+), 38 deletions(-)
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 6f615e6622..18eb62ca47 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -159,7 +159,7 @@ struct typmap
FormData_pg_type am_typ;
};
-static struct typmap **Typ = NULL;
+static List *Typ = NIL; /* List of struct typmap* */
static struct typmap *Ap = NULL;
static Datum values[MAXATTR]; /* current row's attribute values */
@@ -597,7 +597,7 @@ boot_openrel(char *relname)
* pg_type must be filled before any OPEN command is executed, hence we
* can now populate the Typ array if we haven't yet.
*/
- if (Typ == NULL)
+ if (Typ == NIL)
populate_typ_array();
if (boot_reldesc != NULL)
@@ -688,7 +688,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
typeoid = gettype(type);
- if (Typ != NULL)
+ if (Typ != NIL)
{
attrtypes[attnum]->atttypid = Ap->am_oid;
attrtypes[attnum]->attlen = Ap->am_typ.typlen;
@@ -877,36 +877,25 @@ populate_typ_array(void)
Relation rel;
TableScanDesc scan;
HeapTuple tup;
- int nalloc;
- int i;
-
- Assert(Typ == NULL);
- nalloc = 512;
- Typ = (struct typmap **)
- MemoryContextAlloc(TopMemoryContext, nalloc * sizeof(struct typmap *));
+ Assert(Typ == NIL);
rel = table_open(TypeRelationId, NoLock);
scan = table_beginscan_catalog(rel, 0, NULL);
- i = 0;
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
Form_pg_type typForm = (Form_pg_type) GETSTRUCT(tup);
+ struct typmap *newtyp;
+ MemoryContext old;
- /* make sure there will be room for a trailing NULL pointer */
- if (i >= nalloc - 1)
- {
- nalloc *= 2;
- Typ = (struct typmap **)
- repalloc(Typ, nalloc * sizeof(struct typmap *));
- }
- Typ[i] = (struct typmap *)
- MemoryContextAlloc(TopMemoryContext, sizeof(struct typmap));
- Typ[i]->am_oid = typForm->oid;
- memcpy(&(Typ[i]->am_typ), typForm, sizeof(Typ[i]->am_typ));
- i++;
+ old = MemoryContextSwitchTo(TopMemoryContext);
+ newtyp = (struct typmap *) palloc(sizeof(struct typmap));
+ Typ = lappend(Typ, newtyp);
+ MemoryContextSwitchTo(old);
+
+ newtyp->am_oid = typForm->oid;
+ memcpy(&newtyp->am_typ, typForm, sizeof(newtyp->am_typ));
}
- Typ[i] = NULL; /* Fill trailing NULL pointer */
table_endscan(scan);
table_close(rel, NoLock);
}
@@ -925,16 +914,17 @@ populate_typ_array(void)
static Oid
gettype(char *type)
{
- if (Typ != NULL)
+ if (Typ != NIL)
{
- struct typmap **app;
+ ListCell *lc;
- for (app = Typ; *app != NULL; app++)
+ foreach (lc, Typ)
{
- if (strncmp(NameStr((*app)->am_typ.typname), type, NAMEDATALEN) == 0)
+ struct typmap *app = lfirst(lc);
+ if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0)
{
- Ap = *app;
- return (*app)->am_oid;
+ Ap = app;
+ return app->am_oid;
}
}
}
@@ -980,14 +970,17 @@ boot_get_type_io_data(Oid typid,
if (Typ != NULL)
{
/* We have the boot-time contents of pg_type, so use it */
- struct typmap **app;
- struct typmap *ap;
-
- app = Typ;
- while (*app && (*app)->am_oid != typid)
- ++app;
- ap = *app;
- if (ap == NULL)
+ struct typmap *ap = NULL;
+ ListCell *lc;
+
+ foreach (lc, Typ)
+ {
+ ap = lfirst(lc);
+ if (ap->am_oid == typid)
+ break;
+ }
+
+ if (!ap || ap->am_oid != typid)
elog(ERROR, "type OID %u not found in Typ list", typid);
*typlen = ap->am_typ.typlen;
--
2.26.2
--------------76B8D0DC8AE327D516738282
Content-Type: text/x-patch; charset=UTF-8;
name="0002-Allow-composite-types-in-bootstrap-20210108.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0002-Allow-composite-types-in-bootstrap-20210108.patch"
^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: How about using dirty snapshots to locate dependent objects?
@ 2024-06-06 13:27 Bertrand Drouvot <[email protected]>
2024-06-06 14:21 ` Re: How about using dirty snapshots to locate dependent objects? Ashutosh Sharma <[email protected]>
0 siblings, 1 reply; 3+ messages in thread
From: Bertrand Drouvot @ 2024-06-06 13:27 UTC (permalink / raw)
To: Ashutosh Sharma <[email protected]>; +Cc: pgsql-hackers
On Thu, Jun 06, 2024 at 05:59:00PM +0530, Ashutosh Sharma wrote:
> Hello everyone,
>
> At present, we use MVCC snapshots to identify dependent objects. This
> implies that if a new dependent object is inserted within a transaction
> that is still ongoing, our search for dependent objects won't include this
> recently added one. Consequently, if someone attempts to drop the
> referenced object, it will be dropped, and when the ongoing transaction
> completes, we will end up having an entry for a referenced object that has
> already been dropped. This situation can lead to an inconsistent state.
> Below is an example illustrating this scenario:
>
> Session 1:
> - create table t1(a int);
> - insert into t1 select i from generate_series(1, 10000000) i;
> - create extension btree_gist;
> - create index i1 on t1 using gist( a );
>
> Session 2: (While the index creation in session 1 is in progress, drop the
> btree_gist extension)
> - drop extension btree_gist;
>
> Above command succeeds and so does the create index command running in
> session 1, post this, if we try running anything on table t1, i1, it fails
> with an error: "cache lookup failed for opclass ..."
>
> Attached is the patch that I have tried, which seems to be working for me.
> It's not polished and thoroughly tested, but just sharing here to clarify
> what I am trying to suggest. Please have a look and let me know your
> thoughts.
Thanks for the patch proposal!
The patch does not fix the other way around:
- session 1: BEGIN; DROP extension btree_gist;
- session 2: create index i1 on t1 using gist( a );
- session 1: commits while session 2 is creating the index
and does not address all the possible orphaned dependencies cases.
There is an ongoing thread (see [1]) to fix the orphaned dependencies issue.
v9 attached in [1] fixes the case you describe here.
[1]: https://www.postgresql.org/message-id/flat/ZiYjn0eVc7pxVY45%40ip-10-97-1-34.eu-west-3.compute.intern...
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: How about using dirty snapshots to locate dependent objects?
2024-06-06 13:27 Re: How about using dirty snapshots to locate dependent objects? Bertrand Drouvot <[email protected]>
@ 2024-06-06 14:21 ` Ashutosh Sharma <[email protected]>
0 siblings, 0 replies; 3+ messages in thread
From: Ashutosh Sharma @ 2024-06-06 14:21 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: pgsql-hackers
On Thu, Jun 6, 2024 at 6:57 PM Bertrand Drouvot <
[email protected]> wrote:
> On Thu, Jun 06, 2024 at 05:59:00PM +0530, Ashutosh Sharma wrote:
> > Hello everyone,
> >
> > At present, we use MVCC snapshots to identify dependent objects. This
> > implies that if a new dependent object is inserted within a transaction
> > that is still ongoing, our search for dependent objects won't include
> this
> > recently added one. Consequently, if someone attempts to drop the
> > referenced object, it will be dropped, and when the ongoing transaction
> > completes, we will end up having an entry for a referenced object that
> has
> > already been dropped. This situation can lead to an inconsistent state.
> > Below is an example illustrating this scenario:
> >
> > Session 1:
> > - create table t1(a int);
> > - insert into t1 select i from generate_series(1, 10000000) i;
> > - create extension btree_gist;
> > - create index i1 on t1 using gist( a );
> >
> > Session 2: (While the index creation in session 1 is in progress, drop
> the
> > btree_gist extension)
> > - drop extension btree_gist;
> >
> > Above command succeeds and so does the create index command running in
> > session 1, post this, if we try running anything on table t1, i1, it
> fails
> > with an error: "cache lookup failed for opclass ..."
> >
> > Attached is the patch that I have tried, which seems to be working for
> me.
> > It's not polished and thoroughly tested, but just sharing here to clarify
> > what I am trying to suggest. Please have a look and let me know your
> > thoughts.
>
> Thanks for the patch proposal!
>
> The patch does not fix the other way around:
>
> - session 1: BEGIN; DROP extension btree_gist;
> - session 2: create index i1 on t1 using gist( a );
> - session 1: commits while session 2 is creating the index
>
> and does not address all the possible orphaned dependencies cases.
>
> There is an ongoing thread (see [1]) to fix the orphaned dependencies
> issue.
>
> v9 attached in [1] fixes the case you describe here.
>
> [1]:
> https://www.postgresql.org/message-id/flat/ZiYjn0eVc7pxVY45%40ip-10-97-1-34.eu-west-3.compute.intern...
I see. Thanks for sharing this. I can take a look at this and help in
whatever way I can.
With Regards,
Ashutosh Sharma.
^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2024-06-06 14:21 UTC | newest]
Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20 02:48 [PATCH 1/3] bootstrap: convert Typ to a List* Justin Pryzby <[email protected]>
2024-06-06 13:27 Re: How about using dirty snapshots to locate dependent objects? Bertrand Drouvot <[email protected]>
2024-06-06 14:21 ` Re: How about using dirty snapshots to locate dependent objects? Ashutosh Sharma <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox