Fix temporary tablespaces for shared filesets some more.
authorTom Lane <[email protected]>
Fri, 3 Jul 2020 21:01:34 +0000 (17:01 -0400)
committerTom Lane <[email protected]>
Fri, 3 Jul 2020 21:01:34 +0000 (17:01 -0400)
Commit ecd9e9f0b fixed the problem in the wrong place, causing unwanted
side-effects on the behavior of GetNextTempTableSpace().  Instead,
let's make SharedFileSetInit() responsible for subbing in the value
of MyDatabaseTableSpace when the default tablespace is called for.

The convention about what is in the tempTableSpaces[] array is
evidently insufficiently documented, so try to improve that.

It also looks like SharedFileSetInit() is doing the wrong thing in the
case where temp_tablespaces is empty.  It was hard-wiring use of the
pg_default tablespace, but it seems like using MyDatabaseTableSpace
is more consistent with what happens for other temp files.

Back-patch the reversion of PrepareTempTablespaces()'s behavior to
9.5, as ecd9e9f0b was.  The changes in SharedFileSetInit() go back
to v11 where that was introduced.  (Note there is net zero code change
before v11 from these two patch sets, so nothing to release-note.)

Magnus Hagander and Tom Lane

Discussion: https://postgr.es/m/CABUevExg5YEsOvqMxrjoNvb3ApVyH+9jggWGKwTDFyFCVWczGQ@mail.gmail.com

src/backend/commands/tablespace.c
src/backend/storage/file/fd.c
src/backend/storage/file/sharedfileset.c

index 4c80bcdc348b89f5a040718606860b67b9f14637..457948a296d1875a7aee0f39cee41a6dab9a219b 100644 (file)
@@ -1184,6 +1184,7 @@ GetDefaultTablespace(char relpersistence, bool partitioned)
 
 typedef struct
 {
+   /* Array of OIDs to be passed to SetTempTablespaces() */
    int         numSpcs;
    Oid         tblSpcs[FLEXIBLE_ARRAY_MEMBER];
 } temp_tablespaces_extra;
@@ -1233,6 +1234,7 @@ check_temp_tablespaces(char **newval, void **extra, GucSource source)
            /* Allow an empty string (signifying database default) */
            if (curname[0] == '\0')
            {
+               /* InvalidOid signifies database's default tablespace */
                tblSpcs[numSpcs++] = InvalidOid;
                continue;
            }
@@ -1259,6 +1261,7 @@ check_temp_tablespaces(char **newval, void **extra, GucSource source)
             */
            if (curoid == MyDatabaseTableSpace)
            {
+               /* InvalidOid signifies database's default tablespace */
                tblSpcs[numSpcs++] = InvalidOid;
                continue;
            }
@@ -1369,6 +1372,7 @@ PrepareTempTablespaces(void)
        /* Allow an empty string (signifying database default) */
        if (curname[0] == '\0')
        {
+           /* InvalidOid signifies database's default tablespace */
            tblSpcs[numSpcs++] = InvalidOid;
            continue;
        }
@@ -1387,7 +1391,8 @@ PrepareTempTablespaces(void)
         */
        if (curoid == MyDatabaseTableSpace)
        {
-           tblSpcs[numSpcs++] = curoid;
+           /* InvalidOid signifies database's default tablespace */
+           tblSpcs[numSpcs++] = InvalidOid;
            continue;
        }
 
index faa73061cf38e5724c90c830523818ee675b127c..0fd1bbde5b0833f65c67ea499d5a06f1598ea84a 100644 (file)
@@ -251,8 +251,10 @@ static AllocateDesc *allocatedDescs = NULL;
 static long tempFileCounter = 0;
 
 /*
- * Array of OIDs of temp tablespaces.  When numTempTableSpaces is -1,
- * this has not been set in the current transaction.
+ * Array of OIDs of temp tablespaces.  (Some entries may be InvalidOid,
+ * indicating that the current database's default tablespace should be used.)
+ * When numTempTableSpaces is -1, this has not been set in the current
+ * transaction.
  */
 static Oid *tempTableSpaces = NULL;
 static int numTempTableSpaces = -1;
@@ -2670,6 +2672,9 @@ closeAllVfds(void)
  * unless this function is called again before then.  It is caller's
  * responsibility that the passed-in array has adequate lifespan (typically
  * it'd be allocated in TopTransactionContext).
+ *
+ * Some entries of the array may be InvalidOid, indicating that the current
+ * database's default tablespace should be used.
  */
 void
 SetTempTablespaces(Oid *tableSpaces, int numSpaces)
@@ -2709,7 +2714,10 @@ TempTablespacesAreSet(void)
  * GetTempTablespaces
  *
  * Populate an array with the OIDs of the tablespaces that should be used for
- * temporary files.  Return the number that were copied into the output array.
+ * temporary files.  (Some entries may be InvalidOid, indicating that the
+ * current database's default tablespace should be used.)  At most numSpaces
+ * entries will be filled.
+ * Returns the number of OIDs that were copied into the output array.
  */
 int
 GetTempTablespaces(Oid *tableSpaces, int numSpaces)
index 26e5091172d77c479da73399052084f76cc31c67..c21f62647798313562db76dd82a2e9f0b7cfd546 100644 (file)
@@ -63,9 +63,25 @@ SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
                           lengthof(fileset->tablespaces));
    if (fileset->ntablespaces == 0)
    {
-       fileset->tablespaces[0] = DEFAULTTABLESPACE_OID;
+       /* If the GUC is empty, use current database's default tablespace */
+       fileset->tablespaces[0] = MyDatabaseTableSpace;
        fileset->ntablespaces = 1;
    }
+   else
+   {
+       int         i;
+
+       /*
+        * An entry of InvalidOid means use the default tablespace for the
+        * current database.  Replace that now, to be sure that all users of
+        * the SharedFileSet agree on what to do.
+        */
+       for (i = 0; i < fileset->ntablespaces; i++)
+       {
+           if (fileset->tablespaces[i] == InvalidOid)
+               fileset->tablespaces[i] = MyDatabaseTableSpace;
+       }
+   }
 
    /* Register our cleanup callback. */
    on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));