1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Fix autoprewarm neglect of tablespaces

While prewarming blocks from a dump file, autoprewarm_database_main()
mistakenly ignored tablespace when detecting the beginning of the next
relation to prewarm. Because RelFileNumbers are only unique within a
tablespace, autoprewarm could miss prewarming blocks from a
relation with the same RelFileNumber in a different tablespace.

Though this situation is likely rare in practice, it's best to make the
code correct. Do so by explicitly checking for the RelFileNumber when
detecting a new relation.

Reported-by: Heikki Linnakangas <hlinnaka@iki.fi>
Discussion: https://postgr.es/m/97c36982-603b-494a-95f4-aaf2a12ac27e%40iki.fi
This commit is contained in:
Melanie Plageman
2025-04-04 11:34:06 -04:00
parent 742317a80f
commit 64e7fa43a9

View File

@ -472,10 +472,15 @@ autoprewarm_database_main(Datum main_arg)
/*
* As soon as we encounter a block of a new relation, close the old
* relation. Note that rel will be NULL if try_relation_open failed
* previously; in that case, there is nothing to close.
* relation. RelFileNumbers are only guaranteed to be unique within a
* tablespace, so check that too.
*
* Note that rel will be NULL if try_relation_open failed previously;
* in that case, there is nothing to close.
*/
if (old_blk != NULL && old_blk->filenumber != blk->filenumber &&
if (old_blk != NULL &&
(old_blk->tablespace != blk->tablespace ||
old_blk->filenumber != blk->filenumber) &&
rel != NULL)
{
relation_close(rel, AccessShareLock);
@ -487,7 +492,9 @@ autoprewarm_database_main(Datum main_arg)
* Try to open each new relation, but only once, when we first
* encounter it. If it's been dropped, skip the associated blocks.
*/
if (old_blk == NULL || old_blk->filenumber != blk->filenumber)
if (old_blk == NULL ||
old_blk->tablespace != blk->tablespace ||
old_blk->filenumber != blk->filenumber)
{
Oid reloid;
@ -508,6 +515,7 @@ autoprewarm_database_main(Datum main_arg)
/* Once per fork, check for fork existence and size. */
if (old_blk == NULL ||
old_blk->tablespace != blk->tablespace ||
old_blk->filenumber != blk->filenumber ||
old_blk->forknum != blk->forknum)
{