mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-23 07:06:30 +00:00
Merge remote-tracking branch 'origin/master' into heroku
The Great Whitespace Reconciliation Conflicts: check_dir.c config.c dbutils.c repmgr.c repmgr.h repmgrd.c Signed-off-by: Dan Farina <drfarina@acm.org>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -0,0 +1,4 @@
|
||||
*~
|
||||
*.o
|
||||
repmgr
|
||||
repmgrd
|
||||
|
||||
7
CREDITS
Normal file
7
CREDITS
Normal file
@@ -0,0 +1,7 @@
|
||||
Code and documentation contributors to repmgr include:
|
||||
|
||||
Jaime Casanova <jaime@2ndQuadrant.com>
|
||||
Simon Riggs <simon@2ndQuadrant.com>
|
||||
Greg Smith <greg@2ndQuadrant.com>
|
||||
Robert J. Noles <rj@2ndQuadrant.com>
|
||||
Gabriele Bartolini <gabriele@2ndQuadrant.com>
|
||||
3
HISTORY
Normal file
3
HISTORY
Normal file
@@ -0,0 +1,3 @@
|
||||
1.0.0 2010-12-05 First public release
|
||||
|
||||
1.0.1 2010-12-XX Fix missing "--force" option in help
|
||||
15
README.rst
15
README.rst
@@ -212,6 +212,8 @@ If you give a password to the user, you need to create a ``.pgpass`` file for
|
||||
them as well to allow automatic login. In this case you might use the
|
||||
``md5`` authentication method instead of ``trust`` for the repmgr user.
|
||||
|
||||
Don't forget to restart the database server after making all these changes.
|
||||
|
||||
Configuration File
|
||||
==================
|
||||
|
||||
@@ -627,3 +629,16 @@ and on “prime."
|
||||
|
||||
The servers are now again acting as primary on “prime" and standby on “standby".
|
||||
|
||||
License and Contributions
|
||||
=========================
|
||||
|
||||
repmgr is licensed under the GPL v3. All of its code and documentation is
|
||||
Copyright 2010, 2ndQuadrant Limited. See the files COPYRIGHT and LICENSE for
|
||||
details.
|
||||
|
||||
Contributions to repmgr are welcome, and listed in the file CREDITS.
|
||||
2ndQuadrant Limited requires that any contributions provide a copyright
|
||||
assignment and a disclaimer of any work-for-hire ownership claims from the
|
||||
employer of the developer. This lets us make sure that all of the repmgr
|
||||
distribution remains free code. Please contact info@2ndQuadrant.com for a
|
||||
copy of the relevant Copyright Assignment Form.
|
||||
|
||||
41
check_dir.c
41
check_dir.c
@@ -1,10 +1,21 @@
|
||||
/*
|
||||
* check_dir.c
|
||||
* check_dir.c - Directories management functions
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 2010
|
||||
* 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Directories management functions
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -36,9 +47,9 @@ 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;
|
||||
|
||||
@@ -50,7 +61,7 @@ check_dir(char *dir)
|
||||
while ((file = readdir(chkdir)) != NULL)
|
||||
{
|
||||
if (strcmp(".", file->d_name) == 0 ||
|
||||
strcmp("..", file->d_name) == 0)
|
||||
strcmp("..", file->d_name) == 0)
|
||||
{
|
||||
/* skip this and parent directory */
|
||||
continue;
|
||||
@@ -74,7 +85,7 @@ check_dir(char *dir)
|
||||
closedir(chkdir);
|
||||
|
||||
if (errno != 0)
|
||||
return -1; /* some kind of I/O error? */
|
||||
return -1; /* some kind of I/O error? */
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -90,7 +101,7 @@ create_directory(char *dir)
|
||||
return true;
|
||||
|
||||
fprintf(stderr, _("Could not create directory \"%s\": %s\n"),
|
||||
dir, strerror(errno));
|
||||
dir, strerror(errno));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -119,10 +130,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;
|
||||
@@ -141,8 +152,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;
|
||||
|
||||
13
check_dir.h
13
check_dir.h
@@ -2,6 +2,19 @@
|
||||
* 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
int check_dir(char *dir);
|
||||
|
||||
18
config.c
18
config.c
@@ -1,10 +1,20 @@
|
||||
/*
|
||||
* config.c
|
||||
* config.c - Functions to parse the config file
|
||||
* Copyright (C) 2ndQuadrant, 2010
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Functions to parse the config file
|
||||
*/
|
||||
|
||||
#include "repmgr.h"
|
||||
|
||||
13
config.h
13
config.h
@@ -2,6 +2,19 @@
|
||||
* 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
void parse_config(const char *config_file, char *cluster_name, int *node,
|
||||
|
||||
23
dbutils.c
23
dbutils.c
@@ -1,10 +1,19 @@
|
||||
/*
|
||||
* dbutils.c
|
||||
* dbutils.c - Database connection/management functions
|
||||
* Copyright (C) 2ndQuadrant, 2010
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 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
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Database connection/management functions
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -113,8 +122,8 @@ guc_setted(PGconn *conn, const char *parameter, const char *op,
|
||||
char sqlquery[QUERY_STR_LEN];
|
||||
|
||||
sqlquery_snprintf(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)
|
||||
@@ -190,7 +199,7 @@ getMasterConnection(PGconn *standby_conn, int id, char *cluster,
|
||||
/* find all nodes belonging to this cluster */
|
||||
sqlquery_snprintf(sqlquery, "SELECT * FROM repmgr_%s.repl_nodes "
|
||||
" WHERE cluster = '%s' and id <> %d",
|
||||
cluster, cluster, id);
|
||||
cluster, cluster, id);
|
||||
|
||||
res1 = PQexec(standby_conn, sqlquery);
|
||||
if (PQresultStatus(res1) != PGRES_TUPLES_OK)
|
||||
|
||||
13
dbutils.h
13
dbutils.h
@@ -2,6 +2,19 @@
|
||||
* 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error);
|
||||
|
||||
325
repmgr.c
325
repmgr.c
@@ -1,16 +1,27 @@
|
||||
/*
|
||||
* repmgr.c
|
||||
* repmgr.c - Command interpreter for the repmgr
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 2010
|
||||
*
|
||||
* Command interpreter for the repmgr
|
||||
* 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,
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "repmgr.h"
|
||||
@@ -71,7 +82,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'},
|
||||
@@ -111,40 +123,40 @@ main(int argc, char **argv)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
dbname = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
case 'd':
|
||||
dbname = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
masterport = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
username = optarg;
|
||||
case 'U':
|
||||
username = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
dest_dir = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
dest_dir = optarg;
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
case 'R':
|
||||
remote_user = 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:
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,14 +226,14 @@ main(int argc, char **argv)
|
||||
|
||||
switch (optind < argc)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
|
||||
progname, argv[optind + 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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!check_parameters_for_action(action))
|
||||
@@ -262,25 +274,25 @@ main(int argc, char **argv)
|
||||
|
||||
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:
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -641,29 +653,29 @@ do_standby_clone(void)
|
||||
{
|
||||
case 0:
|
||||
/* dest_dir not there, must create it */
|
||||
if (verbose)
|
||||
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;
|
||||
}
|
||||
progname, dest_dir);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Present but empty, fix permissions and use it */
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf(_("fixing permissions on existing directory %s ... "),
|
||||
dest_dir);
|
||||
fflush(stdout);
|
||||
|
||||
if (!set_directory_permissions(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;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -674,20 +686,20 @@ do_standby_clone(void)
|
||||
|
||||
pg_dir = is_pg_dir(dest_dir);
|
||||
if (pg_dir && !force)
|
||||
{
|
||||
fprintf(stderr, _("\nThis looks like a PostgreSQL directroy.\n"
|
||||
{
|
||||
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;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (pg_dir && force)
|
||||
{
|
||||
/* Let it continue */
|
||||
break;
|
||||
}
|
||||
else
|
||||
return;
|
||||
return;
|
||||
default:
|
||||
/* Trouble accessing directory */
|
||||
fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
|
||||
@@ -775,23 +787,23 @@ do_standby_clone(void)
|
||||
{
|
||||
case 0:
|
||||
/* tblspc_dir not there, must create it */
|
||||
if (verbose)
|
||||
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;
|
||||
}
|
||||
progname, tblspc_dir);
|
||||
PQclear(res);
|
||||
PQfinish(conn);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Present but empty, fix permissions and use it */
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf(_("fixing permissions on existing directory \"%s\"... "),
|
||||
tblspc_dir);
|
||||
fflush(stdout);
|
||||
@@ -800,9 +812,9 @@ do_standby_clone(void)
|
||||
{
|
||||
fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
|
||||
progname, tblspc_dir, strerror(errno));
|
||||
PQclear(res);
|
||||
PQfinish(conn);
|
||||
return;
|
||||
PQclear(res);
|
||||
PQfinish(conn);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -1426,12 +1438,12 @@ copy_remote_files(char *host, char *remote_user, char *remote_path,
|
||||
strcat(options,
|
||||
" --exclude=pg_xlog* --exclude=pg_control --exclude=*.pid");
|
||||
maxlen_snprintf(script, "rsync %s %s:%s/* %s",
|
||||
options, host_string, remote_path, local_path);
|
||||
options, host_string, remote_path, local_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxlen_snprintf(script, "rsync %s %s:%s %s/.",
|
||||
options, host_string, remote_path, local_path);
|
||||
options, host_string, remote_path, local_path);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
@@ -1458,105 +1470,110 @@ 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
|
||||
*/
|
||||
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, "\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;
|
||||
ok = false;
|
||||
}
|
||||
if (dest_dir != NULL) {
|
||||
fprintf(stderr, "\nYou don't need a destination directory for MASTER REGISTER command");
|
||||
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
|
||||
*/
|
||||
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, "\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;
|
||||
ok = false;
|
||||
}
|
||||
if (dest_dir != NULL) {
|
||||
fprintf(stderr, "\nYou don't need a destination directory for STANDBY REGISTER command");
|
||||
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
|
||||
*/
|
||||
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, "\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;
|
||||
ok = false;
|
||||
}
|
||||
if (dest_dir != NULL) {
|
||||
fprintf(stderr, "\nYou don't need a destination directory for STANDBY PROMOTE command");
|
||||
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
|
||||
*/
|
||||
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, "\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;
|
||||
ok = false;
|
||||
}
|
||||
if (dest_dir != NULL) {
|
||||
fprintf(stderr, "\nYou don't need a destination directory for STANDBY FOLLOW command");
|
||||
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
|
||||
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.");
|
||||
* 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;
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
14
repmgr.h
14
repmgr.h
@@ -2,7 +2,19 @@
|
||||
* repmgr.h
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
52
repmgrd.c
52
repmgrd.c
@@ -1,12 +1,24 @@
|
||||
/*
|
||||
* repmgrd.c
|
||||
* repmgrd.c - Replication manager daemon
|
||||
*
|
||||
* Copyright (c) 2ndQuadrant, 2010
|
||||
* Copyright (c) Heroku, 2010
|
||||
* Copyright (C) 2ndQuadrant, 2010
|
||||
*
|
||||
* Replication manager daemon
|
||||
* This module connects to the nodes of a replication cluster and monitors
|
||||
* 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
|
||||
* (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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
@@ -74,7 +86,8 @@ static void setup_cancel_handler(void);
|
||||
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}
|
||||
@@ -107,16 +120,16 @@ main(int argc, char **argv)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
|
||||
progname);
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +248,6 @@ MonitorExecute(void)
|
||||
{
|
||||
fprintf(stderr, "\n%s: We couldn't reconnect to master, checking if ",
|
||||
progname);
|
||||
fprintf(stderr, "%s: another node has been promoted.\n", progname);
|
||||
for (connection_retries = 0; connection_retries < 6;
|
||||
connection_retries++)
|
||||
{
|
||||
@@ -265,7 +277,7 @@ MonitorExecute(void)
|
||||
if (!is_standby(myLocalConn))
|
||||
{
|
||||
fprintf(stderr, "\n%s: seems like we have been promoted, so exit from monitoring...\n",
|
||||
progname);
|
||||
progname);
|
||||
CloseConnections();
|
||||
exit(1);
|
||||
}
|
||||
@@ -324,7 +336,7 @@ MonitorExecute(void)
|
||||
"INSERT INTO repmgr_%s.repl_monitor "
|
||||
"VALUES(%d, %d, '%s'::timestamp with time zone, "
|
||||
" '%s', '%s', "
|
||||
" %lld, %lld)", myClusterName,
|
||||
" %lld, %lld)", myClusterName,
|
||||
primaryId, myLocalId, monitor_standby_timestamp,
|
||||
last_wal_primary_location,
|
||||
last_wal_standby_received,
|
||||
@@ -347,8 +359,8 @@ checkClusterConfiguration(void)
|
||||
PGresult *res;
|
||||
|
||||
sqlquery_snprintf(sqlquery, "SELECT oid FROM pg_class "
|
||||
" WHERE oid = 'repmgr_%s.repl_nodes'::regclass",
|
||||
myClusterName);
|
||||
" WHERE oid = 'repmgr_%s.repl_nodes'::regclass",
|
||||
myClusterName);
|
||||
res = PQexec(myLocalConn, sqlquery);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
@@ -386,7 +398,7 @@ checkNodeConfiguration(char *conninfo)
|
||||
/* Check if we have my node information in repl_nodes */
|
||||
sqlquery_snprintf(sqlquery, "SELECT * FROM repmgr_%s.repl_nodes "
|
||||
" WHERE id = %d AND cluster = '%s' ",
|
||||
myClusterName, myLocalId, myClusterName);
|
||||
myClusterName, myLocalId, myClusterName);
|
||||
|
||||
res = PQexec(myLocalConn, sqlquery);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
@@ -408,7 +420,7 @@ checkNodeConfiguration(char *conninfo)
|
||||
|
||||
/* Adding the node */
|
||||
sqlquery_snprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
|
||||
"VALUES (%d, '%s', '%s')",
|
||||
"VALUES (%d, '%s', '%s')",
|
||||
myClusterName, myLocalId, myClusterName, conninfo);
|
||||
|
||||
if (!PQexec(primaryConn, sqlquery))
|
||||
|
||||
Reference in New Issue
Block a user