]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix autoprewarm neglect of tablespaces
authorMelanie Plageman <melanieplageman@gmail.com>
Fri, 4 Apr 2025 15:34:06 +0000 (11:34 -0400)
committerMelanie Plageman <melanieplageman@gmail.com>
Fri, 4 Apr 2025 15:34:06 +0000 (11:34 -0400)
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

contrib/pg_prewarm/autoprewarm.c

index 73485a2323cfbe6651b2a76330366032d296a6db..760b1548eff93b61e760331868e9567a6195721f 100644 (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)
                {