On Tue, Jun 21, 2022 at 5:08 PM houzj.f...@fujitsu.com
<houzj.f...@fujitsu.com> wrote:
> On Tuesday, June 21, 2022 3:21 PM Amit Langote <amitlangot...@gmail.com> 
> wrote:
> > Thanks for the patch.
> >
> > I agree it's an old bug.  A partition map entry's localrel may point
> > to a stale Relation pointer, because once the caller had closed the
> > relation, the relcache subsystem is free to "clear" it, like in the
> > case of a RELCACHE_FORCE_RELEASE build.
>
> Hi,
>
> Thanks for replying.
>
> > Fixing it the way patch does seems fine, though it feels like
> > localrelvalid will lose some of its meaning for the partition map
> > entries -- we will now overwrite localrel even if localrelvalid is
> > true.
>
> To me, it seems localrelvalid doesn't have the meaning that the cached 
> relation
> pointer is valid. In logicalrep_rel_open(), we also reopen and update the
> relation even if the localrelvalid is true.

Ah, right.  I guess only the localrelvalid=false case is really
interesting then.  Only in that case, we need to (re-)build other
fields that are computed using localrel.  In the localrelvalid=true
case, we don't need to worry about other fields, but still need to
make sure that localrel points to an up to date relcache entry of the
relation.

> > +   /*
> > +    * Relation is opened and closed by caller, so we need to always update 
> > the
> > +    * partrel in case the cached relation was closed.
> > +    */
> > +   entry->localrel = partrel;
> > +
> > +   if (entry->localrelvalid)
> >         return entry;
> >
> > Maybe we should add a comment here about why it's okay to overwrite
> > localrel even if localrelvalid is true.  How about the following hunk:
> >
> > @@ -596,8 +596,20 @@ logicalrep_partition_open(LogicalRepRelMapEntry
> > *root,
> >
> >     entry = &part_entry->relmapentry;
> >
> > +   /*
> > +    * We must always overwrite entry->localrel with the latest partition
> > +    * Relation pointer, because the Relation pointed to by the old value 
> > may
> > +    * have been cleared after the caller would have closed the partition
> > +    * relation after the last use of this entry.  Note that localrelvalid 
> > is
> > +    * only updated by the relcache invalidation callback, so it may still 
> > be
> > +    * true irrespective of whether the Relation pointed to by localrel has
> > +    * been cleared or not.
> > +    */
> >     if (found && entry->localrelvalid)
> > +   {
> > +       entry->localrel = partrel;
> >         return entry;
> > +   }
> >
> > Attached a patch containing the above to consider as an alternative.
>
> This looks fine to me as well.

Thank you.

--
Thanks, Amit Langote
EDB: http://www.enterprisedb.com


Reply via email to