提交 0efdbb0f 编写于 作者: D Daniel Gustafsson

Add a --socketdir option to pg_upgrade

This is a backport of the below commit from upstream PostgreSQL,
which was originally written for Greenplum and submitted as an
upstream-first feature. The commit didn't cherrypick as upstream
has moved pg_upgrade to src/bin and Greenplum has yet to merge
that.
Reviewed-by: NJacob Champion <pchampion@pivotal.io>

  commit 2d34ad84
  Author: Tom Lane <tgl@sss.pgh.pa.us>
  Date:   Sat Dec 1 15:45:11 2018 -0500

    Add a --socketdir option to pg_upgrade.

    This allows control of the directory in which the postmaster sockets
    are created for the temporary postmasters started by pg_upgrade.
    The default location remains the current working directory, which is
    typically fine, but if it is deeply nested then its pathname might
    be too long to be a socket name.

    In passing, clean up some messiness in pg_upgrade's option handling,
    particularly the confusing and undocumented way that configuration-only
    datadirs were handled.  And fix check_required_directory's substantially
    under-baked cleanup of directory pathnames.

    Daniel Gustafsson, reviewed by Hironobu Suzuki, some code cleanup by me

    Discussion: https://postgr.es/m/E72DD5C3-2268-48A5-A907-ED4B34BEC223@yesql.se
上级 fab6834b
......@@ -22,8 +22,9 @@
static void usage(void);
static void check_required_directory(char **dirpath, char **configpath,
char *envVarName, char *cmdLineOption, 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"
......@@ -53,6 +54,7 @@ parseCommandLine(int argc, char *argv[])
{"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'},
/* Greenplum specific parameters */
......@@ -111,7 +113,7 @@ parseCommandLine(int argc, char *argv[])
if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
pg_fatal("cannot 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)
......@@ -130,12 +132,10 @@ parseCommandLine(int argc, char *argv[])
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':
......@@ -179,6 +179,10 @@ parseCommandLine(int argc, char *argv[])
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);
......@@ -260,14 +264,16 @@ parseCommandLine(int argc, char *argv[])
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");
/* Ensure we are only adding checksums in copy mode */
if (user_opts.transfer_mode != TRANSFER_MODE_COPY &&
......@@ -296,6 +302,7 @@ Options:\n\
-p, --old-port=PORT old cluster port number (default %d)\n\
-P, --new-port=PORT new cluster port number (default %d)\n\
-r, --retain retain SQL and log files after success\n\
-s, --socketdir=DIR socket directory to use (default CWD)\n\
-U, --username=NAME cluster superuser (default \"%s\")\n\
-v, --verbose enable verbose internal logging\n\
-V, --version display version information, then exit\n\
......@@ -342,29 +349,32 @@ or\n"), old_cluster.port, new_cluster.port, os_info.user);
* 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,
char *envVarName, char *cmdLineOption,
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"
......@@ -373,16 +383,10 @@ check_required_directory(char **dirpath, char **configpath,
}
/*
* 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);
}
/*
......@@ -391,6 +395,10 @@ check_required_directory(char **dirpath, char **configpath,
* If a configuration-only directory was specified, find the real data dir
* by quering 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)
......@@ -401,6 +409,9 @@ 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)
......@@ -465,12 +476,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
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("cannot find current directory\n");
}
cluster->sockdir = user_opts.socketdir;
else
{
/*
......
......@@ -424,7 +424,8 @@ typedef struct
bool check; /* TRUE -> ask user for permission to make
* changes */
transferMode transfer_mode; /* copy files or link them? */
int jobs;
int jobs; /* number of processes/threads to use */
char *socketdir; /* directory to use for Unix sockets */
bool progress;
segmentMode segment_mode;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册