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)