On 21/06/2024 02:12, Tom Lane wrote:
Heikki Linnakangas <hlinn...@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)



Reply via email to