mirror of
https://github.com/postgres/postgres.git
synced 2026-04-21 06:08:26 -04:00
The parallel slots infrastructure (which implements client-side multiplexing of server connections doing similar things, not threading or multiple processes or anything like that) are moved from src/bin/scripts/scripts_parallel.c to src/fe_utils/parallel_slot.c. The functions consumeQueryResult() and processQueryResult() which were previously part of src/bin/scripts/common.c are now moved into that file as well, becoming static helper functions. This might need to be changed in the future, but currently they're not used for anything else. Some other functions from src/bin/scripts/common.c are moved to to src/fe_utils and are split up among several files. connectDatabase(), connectMaintenanceDatabase(), and disconnectDatabase() are moved to connect_utils.c. executeQuery(), executeCommand(), and executeMaintenanceCommand() are move to query_utils.c. handle_help_version_opts() is moved to option_utils.c. Mark Dilger, reviewed by me. The larger patch series of which this is a part has also had review from Peter Geoghegan, Andres Freund, Álvaro Herrera, Michael Paquier, and Amul Sul, but I don't know whether any of them have reviewed this bit specifically. Discussion: http://postgr.es/m/12ED3DA8-25F0-4B68-937D-D907CFBF08E7@enterprisedb.com Discussion: http://postgr.es/m/5F743835-3399-419C-8324-2D424237E999@enterprisedb.com Discussion: http://postgr.es/m/70655DF3-33CE-4527-9A4D-DDEB582B6BA0@enterprisedb.com
241 lines
5.8 KiB
C
241 lines
5.8 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* pg_isready --- checks the status of the PostgreSQL server
|
|
*
|
|
* Copyright (c) 2013-2021, PostgreSQL Global Development Group
|
|
*
|
|
* src/bin/scripts/pg_isready.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres_fe.h"
|
|
#include "common.h"
|
|
#include "common/logging.h"
|
|
#include "fe_utils/option_utils.h"
|
|
|
|
#define DEFAULT_CONNECT_TIMEOUT "3"
|
|
|
|
static void
|
|
help(const char *progname);
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int c;
|
|
|
|
const char *progname;
|
|
|
|
const char *pghost = NULL;
|
|
const char *pgport = NULL;
|
|
const char *pguser = NULL;
|
|
const char *pgdbname = NULL;
|
|
const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
|
|
|
|
const char *pghost_str = NULL;
|
|
const char *pghostaddr_str = NULL;
|
|
const char *pgport_str = NULL;
|
|
|
|
#define PARAMS_ARRAY_SIZE 7
|
|
|
|
const char *keywords[PARAMS_ARRAY_SIZE];
|
|
const char *values[PARAMS_ARRAY_SIZE];
|
|
|
|
bool quiet = false;
|
|
|
|
PGPing rv;
|
|
PQconninfoOption *opts = NULL;
|
|
PQconninfoOption *defs = NULL;
|
|
PQconninfoOption *opt;
|
|
PQconninfoOption *def;
|
|
char *errmsg = NULL;
|
|
|
|
/*
|
|
* We accept user and database as options to avoid useless errors from
|
|
* connecting with invalid params
|
|
*/
|
|
|
|
static struct option long_options[] = {
|
|
{"dbname", required_argument, NULL, 'd'},
|
|
{"host", required_argument, NULL, 'h'},
|
|
{"port", required_argument, NULL, 'p'},
|
|
{"quiet", no_argument, NULL, 'q'},
|
|
{"timeout", required_argument, NULL, 't'},
|
|
{"username", required_argument, NULL, 'U'},
|
|
{NULL, 0, NULL, 0}
|
|
};
|
|
|
|
pg_logging_init(argv[0]);
|
|
progname = get_progname(argv[0]);
|
|
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
|
|
handle_help_version_opts(argc, argv, progname, help);
|
|
|
|
while ((c = getopt_long(argc, argv, "d:h:p:qt:U:", long_options, NULL)) != -1)
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'd':
|
|
pgdbname = pg_strdup(optarg);
|
|
break;
|
|
case 'h':
|
|
pghost = pg_strdup(optarg);
|
|
break;
|
|
case 'p':
|
|
pgport = pg_strdup(optarg);
|
|
break;
|
|
case 'q':
|
|
quiet = true;
|
|
break;
|
|
case 't':
|
|
connect_timeout = pg_strdup(optarg);
|
|
break;
|
|
case 'U':
|
|
pguser = pg_strdup(optarg);
|
|
break;
|
|
default:
|
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
|
|
|
/*
|
|
* We need to make sure we don't return 1 here because someone
|
|
* checking the return code might infer unintended meaning
|
|
*/
|
|
exit(PQPING_NO_ATTEMPT);
|
|
}
|
|
}
|
|
|
|
if (optind < argc)
|
|
{
|
|
pg_log_error("too many command-line arguments (first is \"%s\")",
|
|
argv[optind]);
|
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
|
|
|
/*
|
|
* We need to make sure we don't return 1 here because someone
|
|
* checking the return code might infer unintended meaning
|
|
*/
|
|
exit(PQPING_NO_ATTEMPT);
|
|
}
|
|
|
|
keywords[0] = "host";
|
|
values[0] = pghost;
|
|
keywords[1] = "port";
|
|
values[1] = pgport;
|
|
keywords[2] = "user";
|
|
values[2] = pguser;
|
|
keywords[3] = "dbname";
|
|
values[3] = pgdbname;
|
|
keywords[4] = "connect_timeout";
|
|
values[4] = connect_timeout;
|
|
keywords[5] = "fallback_application_name";
|
|
values[5] = progname;
|
|
keywords[6] = NULL;
|
|
values[6] = NULL;
|
|
|
|
/*
|
|
* Get the host and port so we can display them in our output
|
|
*/
|
|
if (pgdbname &&
|
|
(strncmp(pgdbname, "postgresql://", 13) == 0 ||
|
|
strncmp(pgdbname, "postgres://", 11) == 0 ||
|
|
strchr(pgdbname, '=') != NULL))
|
|
{
|
|
opts = PQconninfoParse(pgdbname, &errmsg);
|
|
if (opts == NULL)
|
|
{
|
|
pg_log_error("%s", errmsg);
|
|
exit(PQPING_NO_ATTEMPT);
|
|
}
|
|
}
|
|
|
|
defs = PQconndefaults();
|
|
if (defs == NULL)
|
|
{
|
|
pg_log_error("could not fetch default options");
|
|
exit(PQPING_NO_ATTEMPT);
|
|
}
|
|
|
|
for (opt = opts, def = defs; def->keyword; def++)
|
|
{
|
|
if (strcmp(def->keyword, "host") == 0)
|
|
{
|
|
if (opt && opt->val)
|
|
pghost_str = opt->val;
|
|
else if (pghost)
|
|
pghost_str = pghost;
|
|
else if (def->val)
|
|
pghost_str = def->val;
|
|
else
|
|
pghost_str = DEFAULT_PGSOCKET_DIR;
|
|
}
|
|
else if (strcmp(def->keyword, "hostaddr") == 0)
|
|
{
|
|
if (opt && opt->val)
|
|
pghostaddr_str = opt->val;
|
|
else if (def->val)
|
|
pghostaddr_str = def->val;
|
|
}
|
|
else if (strcmp(def->keyword, "port") == 0)
|
|
{
|
|
if (opt && opt->val)
|
|
pgport_str = opt->val;
|
|
else if (pgport)
|
|
pgport_str = pgport;
|
|
else if (def->val)
|
|
pgport_str = def->val;
|
|
}
|
|
|
|
if (opt)
|
|
opt++;
|
|
}
|
|
|
|
rv = PQpingParams(keywords, values, 1);
|
|
|
|
if (!quiet)
|
|
{
|
|
printf("%s:%s - ",
|
|
pghostaddr_str != NULL ? pghostaddr_str : pghost_str,
|
|
pgport_str);
|
|
|
|
switch (rv)
|
|
{
|
|
case PQPING_OK:
|
|
printf(_("accepting connections\n"));
|
|
break;
|
|
case PQPING_REJECT:
|
|
printf(_("rejecting connections\n"));
|
|
break;
|
|
case PQPING_NO_RESPONSE:
|
|
printf(_("no response\n"));
|
|
break;
|
|
case PQPING_NO_ATTEMPT:
|
|
printf(_("no attempt\n"));
|
|
break;
|
|
default:
|
|
printf(_("unknown\n"));
|
|
}
|
|
}
|
|
|
|
exit(rv);
|
|
}
|
|
|
|
static void
|
|
help(const char *progname)
|
|
{
|
|
printf(_("%s issues a connection check to a PostgreSQL database.\n\n"), progname);
|
|
printf(_("Usage:\n"));
|
|
printf(_(" %s [OPTION]...\n"), progname);
|
|
|
|
printf(_("\nOptions:\n"));
|
|
printf(_(" -d, --dbname=DBNAME database name\n"));
|
|
printf(_(" -q, --quiet run quietly\n"));
|
|
printf(_(" -V, --version output version information, then exit\n"));
|
|
printf(_(" -?, --help show this help, then exit\n"));
|
|
|
|
printf(_("\nConnection options:\n"));
|
|
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
|
|
printf(_(" -p, --port=PORT database server port\n"));
|
|
printf(_(" -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT);
|
|
printf(_(" -U, --username=USERNAME user name to connect as\n"));
|
|
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
|
|
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
|
|
}
|