mirror of
https://github.com/postgres/postgres.git
synced 2025-08-09 17:03:00 +03:00
Fix refreshing physical relfilenumber on shared index
Buildfarm member 'prion', which is configured with -DRELCACHE_FORCE_RELEASE -DCATCACHE_FORCE_RELEASE, failed with errors like this: ERROR: could not read blocks 0..0 in file "global/2672": read only 0 of 8192 bytes while running a parallel test group that includes VACUUM FULL on some catalog tables among other things. I was not able to reproduce that just by running the tests with -DRELCACHE_FORCE_RELEASE -DCATCACHE_FORCE_RELEASE, even though 'prion' hit it on first run after commit2b9b8ebbf8
, so there might be something else that makes it more susceptible to the race. However, I was able to reproduce it by adding another test to the same test group that runs "vacuum full pg_database" repeatedly. The problem is that RelationReloadIndexInfo() no longer calls RelationInitPhysicalAddr() on a nailed, shared index, when an invalidation happens early during backend startup, before the critical relcaches have been built. Before commit2b9b8ebbf8
, that was done by RelationReloadNailed(), but it went missing from that path. Add it back as an explicit step. Broken by commit2b9b8ebbf8
, which refactored these functions. Discussion: https://www.postgresql.org/message-id/db876575-8f5b-4193-a538-df7e1f92d47a%40iki.fi
This commit is contained in:
7
src/backend/utils/cache/relcache.c
vendored
7
src/backend/utils/cache/relcache.c
vendored
@@ -2253,11 +2253,14 @@ RelationReloadIndexInfo(Relation relation)
|
||||
* If it's a shared index, we might be called before backend startup has
|
||||
* finished selecting a database, in which case we have no way to read
|
||||
* pg_class yet. However, a shared index can never have any significant
|
||||
* schema updates, so it's okay to ignore the invalidation signal. Just
|
||||
* mark it valid and return without doing anything more.
|
||||
* schema updates, so it's okay to mostly ignore the invalidation signal.
|
||||
* Its physical relfilenumber might've changed, but that's all. Update
|
||||
* the physical relfilenumber, mark it valid and return without doing
|
||||
* anything more.
|
||||
*/
|
||||
if (relation->rd_rel->relisshared && !criticalRelcachesBuilt)
|
||||
{
|
||||
RelationInitPhysicalAddr(relation);
|
||||
relation->rd_isvalid = true;
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user