pg_upgrade: conditionally create cluster delete script
authorBruce Momjian <bruce@momjian.us>
Thu, 14 Feb 2013 15:53:03 +0000 (10:53 -0500)
committerBruce Momjian <bruce@momjian.us>
Thu, 14 Feb 2013 15:53:03 +0000 (10:53 -0500)
If users create tablespaces inside the old cluster directory, it is
impossible for the delete script to delete _only_ the old cluster files,
so don't create a script in that case, and issue a message to the user.

contrib/pg_upgrade/check.c

index a7d4a68ce3caa1fa761cc33d79edce88b604f622..65fb54829e3436a469afc22796854f48fb72bdeb 100644 (file)
@@ -246,10 +246,17 @@ output_completion_banner(char *analyze_script_file_name,
                "by pg_upgrade so, once you start the new server, consider running:\n"
                           "    %s\n\n", analyze_script_file_name);
 
-       pg_log(PG_REPORT,
-                  "Running this script will delete the old cluster's data files:\n"
-                  "    %s\n",
-                  deletion_script_file_name);
+
+       if (deletion_script_file_name)
+               pg_log(PG_REPORT,
+                          "Running this script will delete the old cluster's data files:\n"
+                          "    %s\n",
+                          deletion_script_file_name);
+       else
+               pg_log(PG_REPORT,
+                          "Could not create a script to delete the old cluster's data\n"
+                          "files because user-defined tablespaces exist in the old cluster\n"
+                          "directory.  The old cluster's contents must be deleted manually.\n");
 }
 
 
@@ -584,14 +591,38 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 {
        FILE       *script = NULL;
        int                     tblnum;
+       char            old_cluster_pgdata[MAXPGPATH];
 
        *deletion_script_file_name = pg_malloc(MAXPGPATH);
 
-       prep_status("Creating script to delete old cluster");
-
        snprintf(*deletion_script_file_name, MAXPGPATH, "delete_old_cluster.%s",
                         SCRIPT_EXT);
 
+       /*
+        *      Some users (oddly) create tablespaces inside the cluster data
+        *      directory.  We can't create a proper old cluster delete script
+        *      in that case.
+        */
+       strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
+       canonicalize_path(old_cluster_pgdata);
+       for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
+       {
+               char            old_tablespace_dir[MAXPGPATH];
+               
+               strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
+               canonicalize_path(old_tablespace_dir);
+               if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
+               {
+                       /* Unlink file in case it is left over from a previous run. */
+                       unlink(*deletion_script_file_name);
+                       pg_free(*deletion_script_file_name);
+                       *deletion_script_file_name = NULL;
+                       return;
+               }
+       }
+
+       prep_status("Creating script to delete old cluster");
+
        if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
                pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
                           *deletion_script_file_name, getErrorText(errno));