</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-s</option> <replaceable>dir</replaceable></term>
+ <term><option>--socketdir=</option><replaceable>dir</replaceable></term>
+ <listitem><para>directory to use for postmaster sockets during upgrade;
+ default is current working directory; environment
+ variable <envar>PGSOCKETDIR</envar></para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>-U</option> <replaceable>username</replaceable></term>
<term><option>--username=</option><replaceable>username</replaceable></term>
<title>Notes</title>
<para>
- <application>pg_upgrade</application> does not support upgrading of databases
- containing table columns using these <type>reg*</type> OID-referencing system data types:
- <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
- <type>regoperator</type>, <type>regconfig</type>, and
- <type>regdictionary</type>. (<type>regtype</type> can be upgraded.)
+ <application>pg_upgrade</application> creates various working files, such
+ as schema dumps, in the current working directory. For security, be sure
+ that that directory is not readable or writable by any other users.
+ </para>
+
+ <para>
+ <application>pg_upgrade</application> launches short-lived postmasters in
+ the old and new data directories. Temporary Unix socket files for
+ communication with these postmasters are, by default, made in the current
+ working directory. In some situations the path name for the current
+ directory might be too long to be a valid socket name. In that case you
+ can use the <option>-s</option> option to put the socket files in some
+ directory with a shorter path name. For security, be sure that that
+ directory is not readable or writable by any other users.
+ (This is not relevant on Windows.)
</para>
<para>
insert dummy data, and upgrade that.
</para>
+ <para>
+ <application>pg_upgrade</application> does not support upgrading of databases
+ containing table columns using these <type>reg*</type> OID-referencing system data types:
+ <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
+ <type>regoperator</type>, <type>regconfig</type>, and
+ <type>regdictionary</type>. (<type>regtype</type> can be upgraded.)
+ </para>
+
<para>
If you are upgrading a pre-<productname>PostgreSQL</productname> 9.2 cluster
that uses a configuration-file-only directory, you must pass the
static void usage(void);
-static void check_required_directory(char **dirpath, char **configpath,
- const char *envVarName, const char *cmdLineOption, const char *description);
+static void check_required_directory(char **dirpath,
+ const char *envVarName, bool useCwd,
+ const char *cmdLineOption, const char *description);
#define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
{"link", no_argument, NULL, 'k'},
{"retain", no_argument, NULL, 'r'},
{"jobs", required_argument, NULL, 'j'},
+ {"socketdir", required_argument, NULL, 's'},
{"verbose", no_argument, NULL, 'v'},
{"clone", no_argument, NULL, 1},
if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE);
- while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
+ while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rs:U:v",
long_options, &optindex)) != -1)
{
switch (option)
case 'd':
old_cluster.pgdata = pg_strdup(optarg);
- old_cluster.pgconfig = pg_strdup(optarg);
break;
case 'D':
new_cluster.pgdata = pg_strdup(optarg);
- new_cluster.pgconfig = pg_strdup(optarg);
break;
case 'j':
log_opts.retain = true;
break;
+ case 's':
+ user_opts.socketdir = pg_strdup(optarg);
+ break;
+
case 'U':
pg_free(os_info.user);
os_info.user = pg_strdup(optarg);
pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);
/* Get values from env if not already set */
- check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b",
- _("old cluster binaries reside"));
- check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B",
- _("new cluster binaries reside"));
- check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig,
- "PGDATAOLD", "-d", _("old cluster data resides"));
- check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig,
- "PGDATANEW", "-D", _("new cluster data resides"));
+ check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
+ "-b", _("old cluster binaries reside"));
+ check_required_directory(&new_cluster.bindir, "PGBINNEW", false,
+ "-B", _("new cluster binaries reside"));
+ check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false,
+ "-d", _("old cluster data resides"));
+ check_required_directory(&new_cluster.pgdata, "PGDATANEW", false,
+ "-D", _("new cluster data resides"));
+ check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true,
+ "-s", _("sockets will be created"));
#ifdef WIN32
printf(_(" -p, --old-port=PORT old cluster port number (default %d)\n"), old_cluster.port);
printf(_(" -P, --new-port=PORT new cluster port number (default %d)\n"), new_cluster.port);
printf(_(" -r, --retain retain SQL and log files after success\n"));
+ printf(_(" -s, --socketdir=DIR socket directory to use (default CWD)\n"));
printf(_(" -U, --username=NAME cluster superuser (default \"%s\")\n"), os_info.user);
printf(_(" -v, --verbose enable verbose internal logging\n"));
printf(_(" -V, --version display version information, then exit\n"));
* check_required_directory()
*
* Checks a directory option.
- * dirpath - the directory name supplied on the command line
- * configpath - optional configuration directory
+ * dirpath - the directory name supplied on the command line, or NULL
* envVarName - the name of an environment variable to get if dirpath is NULL
- * cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N)
+ * useCwd - true if OK to default to CWD
+ * cmdLineOption - the command line option for this directory
* description - a description of this directory option
*
* We use the last two arguments to construct a meaningful error message if the
* user hasn't provided the required directory name.
*/
static void
-check_required_directory(char **dirpath, char **configpath,
- const char *envVarName, const char *cmdLineOption,
- const char *description)
+check_required_directory(char **dirpath, const char *envVarName, bool useCwd,
+ const char *cmdLineOption, const char *description)
{
if (*dirpath == NULL || strlen(*dirpath) == 0)
{
const char *envVar;
if ((envVar = getenv(envVarName)) && strlen(envVar))
- {
*dirpath = pg_strdup(envVar);
- if (configpath)
- *configpath = pg_strdup(envVar);
+ else if (useCwd)
+ {
+ char cwd[MAXPGPATH];
+
+ if (!getcwd(cwd, MAXPGPATH))
+ pg_fatal("could not determine current directory\n");
+ *dirpath = pg_strdup(cwd);
}
else
pg_fatal("You must identify the directory where the %s.\n"
}
/*
- * Trim off any trailing path separators because we construct paths by
- * appending to this path.
+ * Clean up the path, in particular trimming any trailing path separators,
+ * because we construct paths by appending to this path.
*/
-#ifndef WIN32
- if ((*dirpath)[strlen(*dirpath) - 1] == '/')
-#else
- if ((*dirpath)[strlen(*dirpath) - 1] == '/' ||
- (*dirpath)[strlen(*dirpath) - 1] == '\\')
-#endif
- (*dirpath)[strlen(*dirpath) - 1] = 0;
+ canonicalize_path(*dirpath);
}
/*
* If a configuration-only directory was specified, find the real data dir
* by querying the running server. This has limited checking because we
* can't check for a running server because we can't find postmaster.pid.
+ *
+ * On entry, cluster->pgdata has been set from command line or env variable,
+ * but cluster->pgconfig isn't set. We fill both variables with corrected
+ * values.
*/
void
adjust_data_dir(ClusterInfo *cluster)
FILE *fp,
*output;
+ /* Initially assume config dir and data dir are the same */
+ cluster->pgconfig = pg_strdup(cluster->pgdata);
+
/* If there is no postgresql.conf, it can't be a config-only dir */
snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
if ((fp = fopen(filename, "r")) == NULL)
if (GET_MAJOR_VERSION(cluster->major_version) >= 901)
{
if (!live_check)
- {
- /* Use the current directory for the socket */
- cluster->sockdir = pg_malloc(MAXPGPATH);
- if (!getcwd(cluster->sockdir, MAXPGPATH))
- pg_fatal("could not determine current directory\n");
- }
+ cluster->sockdir = user_opts.socketdir;
else
{
/*