On 21/06/2024 02:12, Tom Lane wrote:
> Heikki Linnakangas <hlinnaka@iki.fi> writes:
>> In commit af0e7deb4a, I removed the call to RelationCloseSmgr() from
>> RelationCacheInvalidate(). I thought it was no longer needed, because we
>> no longer free the underlying SmgrRelation.
>
>> However, it meant that if the relfilenode of the relation was changed,
>> the relation keeps pointing to the SMgrRelation of the old relfilenode.
>> So we still need the RelationCloseSmgr() call, in case the relfilenode
>> has changed.
>
> Ouch. How come we did not see this immediately in testing? I'd have
> thought surely such a bug would be exposed by any command that
> rewrites a heap.
There is a RelationCloseSmgr() call in RelationClearRelation(), which
covers the common cases. This only occurs during
RelationCacheInvalidate(), when pg_class's relfilenumber was changed.
Hmm, looking closer, I think this might be a more appropriate place for
the RelationCloseSmgr() call:
> /*
> * If it's a mapped relation, immediately update its rd_locator in
> * case its relfilenumber changed. We must do this during phase 1
> * in case the relation is consulted during rebuild of other
> * relcache entries in phase 2. It's safe since consulting the
> * map doesn't involve any access to relcache entries.
> */
> if (RelationIsMapped(relation))
> RelationInitPhysicalAddr(relation);
That's where we change the relfilenumber, before the
RelationClearRelation() call.
--
Heikki Linnakangas
Neon (https://neon.tech)