diff --git a/check_dir.c b/check_dir.c
index 94e66c0b..26b07331 100644
--- a/check_dir.c
+++ b/check_dir.c
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
+ *
*/
#include
@@ -43,63 +43,63 @@ static int mkdir_p(char *path, mode_t omode);
int
check_dir(char *dir)
{
- DIR *chkdir;
- struct dirent *file;
- int result = 1;
+ DIR *chkdir;
+ struct dirent *file;
+ int result = 1;
- errno = 0;
+ errno = 0;
- chkdir = opendir(dir);
+ chkdir = opendir(dir);
- if (!chkdir)
- return (errno == ENOENT) ? 0 : -1;
+ if (!chkdir)
+ return (errno == ENOENT) ? 0 : -1;
- while ((file = readdir(chkdir)) != NULL)
- {
- if (strcmp(".", file->d_name) == 0 ||
- strcmp("..", file->d_name) == 0)
- {
- /* skip this and parent directory */
- continue;
- }
- else
- {
- result = 2; /* not empty */
- break;
- }
- }
+ while ((file = readdir(chkdir)) != NULL)
+ {
+ if (strcmp(".", file->d_name) == 0 ||
+ strcmp("..", file->d_name) == 0)
+ {
+ /* skip this and parent directory */
+ continue;
+ }
+ else
+ {
+ result = 2; /* not empty */
+ break;
+ }
+ }
#ifdef WIN32
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
- * released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
+ /*
+ * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
+ * released version
+ */
+ if (GetLastError() == ERROR_NO_MORE_FILES)
+ errno = 0;
#endif
- closedir(chkdir);
+ closedir(chkdir);
- if (errno != 0)
- return -1; /* some kind of I/O error? */
+ if (errno != 0)
+ return -1; /* some kind of I/O error? */
return result;
}
/*
- * Create directory
+ * Create directory
*/
bool
create_directory(char *dir)
{
- if (mkdir_p(dir, 0700) == 0)
- return true;
+ if (mkdir_p(dir, 0700) == 0)
+ return true;
- fprintf(stderr, _("Could not create directory \"%s\": %s\n"),
- dir, strerror(errno));
+ fprintf(stderr, _("Could not create directory \"%s\": %s\n"),
+ dir, strerror(errno));
- return false;
+ return false;
}
bool
@@ -126,10 +126,10 @@ mkdir_p(char *path, mode_t omode)
{
struct stat sb;
mode_t numask,
- oumask;
+ oumask;
int first,
- last,
- retval;
+ last,
+ retval;
char *p;
p = path;
@@ -148,8 +148,8 @@ mkdir_p(char *path, mode_t omode)
return 1;
}
else if (p[1] == ':' &&
- ((p[0] >= 'a' && p[0] <= 'z') ||
- (p[0] >= 'A' && p[0] <= 'Z')))
+ ((p[0] >= 'a' && p[0] <= 'z') ||
+ (p[0] >= 'A' && p[0] <= 'Z')))
{
/* local drive */
p += 2;
@@ -224,5 +224,5 @@ is_pg_dir(char *dir)
sprintf(path, "%s/PG_VERSION", dir);
- return (stat(path, &sb) == 0) ? true : false;
+ return (stat(path, &sb) == 0) ? true : false;
}
diff --git a/check_dir.h b/check_dir.h
index e42c92fd..9acac474 100644
--- a/check_dir.h
+++ b/check_dir.h
@@ -1,7 +1,7 @@
/*
* check_dir.h
* Copyright (c) 2ndQuadrant, 2010
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
diff --git a/config.c b/config.c
index d7512483..4499509f 100644
--- a/config.c
+++ b/config.c
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
+ *
*/
#include "repmgr.h"
@@ -55,28 +55,28 @@ parse_config(const char *config_file, char *cluster_name, int *node, char *conni
}
- /* Close file */
- fclose (fp);
+ /* Close file */
+ fclose (fp);
}
char *
trim (char *s)
{
- /* Initialize start, end pointers */
- char *s1 = s, *s2 = &s[strlen (s) - 1];
+ /* Initialize start, end pointers */
+ char *s1 = s, *s2 = &s[strlen (s) - 1];
- /* Trim and delimit right side */
- while ( (isspace (*s2)) && (s2 >= s1) )
- --s2;
- *(s2+1) = '\0';
+ /* Trim and delimit right side */
+ while ( (isspace (*s2)) && (s2 >= s1) )
+ --s2;
+ *(s2+1) = '\0';
- /* Trim left side */
- while ( (isspace (*s1)) && (s1 < s2) )
- ++s1;
+ /* Trim left side */
+ while ( (isspace (*s1)) && (s1 < s2) )
+ ++s1;
- /* Copy finished string */
- strcpy (s, s1);
- return s;
+ /* Copy finished string */
+ strcpy (s, s1);
+ return s;
}
void
@@ -99,7 +99,7 @@ parse_line(char *buff, char *name, char *value)
/*
* Now the value
- */
+ */
j = 0;
for ( ++i ; i < MAXLEN; ++i)
if (buff[i] == '\'')
diff --git a/config.h b/config.h
index 70a66472..9b2ea3fc 100644
--- a/config.h
+++ b/config.h
@@ -1,7 +1,7 @@
/*
* config.h
* Copyright (c) 2ndQuadrant, 2010
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
diff --git a/dbutils.c b/dbutils.c
index 3749b9f0..38b8c05f 100644
--- a/dbutils.c
+++ b/dbutils.c
@@ -6,15 +6,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
+ *
*/
#include "repmgr.h"
@@ -31,8 +31,8 @@ establishDBConnection(const char *conninfo, const bool exit_on_error)
/* Check to see that the backend connection was successfully made */
if ((PQstatus(conn) != CONNECTION_OK))
{
- fprintf(stderr, "Connection to database failed: %s",
- PQerrorMessage(conn));
+ fprintf(stderr, "Connection to database failed: %s",
+ PQerrorMessage(conn));
if (exit_on_error)
{
PQfinish(conn);
@@ -63,14 +63,14 @@ is_standby(PGconn *conn)
if (strcmp(PQgetvalue(res, 0, 0), "f") == 0)
result = false;
else
- result = true;
+ result = true;
PQclear(res);
return result;
}
-/*
+/*
* If postgreSQL version is 9 or superior returns the major version
* if 8 or inferior returns an empty string
*/
@@ -82,18 +82,18 @@ pg_version(PGconn *conn, char* major_version)
int major_version1;
char *major_version2;
- res = PQexec(conn, "WITH pg_version(ver) AS (SELECT split_part(version(), ' ', 2)) "
- "SELECT split_part(ver, '.', 1), split_part(ver, '.', 2) FROM pg_version");
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
+ res = PQexec(conn, "WITH pg_version(ver) AS (SELECT split_part(version(), ' ', 2)) "
+ "SELECT split_part(ver, '.', 1), split_part(ver, '.', 2) FROM pg_version");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn));
- PQclear(res);
+ PQclear(res);
PQfinish(conn);
exit(1);
- }
- major_version1 = atoi(PQgetvalue(res, 0, 0));
- major_version2 = PQgetvalue(res, 0, 1);
- PQclear(res);
+ }
+ major_version1 = atoi(PQgetvalue(res, 0, 0));
+ major_version2 = PQgetvalue(res, 0, 1);
+ PQclear(res);
if (major_version1 >= 9)
{
@@ -114,21 +114,21 @@ guc_setted(PGconn *conn, const char *parameter, const char *op, const char *valu
char sqlquery[MAXQUERY];
sprintf(sqlquery, "SELECT true FROM pg_settings "
- " WHERE name = '%s' AND setting %s '%s'",
- parameter, op, value);
+ " WHERE name = '%s' AND setting %s '%s'",
+ parameter, op, value);
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn));
- PQclear(res);
+ PQclear(res);
PQfinish(conn);
exit(1);
- }
+ }
if (PQntuples(res) == 0)
{
PQclear(res);
- return false;
+ return false;
}
PQclear(res);
@@ -144,51 +144,51 @@ get_cluster_size(PGconn *conn)
char sqlquery[MAXQUERY];
sprintf(sqlquery, "SELECT pg_size_pretty(SUM(pg_database_size(oid))::bigint) "
- " FROM pg_database ");
+ " FROM pg_database ");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn));
- PQclear(res);
+ PQclear(res);
PQfinish(conn);
exit(1);
- }
- size = PQgetvalue(res, 0, 0);
+ }
+ size = PQgetvalue(res, 0, 0);
PQclear(res);
return size;
}
/*
- * get a connection to master by reading repl_nodes, creating a connection
+ * get a connection to master by reading repl_nodes, creating a connection
* to each node (one at a time) and finding if it is a master or a standby
*/
PGconn *
getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id)
{
PGconn *master_conn = NULL;
- PGresult *res1;
- PGresult *res2;
+ PGresult *res1;
+ PGresult *res2;
char sqlquery[MAXQUERY];
char master_conninfo[MAXCONNINFO];
int i;
/* find all nodes belonging to this cluster */
sprintf(sqlquery, "SELECT * FROM repmgr_%s.repl_nodes "
- " WHERE cluster = '%s' and id <> %d",
- cluster, cluster, id);
+ " WHERE cluster = '%s' and id <> %d",
+ cluster, cluster, id);
- res1 = PQexec(standby_conn, sqlquery);
- if (PQresultStatus(res1) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get nodes info: %s\n", PQerrorMessage(standby_conn));
- PQclear(res1);
+ res1 = PQexec(standby_conn, sqlquery);
+ if (PQresultStatus(res1) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't get nodes info: %s\n", PQerrorMessage(standby_conn));
+ PQclear(res1);
PQfinish(standby_conn);
exit(1);
- }
+ }
for (i = 0; i < PQntuples(res1); i++)
- {
+ {
/* initialize with the values of the current node being processed */
*master_id = atoi(PQgetvalue(res1, i, 0));
strncpy(master_conninfo, PQgetvalue(res1, i, 2), MAXCONNINFO);
@@ -196,19 +196,19 @@ getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id)
if (PQstatus(master_conn) != CONNECTION_OK)
continue;
- /*
- * I can't use the is_standby() function here because on error that
- * function closes the connection i pass and exit, but i still need to close
+ /*
+ * I can't use the is_standby() function here because on error that
+ * function closes the connection i pass and exit, but i still need to close
* standby_conn
*/
- res2 = PQexec(master_conn, "SELECT pg_is_in_recovery()");
- if (PQresultStatus(res2) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get recovery state from this node: %s\n", PQerrorMessage(master_conn));
- PQclear(res2);
+ res2 = PQexec(master_conn, "SELECT pg_is_in_recovery()");
+ if (PQresultStatus(res2) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't get recovery state from this node: %s\n", PQerrorMessage(master_conn));
+ PQclear(res2);
PQfinish(master_conn);
continue;
- }
+ }
/* if false, this is the master */
if (strcmp(PQgetvalue(res2, 0, 0), "f") == 0)
@@ -224,16 +224,16 @@ getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id)
PQfinish(master_conn);
*master_id = -1;
}
- }
+ }
/* If we finish this loop without finding a master then
- * we doesn't have the info or the master has failed (or we
- * reached max_connections or superuser_reserved_connections,
- * anything else i'm missing?),
- * Probably we will need to check the error to know if we need
- * to start failover procedure or just fix some situation on the
- * standby.
- */
+ * we doesn't have the info or the master has failed (or we
+ * reached max_connections or superuser_reserved_connections,
+ * anything else i'm missing?),
+ * Probably we will need to check the error to know if we need
+ * to start failover procedure or just fix some situation on the
+ * standby.
+ */
PQclear(res1);
return NULL;
}
diff --git a/dbutils.h b/dbutils.h
index 32666cf7..cc5830d9 100644
--- a/dbutils.h
+++ b/dbutils.h
@@ -1,7 +1,7 @@
/*
* dbutils.h
* Copyright (c) 2ndQuadrant, 2010
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
diff --git a/repmgr.c b/repmgr.c
index 70103f87..8e2ce895 100644
--- a/repmgr.c
+++ b/repmgr.c
@@ -4,24 +4,24 @@
*
* This module is a command-line utility to easily setup a cluster of
* hot standby servers for an HA environment
- *
+ *
* Commands implemented are.
- * MASTER REGISTER, STANDBY REGISTER, STANDBY CLONE, STANDBY FOLLOW,
+ * MASTER REGISTER, STANDBY REGISTER, STANDBY CLONE, STANDBY FOLLOW,
* STANDBY PROMOTE
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
+ *
*/
#include "repmgr.h"
@@ -67,7 +67,7 @@ char *username = NULL;
char *dest_dir = NULL;
char *config_file = NULL;
char *remote_user = NULL;
-char *wal_keep_segments = NULL;
+char *wal_keep_segments = NULL;
bool verbose = false;
bool force = false;
@@ -81,7 +81,8 @@ char *server_cmd = NULL;
int
main(int argc, char **argv)
{
- static struct option long_options[] = {
+ static struct option long_options[] =
+ {
{"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
@@ -120,112 +121,112 @@ main(int argc, char **argv)
{
switch (c)
{
- case 'd':
- dbname = optarg;
- break;
- case 'h':
- host = optarg;
- break;
- case 'p':
- masterport = optarg;
- break;
- case 'U':
- username = optarg;
- break;
- case 'D':
- dest_dir = optarg;
- break;
- case 'f':
- config_file = optarg;
- break;
- case 'R':
- remote_user = optarg;
- break;
- case 'w':
- wal_keep_segments = optarg;
- break;
- case 'F':
- force = true;
- break;
- case 'v':
- verbose = true;
- break;
- default:
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
+ case 'd':
+ dbname = optarg;
+ break;
+ case 'h':
+ host = optarg;
+ break;
+ case 'p':
+ masterport = optarg;
+ break;
+ case 'U':
+ username = optarg;
+ break;
+ case 'D':
+ dest_dir = optarg;
+ break;
+ case 'f':
+ config_file = optarg;
+ break;
+ case 'R':
+ remote_user = optarg;
+ break;
+ case 'w':
+ wal_keep_segments = optarg;
+ break;
+ case 'F':
+ force = true;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
}
}
- /*
+ /*
* Now we need to obtain the action, this comes in one of these forms:
- * MASTER REGISTER |
- * STANDBY {REGISTER | CLONE [node] | PROMOTE | FOLLOW [node]}
- *
- * the node part is optional, if we receive it then we shouldn't
- * have received a -h option
- */
- if (optind < argc)
+ * MASTER REGISTER |
+ * STANDBY {REGISTER | CLONE [node] | PROMOTE | FOLLOW [node]}
+ *
+ * the node part is optional, if we receive it then we shouldn't
+ * have received a -h option
+ */
+ if (optind < argc)
{
- server_mode = argv[optind++];
+ server_mode = argv[optind++];
if (strcasecmp(server_mode, "STANDBY") != 0 && strcasecmp(server_mode, "MASTER") != 0)
{
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
- }
+ }
}
- if (optind < argc)
+ if (optind < argc)
{
- server_cmd = argv[optind++];
- if (strcasecmp(server_cmd, "REGISTER") == 0)
+ server_cmd = argv[optind++];
+ if (strcasecmp(server_cmd, "REGISTER") == 0)
{
- /*
- * we don't use this info in any other place so i will
- * just execute the compare again instead of having an
- * additional variable to hold a value that we will use
- * no more
- */
+ /*
+ * we don't use this info in any other place so i will
+ * just execute the compare again instead of having an
+ * additional variable to hold a value that we will use
+ * no more
+ */
if (strcasecmp(server_mode, "MASTER") == 0)
action = MASTER_REGISTER;
- else if (strcasecmp(server_mode, "STANDBY") == 0)
+ else if (strcasecmp(server_mode, "STANDBY") == 0)
action = STANDBY_REGISTER;
}
- else if (strcasecmp(server_cmd, "CLONE") == 0)
+ else if (strcasecmp(server_cmd, "CLONE") == 0)
action = STANDBY_CLONE;
- else if (strcasecmp(server_cmd, "PROMOTE") == 0)
+ else if (strcasecmp(server_cmd, "PROMOTE") == 0)
action = STANDBY_PROMOTE;
- else if (strcasecmp(server_cmd, "FOLLOW") == 0)
+ else if (strcasecmp(server_cmd, "FOLLOW") == 0)
action = STANDBY_FOLLOW;
else
{
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
- }
+ }
}
/* For some actions we still can receive a last argument */
if (action == STANDBY_CLONE)
{
- if (optind < argc)
+ if (optind < argc)
{
if (host != NULL)
{
fprintf(stderr, _("Conflicting parameters you can't use -h while providing a node separately. Try \"%s --help\" for more information.\n"), progname);
exit(1);
- }
- host = argv[optind++];
+ }
+ host = argv[optind++];
}
}
switch (optind < argc)
{
- case 0:
- break;
- default:
- fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
- progname, argv[optind + 1]);
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
+ case 0:
+ break;
+ default:
+ fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
+ progname, argv[optind + 1]);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
}
if (!check_parameters_for_action(action))
@@ -243,52 +244,52 @@ main(int argc, char **argv)
strcpy(wal_keep_segments, "5000");
}
- if (dbname == NULL)
- {
- if (getenv("PGDATABASE"))
- dbname = getenv("PGDATABASE");
- else if (getenv("PGUSER"))
- dbname = getenv("PGUSER");
- else
- dbname = "postgres";
- }
+ if (dbname == NULL)
+ {
+ if (getenv("PGDATABASE"))
+ dbname = getenv("PGDATABASE");
+ else if (getenv("PGUSER"))
+ dbname = getenv("PGUSER");
+ else
+ dbname = "postgres";
+ }
- keywords[2] = "user";
- values[2] = username;
- keywords[3] = "dbname";
- values[3] = dbname;
- keywords[4] = "application_name";
- values[4] = (char *) progname;
- keywords[5] = NULL;
- values[5] = NULL;
+ keywords[2] = "user";
+ values[2] = username;
+ keywords[3] = "dbname";
+ values[3] = dbname;
+ keywords[4] = "application_name";
+ values[4] = (char *) progname;
+ keywords[5] = NULL;
+ values[5] = NULL;
switch (action)
{
- case MASTER_REGISTER:
- do_master_register();
- break;
- case STANDBY_REGISTER:
- do_standby_register();
- break;
- case STANDBY_CLONE:
- do_standby_clone();
- break;
- case STANDBY_PROMOTE:
- do_standby_promote();
- break;
- case STANDBY_FOLLOW:
- do_standby_follow();
- break;
- default:
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
+ case MASTER_REGISTER:
+ do_master_register();
+ break;
+ case STANDBY_REGISTER:
+ do_standby_register();
+ break;
+ case STANDBY_CLONE:
+ do_standby_clone();
+ break;
+ case STANDBY_PROMOTE:
+ do_standby_promote();
+ break;
+ case STANDBY_FOLLOW:
+ do_standby_follow();
+ break;
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
}
-
- return 0;
+
+ return 0;
}
-static void
+static void
do_master_register(void)
{
PGconn *conn;
@@ -297,30 +298,30 @@ do_master_register(void)
char myClusterName[MAXLEN];
int myLocalId = -1;
- char conninfo[MAXLEN];
+ char conninfo[MAXLEN];
bool schema_exists = false;
char master_version[MAXVERSIONSTR];
/*
* Read the configuration file: repmgr.conf
- */
+ */
parse_config(config_file, myClusterName, &myLocalId, conninfo);
- if (myLocalId == -1)
+ if (myLocalId == -1)
{
fprintf(stderr, "Node information is missing. "
- "Check the configuration file.\n");
+ "Check the configuration file.\n");
exit(1);
}
- conn = establishDBConnection(conninfo, true);
+ conn = establishDBConnection(conninfo, true);
/* master should be v9 or better */
pg_version(conn, master_version);
if (strcmp(master_version, "") == 0)
{
PQfinish(conn);
- fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -335,83 +336,83 @@ do_master_register(void)
/* Check if there is a schema for this cluster */
sprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = 'repmgr_%s'", myClusterName);
res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "Can't get info about schemas: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
+ fprintf(stderr, "Can't get info about schemas: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
}
-
+
if (PQntuples(res) > 0) /* schema exists */
{
if (!force) /* and we are not forcing so error */
{
- fprintf(stderr, "Schema repmgr_%s already exists.", myClusterName);
- PQclear(res);
- PQfinish(conn);
+ fprintf(stderr, "Schema repmgr_%s already exists.", myClusterName);
+ PQclear(res);
+ PQfinish(conn);
return;
}
schema_exists = true;
}
PQclear(res);
-
+
if (!schema_exists)
{
/* ok, create the schema */
sprintf(sqlquery, "CREATE SCHEMA repmgr_%s", myClusterName);
- if (!PQexec(conn, sqlquery))
+ if (!PQexec(conn, sqlquery))
{
fprintf(stderr, "Cannot create the schema repmgr_%s: %s\n",
- myClusterName, PQerrorMessage(conn));
- PQfinish(conn);
- return;
- }
-
- /* ... the tables */
- sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_nodes ( "
- " id integer primary key, "
- " cluster text not null, "
- " conninfo text not null)", myClusterName);
- if (!PQexec(conn, sqlquery))
- {
- fprintf(stderr, "Cannot create the table repmgr_%s.repl_nodes: %s\n",
- myClusterName, PQerrorMessage(conn));
- PQfinish(conn);
- return;
- }
-
- sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_monitor ( "
- " primary_node INTEGER NOT NULL, "
- " standby_node INTEGER NOT NULL, "
- " last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, "
- " last_wal_primary_location TEXT NOT NULL, "
- " last_wal_standby_location TEXT NOT NULL, "
- " replication_lag BIGINT NOT NULL, "
- " apply_lag BIGINT NOT NULL) ", myClusterName);
- if (!PQexec(conn, sqlquery))
- {
- fprintf(stderr, "Cannot create the table repmgr_%s.repl_monitor: %s\n",
- myClusterName, PQerrorMessage(conn));
- PQfinish(conn);
+ myClusterName, PQerrorMessage(conn));
+ PQfinish(conn);
return;
}
- /* and the view */
+ /* ... the tables */
+ sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_nodes ( "
+ " id integer primary key, "
+ " cluster text not null, "
+ " conninfo text not null)", myClusterName);
+ if (!PQexec(conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot create the table repmgr_%s.repl_nodes: %s\n",
+ myClusterName, PQerrorMessage(conn));
+ PQfinish(conn);
+ return;
+ }
+
+ sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_monitor ( "
+ " primary_node INTEGER NOT NULL, "
+ " standby_node INTEGER NOT NULL, "
+ " last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, "
+ " last_wal_primary_location TEXT NOT NULL, "
+ " last_wal_standby_location TEXT NOT NULL, "
+ " replication_lag BIGINT NOT NULL, "
+ " apply_lag BIGINT NOT NULL) ", myClusterName);
+ if (!PQexec(conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot create the table repmgr_%s.repl_monitor: %s\n",
+ myClusterName, PQerrorMessage(conn));
+ PQfinish(conn);
+ return;
+ }
+
+ /* and the view */
sprintf(sqlquery, "CREATE VIEW repmgr_%s.repl_status AS "
- " WITH monitor_info AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY primary_node, standby_node "
- " ORDER BY last_monitor_time desc) "
- " FROM repmgr_%s.repl_monitor) "
- " SELECT primary_node, standby_node, last_monitor_time, last_wal_primary_location, "
- " last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag, "
- " pg_size_pretty(apply_lag) apply_lag, age(now(), last_monitor_time) AS time_lag "
- " FROM monitor_info a "
- " WHERE row_number = 1", myClusterName, myClusterName);
- if (!PQexec(conn, sqlquery))
+ " WITH monitor_info AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY primary_node, standby_node "
+ " ORDER BY last_monitor_time desc) "
+ " FROM repmgr_%s.repl_monitor) "
+ " SELECT primary_node, standby_node, last_monitor_time, last_wal_primary_location, "
+ " last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag, "
+ " pg_size_pretty(apply_lag) apply_lag, age(now(), last_monitor_time) AS time_lag "
+ " FROM monitor_info a "
+ " WHERE row_number = 1", myClusterName, myClusterName);
+ if (!PQexec(conn, sqlquery))
{
fprintf(stderr, "Cannot create the view repmgr_%s.repl_status: %s\n",
- myClusterName, PQerrorMessage(conn));
- PQfinish(conn);
+ myClusterName, PQerrorMessage(conn));
+ PQfinish(conn);
return;
}
}
@@ -421,7 +422,7 @@ do_master_register(void)
int id;
/* Ensure there isn't any other master already registered */
- master_conn = getMasterConnection(conn, myLocalId, myClusterName, &id);
+ master_conn = getMasterConnection(conn, myLocalId, myClusterName, &id);
if (master_conn != NULL)
{
PQfinish(master_conn);
@@ -433,37 +434,37 @@ do_master_register(void)
/* Now register the master */
if (force)
{
- sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
- " WHERE id = %d",
- myClusterName, myLocalId);
+ sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
+ " WHERE id = %d",
+ myClusterName, myLocalId);
- if (!PQexec(conn, sqlquery))
- {
- fprintf(stderr, "Cannot delete node details, %s\n",
- PQerrorMessage(conn));
- PQfinish(conn);
+ if (!PQexec(conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot delete node details, %s\n",
+ PQerrorMessage(conn));
+ PQfinish(conn);
return;
- }
+ }
}
- sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
- "VALUES (%d, '%s', '%s')",
- myClusterName, myLocalId, myClusterName, conninfo);
-
- if (!PQexec(conn, sqlquery))
- {
- fprintf(stderr, "Cannot insert node details, %s\n",
- PQerrorMessage(conn));
- PQfinish(conn);
+ sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
+ "VALUES (%d, '%s', '%s')",
+ myClusterName, myLocalId, myClusterName, conninfo);
+
+ if (!PQexec(conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot insert node details, %s\n",
+ PQerrorMessage(conn));
+ PQfinish(conn);
return;
- }
+ }
PQfinish(conn);
return;
}
-static void
+static void
do_standby_register(void)
{
PGconn *conn;
@@ -475,30 +476,30 @@ do_standby_register(void)
char myClusterName[MAXLEN];
int myLocalId = -1;
- char conninfo[MAXLEN];
+ char conninfo[MAXLEN];
char master_version[MAXVERSIONSTR];
char standby_version[MAXVERSIONSTR];
/*
* Read the configuration file: repmgr.conf
- */
+ */
parse_config(config_file, myClusterName, &myLocalId, conninfo);
- if (myLocalId == -1)
+ if (myLocalId == -1)
{
fprintf(stderr, "Node information is missing. "
- "Check the configuration file.\n");
+ "Check the configuration file.\n");
exit(1);
}
- conn = establishDBConnection(conninfo, true);
+ conn = establishDBConnection(conninfo, true);
/* should be v9 or better */
pg_version(conn, standby_version);
if (strcmp(standby_version, "") == 0)
{
PQfinish(conn);
- fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -513,23 +514,23 @@ do_standby_register(void)
/* Check if there is a schema for this cluster */
sprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = 'repmgr_%s'", myClusterName);
res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
+ fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
}
-
+
if (PQntuples(res) == 0) /* schema doesn't exists */
{
- fprintf(stderr, "Schema repmgr_%s doesn't exists.", myClusterName);
- PQclear(res);
- PQfinish(conn);
+ fprintf(stderr, "Schema repmgr_%s doesn't exists.", myClusterName);
+ PQclear(res);
+ PQfinish(conn);
return;
}
PQclear(res);
-
+
/* check if there is a master in this cluster */
master_conn = getMasterConnection(conn, myLocalId, myClusterName, &master_id);
if (!master_conn)
@@ -541,7 +542,7 @@ do_standby_register(void)
{
PQfinish(conn);
PQfinish(master_conn);
- fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -550,8 +551,8 @@ do_standby_register(void)
{
PQfinish(conn);
PQfinish(master_conn);
- fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"),
- progname, master_version, standby_version);
+ fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"),
+ progname, master_version, standby_version);
return;
}
@@ -559,32 +560,32 @@ do_standby_register(void)
/* Now register the standby */
if (force)
{
- sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
- " WHERE id = %d",
- myClusterName, myLocalId);
+ sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
+ " WHERE id = %d",
+ myClusterName, myLocalId);
- if (!PQexec(master_conn, sqlquery))
- {
- fprintf(stderr, "Cannot delete node details, %s\n",
- PQerrorMessage(master_conn));
- PQfinish(master_conn);
- PQfinish(conn);
+ if (!PQexec(master_conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot delete node details, %s\n",
+ PQerrorMessage(master_conn));
+ PQfinish(master_conn);
+ PQfinish(conn);
return;
- }
+ }
}
- sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
- "VALUES (%d, '%s', '%s')",
- myClusterName, myLocalId, myClusterName, conninfo);
-
- if (!PQexec(master_conn, sqlquery))
- {
- fprintf(stderr, "Cannot insert node details, %s\n",
- PQerrorMessage(master_conn));
- PQfinish(master_conn);
- PQfinish(conn);
+ sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
+ "VALUES (%d, '%s', '%s')",
+ myClusterName, myLocalId, myClusterName, conninfo);
+
+ if (!PQexec(master_conn, sqlquery))
+ {
+ fprintf(stderr, "Cannot insert node details, %s\n",
+ PQerrorMessage(master_conn));
+ PQfinish(master_conn);
+ PQfinish(conn);
return;
- }
+ }
PQfinish(master_conn);
PQfinish(conn);
@@ -592,7 +593,7 @@ do_standby_register(void)
}
-static void
+static void
do_standby_clone(void)
{
PGconn *conn;
@@ -610,8 +611,8 @@ do_standby_clone(void)
char master_control_file[MAXLEN];
char local_control_file[MAXLEN];
- const char *first_wal_segment = NULL;
- const char *last_wal_segment = NULL;
+ const char *first_wal_segment = NULL;
+ const char *last_wal_segment = NULL;
char master_version[MAXVERSIONSTR];
@@ -623,84 +624,84 @@ do_standby_clone(void)
}
/* Check this directory could be used as a PGDATA dir */
- switch (check_dir(dest_dir))
- {
- case 0:
- /* dest_dir not there, must create it */
- if (verbose)
- printf(_("creating directory %s ... "), dest_dir);
- fflush(stdout);
+ switch (check_dir(dest_dir))
+ {
+ case 0:
+ /* dest_dir not there, must create it */
+ if (verbose)
+ printf(_("creating directory %s ... "), dest_dir);
+ fflush(stdout);
- if (!create_directory(dest_dir))
- {
- fprintf(stderr, _("%s: couldn't create directory %s ... "),
- progname, dest_dir);
- return;
- }
- break;
- case 1:
- /* Present but empty, fix permissions and use it */
- if (verbose)
- printf(_("fixing permissions on existing directory %s ... "),
- dest_dir);
- fflush(stdout);
+ if (!create_directory(dest_dir))
+ {
+ fprintf(stderr, _("%s: couldn't create directory %s ... "),
+ progname, dest_dir);
+ return;
+ }
+ break;
+ case 1:
+ /* Present but empty, fix permissions and use it */
+ if (verbose)
+ printf(_("fixing permissions on existing directory %s ... "),
+ dest_dir);
+ fflush(stdout);
- if (!set_directory_permissions(dest_dir))
- {
- fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
- progname, dest_dir, strerror(errno));
- return;
- }
- break;
- case 2:
- /* Present and not empty */
- fprintf(stderr,
- _("%s: directory \"%s\" exists but is not empty\n"),
- progname, dest_dir);
+ if (!set_directory_permissions(dest_dir))
+ {
+ fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
+ progname, dest_dir, strerror(errno));
+ return;
+ }
+ break;
+ case 2:
+ /* Present and not empty */
+ fprintf(stderr,
+ _("%s: directory \"%s\" exists but is not empty\n"),
+ progname, dest_dir);
pg_dir = is_pg_dir(dest_dir);
- if (pg_dir && !force)
- {
- fprintf(stderr, _("\nThis looks like a PostgreSQL directroy.\n"
- "If you are sure you want to clone here, "
- "please check there is no PostgreSQL server "
- "running and use the --force option\n"));
- return;
- }
- else if (pg_dir && force)
- {
- /* Let it continue */
- break;
- }
- else
- return;
- default:
- /* Trouble accessing directory */
- fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
- progname, dest_dir, strerror(errno));
- }
+ if (pg_dir && !force)
+ {
+ fprintf(stderr, _("\nThis looks like a PostgreSQL directroy.\n"
+ "If you are sure you want to clone here, "
+ "please check there is no PostgreSQL server "
+ "running and use the --force option\n"));
+ return;
+ }
+ else if (pg_dir && force)
+ {
+ /* Let it continue */
+ break;
+ }
+ else
+ return;
+ default:
+ /* Trouble accessing directory */
+ fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
+ progname, dest_dir, strerror(errno));
+ }
- /* Connection parameters for master only */
- keywords[0] = "host";
- values[0] = host;
- keywords[1] = "port";
- values[1] = masterport;
+ /* Connection parameters for master only */
+ keywords[0] = "host";
+ values[0] = host;
+ keywords[1] = "port";
+ values[1] = masterport;
/* We need to connect to check configuration and start a backup */
- conn = PQconnectdbParams(keywords, values, true);
- if (!conn)
- {
- fprintf(stderr, _("%s: could not connect to master\n"),
- progname);
- return;
- }
+ conn = PQconnectdbParams(keywords, values, true);
+ if (!conn)
+ {
+ fprintf(stderr, _("%s: could not connect to master\n"),
+ progname);
+ return;
+ }
/* primary should be v9 or better */
pg_version(conn, master_version);
if (strcmp(master_version, "") == 0)
{
PQfinish(conn);
- fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -716,19 +717,19 @@ do_standby_clone(void)
if (!guc_setted(conn, "wal_level", "=", "hot_standby"))
{
PQfinish(conn);
- fprintf(stderr, _("%s needs parameter 'wal_level' to be set to 'hot_standby'\n"), progname);
+ fprintf(stderr, _("%s needs parameter 'wal_level' to be set to 'hot_standby'\n"), progname);
return;
}
if (!guc_setted(conn, "wal_keep_segments", ">=", wal_keep_segments))
{
PQfinish(conn);
- fprintf(stderr, _("%s needs parameter 'wal_keep_segments' to be set to %s or greater\n"), wal_keep_segments, progname);
+ fprintf(stderr, _("%s needs parameter 'wal_keep_segments' to be set to %s or greater\n"), wal_keep_segments, progname);
return;
}
if (!guc_setted(conn, "archive_mode", "=", "on"))
{
PQfinish(conn);
- fprintf(stderr, _("%s needs parameter 'archive_mode' to be set to 'on'\n"), progname);
+ fprintf(stderr, _("%s needs parameter 'archive_mode' to be set to 'on'\n"), progname);
return;
}
@@ -737,13 +738,13 @@ do_standby_clone(void)
/* Check if the tablespace locations exists and that we can write to them */
sprintf(sqlquery, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
+ fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
}
for (i = 0; i < PQntuples(res); i++)
{
@@ -751,74 +752,74 @@ do_standby_clone(void)
strcpy(tblspc_dir, PQgetvalue(res, i, 0));
/* Check this directory could be used as a PGDATA dir */
- switch (check_dir(tblspc_dir))
- {
- case 0:
- /* tblspc_dir not there, must create it */
- if (verbose)
- printf(_("creating directory \"%s\"... "), tblspc_dir);
- fflush(stdout);
-
- if (!create_directory(tblspc_dir))
- {
- fprintf(stderr, _("%s: couldn't create directory \"%s\"... "),
- progname, tblspc_dir);
- PQclear(res);
- PQfinish(conn);
- return;
- }
- break;
- case 1:
- /* Present but empty, fix permissions and use it */
- if (verbose)
- printf(_("fixing permissions on existing directory \"%s\"... "),
- tblspc_dir);
- fflush(stdout);
-
- if (!set_directory_permissions(tblspc_dir))
- {
- fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
- progname, tblspc_dir, strerror(errno));
- PQclear(res);
- PQfinish(conn);
- return;
- }
- break;
- case 2:
- /* Present and not empty */
+ switch (check_dir(tblspc_dir))
+ {
+ case 0:
+ /* tblspc_dir not there, must create it */
+ if (verbose)
+ printf(_("creating directory \"%s\"... "), tblspc_dir);
+ fflush(stdout);
+
+ if (!create_directory(tblspc_dir))
+ {
+ fprintf(stderr, _("%s: couldn't create directory \"%s\"... "),
+ progname, tblspc_dir);
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
+ break;
+ case 1:
+ /* Present but empty, fix permissions and use it */
+ if (verbose)
+ printf(_("fixing permissions on existing directory \"%s\"... "),
+ tblspc_dir);
+ fflush(stdout);
+
+ if (!set_directory_permissions(tblspc_dir))
+ {
+ fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
+ progname, tblspc_dir, strerror(errno));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
+ break;
+ case 2:
+ /* Present and not empty */
if (!force)
{
fprintf(stderr,
- _("%s: directory \"%s\" exists but is not empty\n"),
- progname, tblspc_dir);
+ _("%s: directory \"%s\" exists but is not empty\n"),
+ progname, tblspc_dir);
PQclear(res);
PQfinish(conn);
- return;
+ return;
}
- default:
- /* Trouble accessing directory */
- fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
- progname, tblspc_dir, strerror(errno));
+ default:
+ /* Trouble accessing directory */
+ fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
+ progname, tblspc_dir, strerror(errno));
PQclear(res);
PQfinish(conn);
return;
}
}
-
+
fprintf(stderr, "Starting backup...\n");
-
+
/* Get the data directory full path and the configuration files location */
sprintf(sqlquery, "SELECT name, setting "
- " FROM pg_settings "
- " WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file')");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get info about data directory and configuration files: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
- }
+ " FROM pg_settings "
+ " WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file')");
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't get info about data directory and configuration files: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
for (i = 0; i < PQntuples(res); i++)
{
if (strcmp(PQgetvalue(res, i, 0), "data_directory") == 0)
@@ -832,32 +833,32 @@ do_standby_clone(void)
else
fprintf(stderr, _("uknown parameter: %s"), PQgetvalue(res, i, 0));
}
- PQclear(res);
+ PQclear(res);
- /*
- * inform the master we will start a backup and get the first XLog filename
+ /*
+ * inform the master we will start a backup and get the first XLog filename
* so we can say to the user we need those files
- */
+ */
sprintf(sqlquery, "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", time(NULL));
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't start backup: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
- }
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't start backup: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
first_wal_segment = PQgetvalue(res, 0, 0);
PQclear(res);
/*
- * 1) first move global/pg_control
+ * 1) first move global/pg_control
*
* 2) then move data_directory ommiting the files we have already moved and pg_xlog
* content
*
* 3) finally We need to backup configuration files (that could be on other directories, debian
- * like systems likes to do that), so look at config_file, hba_file and ident_file but we
+ * like systems likes to do that), so look at config_file, hba_file and ident_file but we
* can omit external_pid_file ;)
*
* On error we need to return but before that execute pg_stop_backup()
@@ -867,90 +868,90 @@ do_standby_clone(void)
sprintf(master_control_file, "%s/global/pg_control", master_data_directory);
sprintf(local_control_file, "%s/global", dest_dir);
if (!create_directory(local_control_file))
- {
- fprintf(stderr, _("%s: couldn't create directory %s ... "),
- progname, dest_dir);
+ {
+ fprintf(stderr, _("%s: couldn't create directory %s ... "),
+ progname, dest_dir);
goto stop_backup;
}
- r = copy_remote_files(host, remote_user, master_control_file, local_control_file, false);
+ r = copy_remote_files(host, remote_user, master_control_file, local_control_file, false);
if (r != 0)
goto stop_backup;
- r = copy_remote_files(host, remote_user, master_data_directory, dest_dir, true);
+ r = copy_remote_files(host, remote_user, master_data_directory, dest_dir, true);
if (r != 0)
goto stop_backup;
- /*
+ /*
* Copy tablespace locations, i'm doing this separately because i couldn't find and appropiate
- * rsync option but besides we could someday make all these rsync happen concurrently
- */
- sprintf(sqlquery, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
- PQclear(res);
- goto stop_backup;
- }
- for (i = 0; i < PQntuples(res); i++)
+ * rsync option but besides we could someday make all these rsync happen concurrently
+ */
+ sprintf(sqlquery, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
- r = copy_remote_files(host, remote_user, PQgetvalue(res, i, 0), PQgetvalue(res, i, 0), true);
+ fprintf(stderr, "Can't get info about tablespaces: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ goto stop_backup;
+ }
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ r = copy_remote_files(host, remote_user, PQgetvalue(res, i, 0), PQgetvalue(res, i, 0), true);
if (r != 0)
goto stop_backup;
}
- r = copy_remote_files(host, remote_user, master_config_file, dest_dir, false);
+ r = copy_remote_files(host, remote_user, master_config_file, dest_dir, false);
if (r != 0)
goto stop_backup;
- r = copy_remote_files(host, remote_user, master_hba_file, dest_dir, false);
+ r = copy_remote_files(host, remote_user, master_hba_file, dest_dir, false);
if (r != 0)
goto stop_backup;
- r = copy_remote_files(host, remote_user, master_ident_file, dest_dir, false);
+ r = copy_remote_files(host, remote_user, master_ident_file, dest_dir, false);
if (r != 0)
goto stop_backup;
stop_backup:
- /* inform the master that we have finished the backup */
- conn = PQconnectdbParams(keywords, values, true);
- if (!conn)
- {
- fprintf(stderr, _("%s: could not connect to master\n"),
- progname);
- return;
- }
+ /* inform the master that we have finished the backup */
+ conn = PQconnectdbParams(keywords, values, true);
+ if (!conn)
+ {
+ fprintf(stderr, _("%s: could not connect to master\n"),
+ progname);
+ return;
+ }
- fprintf(stderr, "Finishing backup...\n");
+ fprintf(stderr, "Finishing backup...\n");
sprintf(sqlquery, "SELECT pg_xlogfile_name(pg_stop_backup())");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't stop backup: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
- }
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't stop backup: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
last_wal_segment = PQgetvalue(res, 0, 0);
- PQclear(res);
- PQfinish(conn);
+ PQclear(res);
+ PQfinish(conn);
/* Now, if the rsync failed then exit */
if (r != 0)
return;
if (verbose)
- printf(_("%s requires primary to keep WAL files %s until at least %s\n"),
- progname, first_wal_segment, last_wal_segment);
+ printf(_("%s requires primary to keep WAL files %s until at least %s\n"),
+ progname, first_wal_segment, last_wal_segment);
/* we need to create the pg_xlog sub directory too, i'm reusing a variable here */
sprintf(local_control_file, "%s/pg_xlog", dest_dir);
if (!create_directory(local_control_file))
- {
- fprintf(stderr, _("%s: couldn't create directory %s, you will need to do it manually...\n"),
- progname, dest_dir);
+ {
+ fprintf(stderr, _("%s: couldn't create directory %s, you will need to do it manually...\n"),
+ progname, dest_dir);
}
/* Finally, write the recovery.conf file */
@@ -961,7 +962,7 @@ stop_backup:
}
-static void
+static void
do_standby_promote(void)
{
PGconn *conn;
@@ -971,7 +972,7 @@ do_standby_promote(void)
char myClusterName[MAXLEN];
int myLocalId = -1;
- char conninfo[MAXLEN];
+ char conninfo[MAXLEN];
PGconn *old_master_conn;
int old_master_id;
@@ -985,24 +986,24 @@ do_standby_promote(void)
/*
* Read the configuration file: repmgr.conf
- */
+ */
parse_config(config_file, myClusterName, &myLocalId, conninfo);
- if (myLocalId == -1)
+ if (myLocalId == -1)
{
fprintf(stderr, "Node information is missing. "
- "Check the configuration file.\n");
+ "Check the configuration file.\n");
exit(1);
}
/* We need to connect to check configuration */
- conn = establishDBConnection(conninfo, true);
+ conn = establishDBConnection(conninfo, true);
/* we need v9 or better */
pg_version(conn, standby_version);
if (strcmp(standby_version, "") == 0)
{
PQfinish(conn);
- fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -1014,7 +1015,7 @@ do_standby_promote(void)
}
/* we also need to check if there isn't any master already */
- old_master_conn = getMasterConnection(conn, myLocalId, myClusterName, &old_master_id);
+ old_master_conn = getMasterConnection(conn, myLocalId, myClusterName, &old_master_id);
if (old_master_conn != NULL)
{
PQfinish(old_master_conn);
@@ -1024,21 +1025,21 @@ do_standby_promote(void)
if (verbose)
printf(_("\n%s: Promoting standby...\n"), progname);
-
+
/* Get the data directory full path and the last subdirectory */
sprintf(sqlquery, "SELECT setting "
- " FROM pg_settings WHERE name = 'data_directory'");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get info about data directory: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
- }
+ " FROM pg_settings WHERE name = 'data_directory'");
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't get info about data directory: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
strcpy(data_dir, PQgetvalue(res, 0, 0));
- PQclear(res);
- PQfinish(conn);
+ PQclear(res);
+ PQfinish(conn);
sprintf(recovery_file_path, "%s/%s", data_dir, RECOVERY_FILE);
sprintf(recovery_done_path, "%s/%s", data_dir, RECOVERY_DONE_FILE);
@@ -1047,29 +1048,29 @@ do_standby_promote(void)
/* We assume the pg_ctl script is in the PATH */
sprintf(script, "pg_ctl -D %s -m fast restart", data_dir);
r = system(script);
- if (r != 0)
- {
- fprintf(stderr, "Can't restart service\n");
+ if (r != 0)
+ {
+ fprintf(stderr, "Can't restart service\n");
return;
- }
+ }
/* reconnect to check we got promoted */
- /*
- * XXX i'm removing this because it gives an annoying message saying couldn't connect
- * but is just the server starting up
-* conn = establishDBConnection(conninfo, true);
-* if (is_standby(conn))
-* fprintf(stderr, "\n%s: STANDBY PROMOTE failed, this is still a standby node.\n", progname);
-* else
-* fprintf(stderr, "\n%s: you should REINDEX any hash indexes you have.\n", progname);
-* PQfinish(conn);
+ /*
+ * XXX i'm removing this because it gives an annoying message saying couldn't connect
+ * but is just the server starting up
+ * conn = establishDBConnection(conninfo, true);
+ * if (is_standby(conn))
+ * fprintf(stderr, "\n%s: STANDBY PROMOTE failed, this is still a standby node.\n", progname);
+ * else
+ * fprintf(stderr, "\n%s: you should REINDEX any hash indexes you have.\n", progname);
+ * PQfinish(conn);
*/
return;
}
-static void
+static void
do_standby_follow(void)
{
PGconn *conn;
@@ -1079,7 +1080,7 @@ do_standby_follow(void)
char myClusterName[MAXLEN];
int myLocalId = -1;
- char conninfo[MAXLEN];
+ char conninfo[MAXLEN];
PGconn *master_conn;
int master_id;
@@ -1092,17 +1093,17 @@ do_standby_follow(void)
/*
* Read the configuration file: repmgr.conf
- */
+ */
parse_config(config_file, myClusterName, &myLocalId, conninfo);
- if (myLocalId == -1)
+ if (myLocalId == -1)
{
fprintf(stderr, "Node information is missing. "
- "Check the configuration file.\n");
+ "Check the configuration file.\n");
exit(1);
}
/* We need to connect to check configuration */
- conn = establishDBConnection(conninfo, true);
+ conn = establishDBConnection(conninfo, true);
/* Check we are in a standby node */
if (!is_standby(conn))
@@ -1116,12 +1117,12 @@ do_standby_follow(void)
if (strcmp(standby_version, "") == 0)
{
PQfinish(conn);
- fprintf(stderr, _("\n%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("\n%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
return;
}
/* we also need to check if there is any master in the cluster */
- master_conn = getMasterConnection(conn, myLocalId, myClusterName, &master_id);
+ master_conn = getMasterConnection(conn, myLocalId, myClusterName, &master_id);
if (master_conn == NULL)
{
PQfinish(conn);
@@ -1143,7 +1144,7 @@ do_standby_follow(void)
{
PQfinish(conn);
PQfinish(master_conn);
- fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname);
return;
}
@@ -1152,14 +1153,14 @@ do_standby_follow(void)
{
PQfinish(conn);
PQfinish(master_conn);
- fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"),
- progname, master_version, standby_version);
+ fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"),
+ progname, master_version, standby_version);
return;
}
- /*
- * set the host and masterport variables with the master ones
- * before closing the connection because we will need them to
+ /*
+ * set the host and masterport variables with the master ones
+ * before closing the connection because we will need them to
* recreate the recovery.conf file
*/
host = malloc(20);
@@ -1170,48 +1171,48 @@ do_standby_follow(void)
if (verbose)
printf(_("\n%s: Changing standby's master...\n"), progname);
-
+
/* Get the data directory full path */
sprintf(sqlquery, "SELECT setting "
- " FROM pg_settings WHERE name = 'data_directory'");
- res = PQexec(conn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "Can't get info about data directory: %s\n", PQerrorMessage(conn));
- PQclear(res);
- PQfinish(conn);
- return;
- }
+ " FROM pg_settings WHERE name = 'data_directory'");
+ res = PQexec(conn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "Can't get info about data directory: %s\n", PQerrorMessage(conn));
+ PQclear(res);
+ PQfinish(conn);
+ return;
+ }
strcpy(data_dir, PQgetvalue(res, 0, 0));
- PQclear(res);
- PQfinish(conn);
+ PQclear(res);
+ PQfinish(conn);
/* write the recovery.conf file */
if (!create_recovery_file(data_dir))
- return;
+ return;
/* Finally, restart the service */
/* We assume the pg_ctl script is in the PATH */
sprintf(script, "pg_ctl -D %s -m fast restart", data_dir);
r = system(script);
- if (r != 0)
- {
- fprintf(stderr, "Can't restart service\n");
+ if (r != 0)
+ {
+ fprintf(stderr, "Can't restart service\n");
return;
- }
+ }
return;
}
-static void
+static void
help(const char *progname)
{
- printf(_("\n%s: Replicator manager \n"), progname);
- printf(_("Usage:\n"));
- printf(_(" %s [OPTIONS] master {register}\n"), progname);
- printf(_(" %s [OPTIONS] standby {register|clone|promote|follow}\n"), progname);
- printf(_("\nGeneral options:\n"));
+ printf(_("\n%s: Replicator manager \n"), progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTIONS] master {register}\n"), progname);
+ printf(_(" %s [OPTIONS] standby {register|clone|promote|follow}\n"), progname);
+ printf(_("\nGeneral options:\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_(" --verbose output verbose activity information\n"));
@@ -1226,16 +1227,16 @@ help(const char *progname)
printf(_(" -R, --remote-user=USERNAME database server username for rsync\n"));
printf(_(" -w, --wal-keep-segments=VALUE minimum value for the GUC wal_keep_segments (default: 5000)\n"));
printf(_(" -F, --force force potentially dangerous operations to happen\n"));
-
+
printf(_("\n%s performs some tasks like clone a node, promote it "), progname);
- printf(_("or making follow another node and then exits.\n"));
- printf(_("COMMANDS:\n"));
- printf(_(" master register - registers the master in a cluster\n"));
- printf(_(" standby register - registers a standby in a cluster\n"));
- printf(_(" standby clone [node] - allows creation of a new standby\n"));
- printf(_(" standby promote - allows manual promotion of a specific standby into a "));
- printf(_("new master in the event of a failover\n"));
- printf(_(" standby follow - allows the standby to re-point itself to a new master\n"));
+ printf(_("or making follow another node and then exits.\n"));
+ printf(_("COMMANDS:\n"));
+ printf(_(" master register - registers the master in a cluster\n"));
+ printf(_(" standby register - registers a standby in a cluster\n"));
+ printf(_(" standby clone [node] - allows creation of a new standby\n"));
+ printf(_(" standby promote - allows manual promotion of a specific standby into a "));
+ printf(_("new master in the event of a failover\n"));
+ printf(_(" standby follow - allows the standby to re-point itself to a new master\n"));
}
@@ -1248,31 +1249,31 @@ create_recovery_file(const char *data_dir)
sprintf(recovery_file_path, "%s/%s", data_dir, RECOVERY_FILE);
- recovery_file = fopen(recovery_file_path, "w");
- if (recovery_file == NULL)
- {
- fprintf(stderr, "could not create recovery.conf file, it could be necesary to create it manually\n");
+ recovery_file = fopen(recovery_file_path, "w");
+ if (recovery_file == NULL)
+ {
+ fprintf(stderr, "could not create recovery.conf file, it could be necesary to create it manually\n");
return false;
- }
+ }
sprintf(line, "standby_mode = 'on'\n");
if (fputs(line, recovery_file) == EOF)
- {
- fprintf(stderr, "recovery file could not be written, it could be necesary to create it manually\n");
- fclose(recovery_file);
+ {
+ fprintf(stderr, "recovery file could not be written, it could be necesary to create it manually\n");
+ fclose(recovery_file);
return false;
- }
+ }
sprintf(line, "primary_conninfo = 'host=%s port=%s'\n", host, ((masterport==NULL) ? "5432" : masterport));
if (fputs(line, recovery_file) == EOF)
- {
- fprintf(stderr, "recovery file could not be written, it could be necesary to create it manually\n");
- fclose(recovery_file);
+ {
+ fprintf(stderr, "recovery file could not be written, it could be necesary to create it manually\n");
+ fclose(recovery_file);
return false;
- }
+ }
- /*FreeFile(recovery_file);*/
- fclose(recovery_file);
+ /*FreeFile(recovery_file);*/
+ fclose(recovery_file);
return true;
}
@@ -1286,7 +1287,7 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, char *local_
char host_string[QUERY_STR_LEN];
int r;
- sprintf(options, "--archive --checksum --compress --progress --rsh=ssh");
+ sprintf(options, "--archive --checksum --compress --progress --rsh=ssh");
if (force)
strcat(options, " --delete");
@@ -1302,23 +1303,23 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, char *local_
if (is_directory)
{
strcat(options, " --exclude=pg_xlog* --exclude=pg_control --exclude=*.pid");
- sprintf(script, "rsync %s %s:%s/* %s",
- options, host_string, remote_path, local_path);
+ sprintf(script, "rsync %s %s:%s/* %s",
+ options, host_string, remote_path, local_path);
}
else
{
- sprintf(script, "rsync %s %s:%s %s/.",
- options, host_string, remote_path, local_path);
+ sprintf(script, "rsync %s %s:%s %s/.",
+ options, host_string, remote_path, local_path);
}
if (verbose)
printf("rsync command line: '%s'\n",script);
r = system(script);
-
- if (r != 0)
- fprintf(stderr, _("Can't rsync from remote file or directory (%s:%s)\n"),
- host_string, remote_path);
+
+ if (r != 0)
+ fprintf(stderr, _("Can't rsync from remote file or directory (%s:%s)\n"),
+ host_string, remote_path);
return r;
}
@@ -1334,96 +1335,101 @@ check_parameters_for_action(const int action)
switch (action)
{
- case MASTER_REGISTER:
- /*
- * To register a master we only need the repmgr.conf
- * all other parameters are at least useless and could be
- * confusing so reject them
- */
- if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
- (dbname != NULL))
- {
- fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a MASTER REGISTER command.");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- if (dest_dir != NULL) {
- fprintf(stderr, "\nYou don't need a destination directory for MASTER REGISTER command");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- break;
- case STANDBY_REGISTER:
- /*
- * To register a standby we only need the repmgr.conf
- * we don't need connection parameters to the master
- * because we can detect the master in repl_nodes
- */
- if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
- (dbname != NULL))
- {
- fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY REGISTER command.");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- if (dest_dir != NULL) {
- fprintf(stderr, "\nYou don't need a destination directory for STANDBY REGISTER command");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- break;
- case STANDBY_PROMOTE:
- /*
- * To promote a standby we only need the repmgr.conf
- * we don't want connection parameters to the master
- * because we will try to detect the master in repl_nodes
- * if we can't find it then the promote action will be cancelled
- */
- if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
- (dbname != NULL))
- {
- fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY PROMOTE command.");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- if (dest_dir != NULL) {
- fprintf(stderr, "\nYou don't need a destination directory for STANDBY PROMOTE command");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- break;
- case STANDBY_FOLLOW:
- /*
- * To make a standby follow a master we only need the repmgr.conf
- * we don't want connection parameters to the new master
- * because we will try to detect the master in repl_nodes
- * if we can't find it then the follow action will be cancelled
- */
- if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
- (dbname != NULL))
- {
- fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY FOLLOW command.");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- if (dest_dir != NULL) {
- fprintf(stderr, "\nYou don't need a destination directory for STANDBY FOLLOW command");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- break;
- case STANDBY_CLONE:
- /*
- * To clone a master into a standby we need connection parameters
- * repmgr.conf is useless because we don't have a server running
- * in the standby
- */
- if (config_file != NULL) {
- fprintf(stderr, "\nYou need to use connection parameters to the master when issuing a STANDBY CLONE command.");
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- ok = false;
- }
- break;
+ case MASTER_REGISTER:
+ /*
+ * To register a master we only need the repmgr.conf
+ * all other parameters are at least useless and could be
+ * confusing so reject them
+ */
+ if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
+ (dbname != NULL))
+ {
+ fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a MASTER REGISTER command.");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ if (dest_dir != NULL)
+ {
+ fprintf(stderr, "\nYou don't need a destination directory for MASTER REGISTER command");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ break;
+ case STANDBY_REGISTER:
+ /*
+ * To register a standby we only need the repmgr.conf
+ * we don't need connection parameters to the master
+ * because we can detect the master in repl_nodes
+ */
+ if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
+ (dbname != NULL))
+ {
+ fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY REGISTER command.");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ if (dest_dir != NULL)
+ {
+ fprintf(stderr, "\nYou don't need a destination directory for STANDBY REGISTER command");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ break;
+ case STANDBY_PROMOTE:
+ /*
+ * To promote a standby we only need the repmgr.conf
+ * we don't want connection parameters to the master
+ * because we will try to detect the master in repl_nodes
+ * if we can't find it then the promote action will be cancelled
+ */
+ if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
+ (dbname != NULL))
+ {
+ fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY PROMOTE command.");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ if (dest_dir != NULL)
+ {
+ fprintf(stderr, "\nYou don't need a destination directory for STANDBY PROMOTE command");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ break;
+ case STANDBY_FOLLOW:
+ /*
+ * To make a standby follow a master we only need the repmgr.conf
+ * we don't want connection parameters to the new master
+ * because we will try to detect the master in repl_nodes
+ * if we can't find it then the follow action will be cancelled
+ */
+ if ((host != NULL) || (masterport != NULL) || (username != NULL) ||
+ (dbname != NULL))
+ {
+ fprintf(stderr, "\nYou can't use connection parameters to the master when issuing a STANDBY FOLLOW command.");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ if (dest_dir != NULL)
+ {
+ fprintf(stderr, "\nYou don't need a destination directory for STANDBY FOLLOW command");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ break;
+ case STANDBY_CLONE:
+ /*
+ * To clone a master into a standby we need connection parameters
+ * repmgr.conf is useless because we don't have a server running
+ * in the standby
+ */
+ if (config_file != NULL)
+ {
+ fprintf(stderr, "\nYou need to use connection parameters to the master when issuing a STANDBY CLONE command.");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ ok = false;
+ }
+ break;
}
return ok;
diff --git a/repmgr.h b/repmgr.h
index e099f62c..ec32b995 100644
--- a/repmgr.h
+++ b/repmgr.h
@@ -1,7 +1,7 @@
/*
* repmgr.h
* Copyright (c) 2ndQuadrant, 2010
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
diff --git a/repmgrd.c b/repmgrd.c
index ee646a87..b7e0d1b5 100644
--- a/repmgrd.c
+++ b/repmgrd.c
@@ -3,8 +3,8 @@
* Copyright (C) 2ndQuadrant, 2010
*
* This module connects to the nodes of a replication cluster and monitors
- * how far are they from master
- *
+ * how far are they from master
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -78,13 +78,14 @@ static void setup_cancel_handler(void);
{ \
MonitorExecute(); \
sleep(3); \
- }
+ }
int
main(int argc, char **argv)
{
- static struct option long_options[] = {
+ static struct option long_options[] =
+ {
{"config", required_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
@@ -93,7 +94,7 @@ main(int argc, char **argv)
int optindex;
int c;
- char conninfo[MAXLEN];
+ char conninfo[MAXLEN];
char standby_version[MAXVERSIONSTR];
progname = get_progname(argv[0]);
@@ -117,20 +118,20 @@ main(int argc, char **argv)
{
switch (c)
{
- case 'f':
- config_file = optarg;
- break;
- case 'v':
- verbose = true;
- break;
- default:
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
- exit(1);
+ case 'f':
+ config_file = optarg;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
}
}
setup_cancel_handler();
-
+
if (config_file == NULL)
{
config_file = malloc(5 + sizeof(CONFIG_FILE));
@@ -139,30 +140,30 @@ main(int argc, char **argv)
/*
* Read the configuration file: repmgr.conf
- */
+ */
parse_config(config_file, myClusterName, &myLocalId, conninfo);
- if (myLocalId == -1)
+ if (myLocalId == -1)
{
fprintf(stderr, "Node information is missing. "
- "Check the configuration file.\n");
+ "Check the configuration file.\n");
exit(1);
}
- myLocalConn = establishDBConnection(conninfo, true);
+ myLocalConn = establishDBConnection(conninfo, true);
/* should be v9 or better */
pg_version(myLocalConn, standby_version);
if (strcmp(standby_version, "") == 0)
{
PQfinish(myLocalConn);
- fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
+ fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
exit(1);
}
- /*
- * Set my server mode, establish a connection to primary
+ /*
+ * Set my server mode, establish a connection to primary
* and start monitor
- */
+ */
myLocalMode = is_standby(myLocalConn) ? STANDBY_MODE : PRIMARY_MODE;
if (myLocalMode == PRIMARY_MODE)
{
@@ -182,13 +183,13 @@ main(int argc, char **argv)
checkNodeConfiguration(conninfo);
if (myLocalMode == STANDBY_MODE)
{
- MonitorCheck();
+ MonitorCheck();
}
- /* close the connection to the database and cleanup */
- CloseConnections();
+ /* close the connection to the database and cleanup */
+ CloseConnections();
- return 0;
+ return 0;
}
@@ -200,7 +201,7 @@ main(int argc, char **argv)
static void
MonitorExecute(void)
{
- PGresult *res;
+ PGresult *res;
char monitor_standby_timestamp[MAXLEN];
char last_wal_primary_location[MAXLEN];
char last_wal_standby_received[MAXLEN];
@@ -212,9 +213,9 @@ MonitorExecute(void)
int connection_retries;
- /*
- * Check if the master is still available, if after 5 minutes of retries
- * we cannot reconnect, try to get a new master.
+ /*
+ * Check if the master is still available, if after 5 minutes of retries
+ * we cannot reconnect, try to get a new master.
*/
for (connection_retries = 0; connection_retries < 15; connection_retries++)
{
@@ -225,7 +226,7 @@ MonitorExecute(void)
sleep(20);
PQreset(primaryConn);
- }
+ }
else
{
fprintf(stderr, "\n%s: Connection to master has been restored, continue monitoring.\n", progname);
@@ -261,53 +262,53 @@ MonitorExecute(void)
/* Check if we still are a standby, we could have been promoted */
if (!is_standby(myLocalConn))
- {
- fprintf(stderr, "\n%s: seems like we have been promoted, so exit from monitoring...\n",
- progname);
+ {
+ fprintf(stderr, "\n%s: seems like we have been promoted, so exit from monitoring...\n",
+ progname);
CloseConnections();
exit(1);
}
- /*
+ /*
* first check if there is a command being executed,
* and if that is the case, cancel the query so i can
- * insert the current record
- */
+ * insert the current record
+ */
if (PQisBusy(primaryConn) == 1)
CancelQuery();
/* Get local xlog info */
- sprintf(sqlquery,
- "SELECT CURRENT_TIMESTAMP, pg_last_xlog_receive_location(), "
- "pg_last_xlog_replay_location()");
+ sprintf(sqlquery,
+ "SELECT CURRENT_TIMESTAMP, pg_last_xlog_receive_location(), "
+ "pg_last_xlog_replay_location()");
- res = PQexec(myLocalConn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
- PQclear(res);
+ res = PQexec(myLocalConn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
+ PQclear(res);
/* if there is any error just let it be and retry in next loop */
- return;
- }
+ return;
+ }
- strcpy(monitor_standby_timestamp, PQgetvalue(res, 0, 0));
- strcpy(last_wal_standby_received , PQgetvalue(res, 0, 1));
- strcpy(last_wal_standby_applied , PQgetvalue(res, 0, 2));
- PQclear(res);
+ strcpy(monitor_standby_timestamp, PQgetvalue(res, 0, 0));
+ strcpy(last_wal_standby_received , PQgetvalue(res, 0, 1));
+ strcpy(last_wal_standby_applied , PQgetvalue(res, 0, 2));
+ PQclear(res);
/* Get primary xlog info */
- sprintf(sqlquery, "SELECT pg_current_xlog_location() ");
+ sprintf(sqlquery, "SELECT pg_current_xlog_location() ");
- res = PQexec(primaryConn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(primaryConn));
- PQclear(res);
- return;
- }
+ res = PQexec(primaryConn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(primaryConn));
+ PQclear(res);
+ return;
+ }
- strcpy(last_wal_primary_location, PQgetvalue(res, 0, 0));
- PQclear(res);
+ strcpy(last_wal_primary_location, PQgetvalue(res, 0, 0));
+ PQclear(res);
/* Calculate the lag */
lsn_primary = walLocationToBytes(last_wal_primary_location);
@@ -318,15 +319,15 @@ MonitorExecute(void)
* Build the SQL to execute on primary
*/
sprintf(sqlquery,
- "INSERT INTO repmgr_%s.repl_monitor "
- "VALUES(%d, %d, '%s'::timestamp with time zone, "
- " '%s', '%s', "
- " %lld, %lld)", myClusterName,
- primaryId, myLocalId, monitor_standby_timestamp,
- last_wal_primary_location,
- last_wal_standby_received,
- (lsn_primary - lsn_standby_received),
- (lsn_standby_received - lsn_standby_applied));
+ "INSERT INTO repmgr_%s.repl_monitor "
+ "VALUES(%d, %d, '%s'::timestamp with time zone, "
+ " '%s', '%s', "
+ " %lld, %lld)", myClusterName,
+ primaryId, myLocalId, monitor_standby_timestamp,
+ last_wal_primary_location,
+ last_wal_standby_received,
+ (lsn_primary - lsn_standby_received),
+ (lsn_standby_received - lsn_standby_applied));
/*
* Execute the query asynchronously, but don't check for a result. We
@@ -334,27 +335,27 @@ MonitorExecute(void)
*/
if (PQsendQuery(primaryConn, sqlquery) == 0)
fprintf(stderr, "Query could not be sent to primary. %s\n",
- PQerrorMessage(primaryConn));
+ PQerrorMessage(primaryConn));
}
static void
checkClusterConfiguration(void)
{
- PGresult *res;
+ PGresult *res;
sprintf(sqlquery, "SELECT oid FROM pg_class "
- " WHERE oid = 'repmgr_%s.repl_nodes'::regclass",
- myClusterName);
- res = PQexec(myLocalConn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
- PQclear(res);
- PQfinish(myLocalConn);
- PQfinish(primaryConn);
+ " WHERE oid = 'repmgr_%s.repl_nodes'::regclass",
+ myClusterName);
+ res = PQexec(myLocalConn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
+ PQclear(res);
+ PQfinish(myLocalConn);
+ PQfinish(primaryConn);
exit(1);
- }
+ }
/*
* If there isn't any results then we have not configured a primary node yet
@@ -363,10 +364,10 @@ checkClusterConfiguration(void)
*/
if (PQntuples(res) == 0)
{
- fprintf(stderr, "The replication cluster is not configured\n");
- PQclear(res);
- PQfinish(myLocalConn);
- PQfinish(primaryConn);
+ fprintf(stderr, "The replication cluster is not configured\n");
+ PQclear(res);
+ PQfinish(myLocalConn);
+ PQfinish(primaryConn);
exit(1);
}
PQclear(res);
@@ -376,41 +377,41 @@ checkClusterConfiguration(void)
static void
checkNodeConfiguration(char *conninfo)
{
- PGresult *res;
+ PGresult *res;
/*
* Check if we have my node information in repl_nodes
*/
sprintf(sqlquery, "SELECT * FROM repmgr_%s.repl_nodes "
- " WHERE id = %d AND cluster = '%s' ",
- myClusterName, myLocalId, myClusterName);
+ " WHERE id = %d AND cluster = '%s' ",
+ myClusterName, myLocalId, myClusterName);
- res = PQexec(myLocalConn, sqlquery);
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
- PQclear(res);
- PQfinish(myLocalConn);
- PQfinish(primaryConn);
+ res = PQexec(myLocalConn, sqlquery);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "PQexec failed: %s\n", PQerrorMessage(myLocalConn));
+ PQclear(res);
+ PQfinish(myLocalConn);
+ PQfinish(primaryConn);
exit(1);
- }
+ }
/*
* If there isn't any results then we have not configured this node yet
- * in repmgr, if that is the case we will insert the node to the cluster
+ * in repmgr, if that is the case we will insert the node to the cluster
*/
if (PQntuples(res) == 0)
{
- PQclear(res);
+ PQclear(res);
/* Adding the node */
sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
- "VALUES (%d, '%s', '%s')",
- myClusterName, myLocalId, myClusterName, conninfo);
+ "VALUES (%d, '%s', '%s')",
+ myClusterName, myLocalId, myClusterName, conninfo);
- if (!PQexec(primaryConn, sqlquery))
+ if (!PQexec(primaryConn, sqlquery))
{
fprintf(stderr, "Cannot insert node details, %s\n",
- PQerrorMessage(primaryConn));
+ PQerrorMessage(primaryConn));
PQfinish(myLocalConn);
PQfinish(primaryConn);
exit(1);
@@ -420,33 +421,33 @@ checkNodeConfiguration(char *conninfo)
}
-static unsigned long long int
+static unsigned long long int
walLocationToBytes(char *wal_location)
{
- unsigned int xlogid;
- unsigned int xrecoff;
+ unsigned int xlogid;
+ unsigned int xrecoff;
- if (sscanf(wal_location, "%X/%X", &xlogid, &xrecoff) != 2)
- {
- fprintf(stderr, "wrong log location format: %s\n", wal_location);
- return 0;
- }
- return ((xlogid * 16 * 1024 * 1024 * 255) + xrecoff);
+ if (sscanf(wal_location, "%X/%X", &xlogid, &xrecoff) != 2)
+ {
+ fprintf(stderr, "wrong log location format: %s\n", wal_location);
+ return 0;
+ }
+ return ((xlogid * 16 * 1024 * 1024 * 255) + xrecoff);
}
-static void
+static void
help(const char *progname)
{
- printf(_("\n%s: Replicator manager daemon \n"), progname);
- printf(_("Usage:\n"));
- printf(_(" %s [OPTIONS]\n"), progname);
- printf(_("\nOptions:\n"));
+ printf(_("\n%s: Replicator manager daemon \n"), progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTIONS]\n"), progname);
+ printf(_("\nOptions:\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_(" --verbose output verbose activity information\n"));
printf(_(" -f, --config_file=PATH database to connect to\n"));
- printf(_("\n%s monitors a cluster of servers.\n"), progname);
+ printf(_("\n%s monitors a cluster of servers.\n"), progname);
}
@@ -455,13 +456,13 @@ help(const char *progname)
static void
handle_sigint(SIGNAL_ARGS)
{
- CloseConnections();
+ CloseConnections();
}
static void
setup_cancel_handler(void)
{
- pqsignal(SIGINT, handle_sigint);
+ pqsignal(SIGINT, handle_sigint);
}
#endif
@@ -469,13 +470,13 @@ setup_cancel_handler(void)
static void
CancelQuery(void)
{
- char errbuf[256];
- PGcancel *pgcancel;
+ char errbuf[256];
+ PGcancel *pgcancel;
- pgcancel = PQgetCancel(primaryConn);
+ pgcancel = PQgetCancel(primaryConn);
- if (!pgcancel || PQcancel(pgcancel, errbuf, 256) == 0)
- fprintf(stderr, "Can't stop current query: %s", errbuf);
+ if (!pgcancel || PQcancel(pgcancel, errbuf, 256) == 0)
+ fprintf(stderr, "Can't stop current query: %s", errbuf);
- PQfreeCancel(pgcancel);
+ PQfreeCancel(pgcancel);
}