Compare commits

...

29 Commits
v3.3 ... v3.3.1

Author SHA1 Message Date
Ian Barwick
9c28d3626b Update HISTORY 2017-03-20 14:20:52 +09:00
Ian Barwick
0916d8f2ad repmgr: disallow node ids which are not positive signed 32 bit integers
Fixes GitHub #280
2017-03-20 11:26:34 +09:00
Ian Barwick
1964f890be repmgr: enable master register --force with node foreign key dependency
Fixes GitHub #273
2017-03-20 10:03:38 +09:00
Ian Barwick
976a61005e Only attempt to set synchronous transaction mode with valid connection 2017-03-17 20:33:29 +09:00
Ian Barwick
0c82278fd4 repmgr: fix command line parsing with hostname as an additional argument
Check explicitly whether -h/--hostname provided, otherwise PGHOST,
if set, will be misinterpreted.
2017-03-17 20:21:13 +09:00
Ian Barwick
0abfde3773 repmgr: ensure that data dir permissions set correctly when cloning in barman mode 2017-03-17 16:37:49 +09:00
Ian Barwick
1746831486 repmgr: fix standby clone with barman
As of Barman commit 5ff62d3255, `pg_notify`
is also excluded from Barman backups.
2017-03-17 16:32:35 +09:00
Ian Barwick
8c8e368a69 repmgr: set "synchronous_commit" to "local" by default
Rather than set this for individual connections, we'll change the setting
each time a connection is made (except replication connections), which will
obviate the need to take this into consideration when making connections
in the application code.

Resolves GitHub #276.
2017-03-17 11:32:25 +09:00
Ian Barwick
0ef532dcff repmgr: improve standby clone when synchronous replication in use
Fixes GitHub #277
2017-03-16 16:46:08 +09:00
Ian Barwick
478407fd86 repmgr: fix standby clone with barman
As of Barman commit 5ff62d3255, `pg_notify`
is also excluded from Barman backups.
2017-03-16 10:29:50 +09:00
Ian Barwick
05bfdfab2c repmgr: fix command line parsing with hostname as an additional argument
Check explicitly whether -h/--hostname provided, otherwise PGHOST,
if set, will be misinterpreted.
2017-03-14 22:55:27 +09:00
Ian Barwick
29740dc41b Bump version
3.3.1
2017-03-13 16:00:44 +09:00
Ian Barwick
ad6ecef2ab repmgr: clean up standby follow code 2017-03-13 13:27:02 +09:00
Ian Barwick
5318d37462 README: fix typos 2017-03-13 13:20:56 +09:00
Ian Barwick
7244dda20f repmgr: fix typo 2017-03-13 13:20:35 +09:00
Ian Barwick
e651284927 Update documentation/sample configuration with references to --wal-method 2017-03-13 13:20:20 +09:00
Ian Barwick
72a2ac284a repmgr: improve logging of rsync actions
In particular, copy_remote_files() would report any kind of non-zero
exit status from rsync as an error, even though when cloning data
directories and tablespaces we explicitly ignore the "vanished
files" status (code 24) as it's expected behaviour for files in these
locations to disappear during the rsync copy process.

Conflicts:
	HISTORY
2017-03-13 13:16:44 +09:00
Ian Barwick
cec01c6620 repmgr: improve standby follow log output
In particular suppress any error messages encountered when trying to
connect to the old upstream node, as these are not critical and
will lead to confusion.
2017-03-13 13:14:19 +09:00
Ian Barwick
989f683bc6 repmgr: have "standby follow" delete old replication slot, if possible
Addresses GitHub #272
2017-03-13 13:14:05 +09:00
Ian Barwick
fa30382f2c When retrieving a node record, set upstream_node_id correctly.
-1 (NO_UPSTREAM_NODE) should be returned if the record's column is NULL.
2017-03-13 12:16:22 +09:00
Martin
defc2653e0 There where 2 barman configuration parameters missing in the repmgr.conf
sample file.

Added with some comments
2017-02-15 17:17:39 -03:00
Ian Barwick
67e8ca73b5 repmgrd: fix XLogRecPtr conversion function 2017-01-11 15:03:13 +09:00
Ian Barwick
a1a1d64e1f repmgrd: fix usage description
Matches the one provided by repmgr.
2017-01-11 15:03:07 +09:00
Ian Barwick
76509038cc repmgrd: prevent invalid apply lag value being written to the monitoring table 2017-01-11 15:03:02 +09:00
Ian Barwick
7f8e50c882 Update copyright notice to 2017
Also standardize case to "(c)"
2017-01-11 15:02:55 +09:00
Ian Barwick
5deb6c8ce4 rempgr: don't link to backend functions
The intent was to avoid maintaining duplicate code, but this approach
makes it difficult to build Debian packages (see GitHub #261).

As the functions in question are quite compact and unlikely to change,
we'll just use the adapted versions provided for 9.5 and earlier.
2017-01-04 16:55:09 +09:00
Ian Barwick
175ee8acfc README: update version information 2017-01-04 10:59:13 +09:00
Ian Barwick
d1491f51a3 Remove erroneously added configuration item from repmgr.conf.sample
Per GitHub #262
2017-01-04 09:35:39 +09:00
Ian Barwick
bc9febdc48 repmgr: fix error message string
Per GitHub #263.
2017-01-04 09:25:50 +09:00
30 changed files with 372 additions and 185 deletions

View File

@@ -2,7 +2,7 @@ License and Contributions
========================= =========================
`repmgr` is licensed under the GPL v3. All of its code and documentation is `repmgr` is licensed under the GPL v3. All of its code and documentation is
Copyright 2010-2016, 2ndQuadrant Limited. See the files COPYRIGHT and LICENSE for Copyright 2010-2017, 2ndQuadrant Limited. See the files COPYRIGHT and LICENSE for
details. details.
The development of repmgr has primarily been sponsored by 2ndQuadrant customers. The development of repmgr has primarily been sponsored by 2ndQuadrant customers.

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2016, 2ndQuadrant Limited Copyright (c) 2010-2017, 2ndQuadrant Limited
All rights reserved. All rights reserved.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify

13
HISTORY
View File

@@ -1,3 +1,16 @@
3.3.1 2017-03-
repmgrd: prevent invalid apply lag value being written to the
monitoring table (Ian)
repmgrd: fix error in XLogRecPtr conversion when calculating
monitoring statistics (Ian)
repmgr: if replication slots in use, where possible delete slot on old
upstream node after following new upstream (Ian)
repmgr: improve logging of rsync actions (Ian)
repmgr: improve `standby clone` when synchronous replication in use (Ian)
repmgr: stricter checking of allowed node id values
repmgr: enable `master register --force` when there is a foreign key
dependency from a standby node (Ian)
3.3 2016-12-27 3.3 2016-12-27
repmgr: always log to STDERR even if log facility defined (Ian) repmgr: always log to STDERR even if log facility defined (Ian)
repmgr: add --log-to-file to log repmgr output to the defined repmgr: add --log-to-file to log repmgr output to the defined

View File

@@ -1,6 +1,6 @@
# #
# Makefile # Makefile
# Copyright (c) 2ndQuadrant, 2010-2016 # Copyright (c) 2ndQuadrant, 2010-2017
HEADERS = $(wildcard *.h) HEADERS = $(wildcard *.h)

View File

@@ -7,7 +7,7 @@ replication capabilities with utilities to set up standby servers, monitor
replication, and perform administrative tasks such as failover or switchover replication, and perform administrative tasks such as failover or switchover
operations. operations.
The current `repmgr` version, 3.2, supports all PostgreSQL versions from The current `repmgr` version (3.3) supports all PostgreSQL versions from
9.3 to 9.6. 9.3 to 9.6.
Overview Overview
@@ -333,10 +333,11 @@ The following replication settings may need to be adjusted:
archive_command = '/bin/true' archive_command = '/bin/true'
# If cloning using rsync, or you have configured `pg_basebackup_options` # If cloning using rsync, or you have configured `pg_basebackup_options`
# in `repmgr.conf` to include the setting `--xlog-method=fetch`, *and* # in `repmgr.conf` to include the setting `--xlog-method=fetch` (from
# you have not set `restore_command` in `repmgr.conf`to fetch WAL files # PostgreSQL 10 `--wal-method=fetch`), *and* you have not set
# from another source such as Barman, you'll need to set `wal_keep_segments` # `restore_command` in `repmgr.conf`to fetch WAL files from another
# to a high enough value to ensure that all WAL files generated while # source such as Barman, you'll need to set `wal_keep_segments` to a
# high enough value to ensure that all WAL files generated while
# the standby is being cloned are retained until the standby starts up. # the standby is being cloned are retained until the standby starts up.
# wal_keep_segments = 5000 # wal_keep_segments = 5000
@@ -390,7 +391,8 @@ least the following parameters:
- `cluster`: an arbitrary name for the replication cluster; this must be identical - `cluster`: an arbitrary name for the replication cluster; this must be identical
on all nodes on all nodes
- `node`: a unique integer identifying the node - `node`: a unique integer identifying the node; note this must be a positive
32 bit signed integer between 1 and 2147483647
- `node_name`: a unique string identifying the node; we recommend a name - `node_name`: a unique string identifying the node; we recommend a name
specific to the server (e.g. 'server_1'); avoid names indicating the specific to the server (e.g. 'server_1'); avoid names indicating the
current replication role like 'master' or 'standby' as the server's current replication role like 'master' or 'standby' as the server's
@@ -501,7 +503,8 @@ place. To ensure this happens when using the default `pg_basebackup` method,
`repmgr` will set `pg_basebackup`'s `--xlog-method` parameter to `stream`, `repmgr` will set `pg_basebackup`'s `--xlog-method` parameter to `stream`,
which will ensure all WAL files generated during the cloning process are which will ensure all WAL files generated during the cloning process are
streamed in parallel with the main backup. Note that this requires two streamed in parallel with the main backup. Note that this requires two
replication connections to be available. replication connections to be available (`repmgr` will verify sufficient
connections are available before attempting to clonse).
To override this behaviour, in `repmgr.conf` set `pg_basebackup`'s To override this behaviour, in `repmgr.conf` set `pg_basebackup`'s
`--xlog-method` parameter to `fetch`: `--xlog-method` parameter to `fetch`:
@@ -513,6 +516,9 @@ See the `pg_basebackup` documentation for details:
https://www.postgresql.org/docs/current/static/app-pgbasebackup.html https://www.postgresql.org/docs/current/static/app-pgbasebackup.html
> *NOTE*: From PostgreSQL 10, `pg_basebackup`'s `--xlog-method` parameter
> has been renamed to `--wal-method`.
Make any adjustments to the standby's PostgreSQL configuration files now, Make any adjustments to the standby's PostgreSQL configuration files now,
then start the server. then start the server.
@@ -1153,11 +1159,10 @@ Additionally the following `repmgrd` options must be set in `repmgr.conf`:
promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file' promote_command='repmgr standby promote -f /etc/repmgr.conf --log-to-file'
follow_command='repmgr standby follow -f /etc/repmgr.conf --log-to-file' follow_command='repmgr standby follow -f /etc/repmgr.conf --log-to-file'
Note that the `--log-to-file` option will cause `repmgr` output to be logged to Note that the `--log-to-file` option will cause `repmgr`'s output to be logged to
the destination configured to receive log output `repmgrd`. the destination configured to receive log output for `repmgrd`.
See `repmgr.conf.sample` for further `repmgrd`-specific settings See `repmgr.conf.sample` for further `repmgrd`-specific settings
When `failover` is set to `automatic`, upon detecting failure of the current When `failover` is set to `automatic`, upon detecting failure of the current
master, `repmgrd` will execute one of `promote_command` or `follow_command`, master, `repmgrd` will execute one of `promote_command` or `follow_command`,
depending on whether the current server is becoming the new master or depending on whether the current server is becoming the new master or
@@ -1461,7 +1466,7 @@ In general `repmgr` can be upgraded as-is without any further action required,
however feature releases may require the `repmgr` database to be upgraded. however feature releases may require the `repmgr` database to be upgraded.
An SQL script will be provided - please check the release notes for details: An SQL script will be provided - please check the release notes for details:
* http://repmgr.org/release-notes-3.2.1.html#UPGRADING * http://repmgr.org/release-notes-3.3.html#UPGRADING
Distribution-specific configuration Distribution-specific configuration

View File

@@ -1,6 +1,6 @@
/* /*
* check_dir.c - Directories management functions * check_dir.c - Directories management functions
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* /*
* check_dir.h * check_dir.h
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,10 +1,12 @@
/* /*
* *
* compat.c * compat.c
* Provide backports of various functions not publicly * Provides a couple of useful string utility functions adapted
* exposed before PostgreSQL 9.6 * from the backend code, which are not publicly exposed. They're
* unlikely to change but it would be worth keeping an eye on them
* for any fixes/improvements
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
@@ -24,8 +26,6 @@
* *
*/ */
#if (PG_VERSION_NUM < 90600)
#include "repmgr.h" #include "repmgr.h"
#include "compat.h" #include "compat.h"
@@ -34,8 +34,8 @@
* the string as a value, in a keyword/pair value in a libpq connection * the string as a value, in a keyword/pair value in a libpq connection
* string * string
* *
* This function is copied from src/bin/pg_dump/dumputils.c * This function is adapted from src/fe_utils/string_utils.c (before 9.6
* as it is only publicly exposed from 9.6 * located in: src/bin/pg_dump/dumputils.c)
*/ */
void void
appendConnStrVal(PQExpBuffer buf, const char *str) appendConnStrVal(PQExpBuffer buf, const char *str)
@@ -79,8 +79,6 @@ appendConnStrVal(PQExpBuffer buf, const char *str)
/* /*
* Adapted from: src/fe_utils/string_utils.c * Adapted from: src/fe_utils/string_utils.c
*
* Function not publicly available before PostgreSQL 9.6.
*/ */
void void
appendShellString(PQExpBuffer buf, const char *str) appendShellString(PQExpBuffer buf, const char *str)
@@ -107,5 +105,3 @@ appendShellString(PQExpBuffer buf, const char *str)
appendPQExpBufferChar(buf, '\''); appendPQExpBufferChar(buf, '\'');
} }
#endif

View File

@@ -1,6 +1,6 @@
/* /*
* compat.h * compat.h
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
* config.c - Functions to parse the config file * config.c - Functions to parse the config file
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -448,6 +448,10 @@ _parse_config(t_configuration_options *options, ItemList *error_list)
{ {
item_list_append(error_list, _("\"node\": must be greater than zero")); item_list_append(error_list, _("\"node\": must be greater than zero"));
} }
else if (options->node < 0)
{
item_list_append(error_list, _("\"node\": must be a positive signed 32 bit integer, i.e. 2147483647 or less"));
}
if (strlen(options->conninfo)) if (strlen(options->conninfo))
{ {

View File

@@ -1,7 +1,7 @@
/* /*
* config.h * config.h
* *
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

106
dbutils.c
View File

@@ -1,7 +1,7 @@
/* /*
* dbutils.c - Database connection/management functions * dbutils.c - Database connection/management functions
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -33,6 +33,15 @@ char repmgr_schema[MAXLEN] = "";
char repmgr_schema_quoted[MAXLEN] = ""; char repmgr_schema_quoted[MAXLEN] = "";
static int _get_node_record(PGconn *conn, char *cluster, char *sqlquery, t_node_info *node_info); static int _get_node_record(PGconn *conn, char *cluster, char *sqlquery, t_node_info *node_info);
static bool _set_config(PGconn *conn, const char *config_param, const char *sqlquery);
/*
* _establish_db_connection()
*
* Connect to a database using a conninfo string.
*
* NOTE: *do not* use this for replication connections; use establish_db_connection_by_params() instead.
*/
PGconn * PGconn *
_establish_db_connection(const char *conninfo, const bool exit_on_error, const bool log_notice, const bool verbose_only) _establish_db_connection(const char *conninfo, const bool exit_on_error, const bool log_notice, const bool verbose_only)
@@ -77,6 +86,19 @@ _establish_db_connection(const char *conninfo, const bool exit_on_error, const b
} }
} }
/*
* set "synchronous_commit" to "local" in case synchronous replication is in use
*/
else if (set_config(conn, "synchronous_commit", "local") == false)
{
if (exit_on_error)
{
PQfinish(conn);
exit(ERR_DB_CON);
}
}
return conn; return conn;
} }
@@ -116,8 +138,12 @@ PGconn *
establish_db_connection_by_params(const char *keywords[], const char *values[], establish_db_connection_by_params(const char *keywords[], const char *values[],
const bool exit_on_error) const bool exit_on_error)
{ {
/* Make a connection to the database */ PGconn *conn;
PGconn *conn = PQconnectdbParams(keywords, values, true); bool replication_connection = false;
int i;
/* Connect to the database using the provided parameters */
conn = PQconnectdbParams(keywords, values, true);
/* Check to see that the backend connection was successfully made */ /* Check to see that the backend connection was successfully made */
if ((PQstatus(conn) != CONNECTION_OK)) if ((PQstatus(conn) != CONNECTION_OK))
@@ -130,6 +156,28 @@ establish_db_connection_by_params(const char *keywords[], const char *values[],
exit(ERR_DB_CON); exit(ERR_DB_CON);
} }
} }
else
{
/*
* set "synchronous_commit" to "local" in case synchronous replication is in
* use (provided this is not a replication connection)
*/
for (i = 0; keywords[i]; i++)
{
if (strcmp(keywords[i], "replication") == 0)
replication_connection = true;
}
if (replication_connection == false && set_config(conn, "synchronous_commit", "local") == false)
{
if (exit_on_error)
{
PQfinish(conn);
exit(ERR_DB_CON);
}
}
}
return conn; return conn;
} }
@@ -1150,19 +1198,12 @@ stop_backup(PGconn *conn, char *last_wal_segment)
} }
bool bool
set_config_bool(PGconn *conn, const char *config_param, bool state) _set_config(PGconn *conn, const char *config_param, const char *sqlquery)
{ {
char sqlquery[QUERY_STR_LEN];
PGresult *res; PGresult *res;
sqlquery_snprintf(sqlquery,
"SET %s TO %s",
config_param,
state ? "TRUE" : "FALSE");
log_verbose(LOG_DEBUG, "set_config_bool():\n%s\n", sqlquery);
res = PQexec(conn, sqlquery); res = PQexec(conn, sqlquery);
if (PQresultStatus(res) != PGRES_COMMAND_OK) if (PQresultStatus(res) != PGRES_COMMAND_OK)
@@ -1177,6 +1218,36 @@ set_config_bool(PGconn *conn, const char *config_param, bool state)
return true; return true;
} }
bool
set_config(PGconn *conn, const char *config_param, const char *config_value)
{
char sqlquery[QUERY_STR_LEN];
sqlquery_snprintf(sqlquery,
"SET %s TO '%s'",
config_param,
config_value);
log_verbose(LOG_DEBUG, "set_config():\n%s\n", sqlquery);
return _set_config(conn, config_param, sqlquery);
}
bool
set_config_bool(PGconn *conn, const char *config_param, bool state)
{
char sqlquery[QUERY_STR_LEN];
sqlquery_snprintf(sqlquery,
"SET %s TO %s",
config_param,
state ? "TRUE" : "FALSE");
log_verbose(LOG_DEBUG, "set_config_bool():\n%s\n", sqlquery);
return _set_config(conn, config_param, sqlquery);
}
/* /*
* witness_copy_node_records() * witness_copy_node_records()
@@ -1872,7 +1943,16 @@ _get_node_record(PGconn *conn, char *cluster, char *sqlquery, t_node_info *node_
node_info->node_id = atoi(PQgetvalue(res, 0, 0)); node_info->node_id = atoi(PQgetvalue(res, 0, 0));
node_info->type = parse_node_type(PQgetvalue(res, 0, 1)); node_info->type = parse_node_type(PQgetvalue(res, 0, 1));
node_info->upstream_node_id = atoi(PQgetvalue(res, 0, 2));
if (PQgetisnull(res, 0, 2))
{
node_info->upstream_node_id = NO_UPSTREAM_NODE;
}
else
{
node_info->upstream_node_id = atoi(PQgetvalue(res, 0, 2));
}
strncpy(node_info->name, PQgetvalue(res, 0, 3), MAXLEN); strncpy(node_info->name, PQgetvalue(res, 0, 3), MAXLEN);
strncpy(node_info->conninfo_str, PQgetvalue(res, 0, 4), MAXLEN); strncpy(node_info->conninfo_str, PQgetvalue(res, 0, 4), MAXLEN);
strncpy(node_info->slot_name, PQgetvalue(res, 0, 5), MAXLEN); strncpy(node_info->slot_name, PQgetvalue(res, 0, 5), MAXLEN);

View File

@@ -1,7 +1,7 @@
/* /*
* dbutils.h * dbutils.h
* *
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -124,6 +124,7 @@ int get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record)
bool drop_replication_slot(PGconn *conn, char *slot_name); bool drop_replication_slot(PGconn *conn, char *slot_name);
bool start_backup(PGconn *conn, char *first_wal_segment, bool fast_checkpoint); bool start_backup(PGconn *conn, char *first_wal_segment, bool fast_checkpoint);
bool stop_backup(PGconn *conn, char *last_wal_segment); bool stop_backup(PGconn *conn, char *last_wal_segment);
bool set_config(PGconn *conn, const char *config_param, const char *config_value);
bool set_config_bool(PGconn *conn, const char *config_param, bool state); bool set_config_bool(PGconn *conn, const char *config_param, bool state);
bool witness_copy_node_records(PGconn *masterconn, PGconn *witnessconn, char *cluster_name); bool witness_copy_node_records(PGconn *masterconn, PGconn *witnessconn, char *cluster_name);
bool create_node_record(PGconn *conn, char *action, int node, char *type, int upstream_node, char *cluster_name, char *node_name, char *conninfo, int priority, char *slot_name, bool active); bool create_node_record(PGconn *conn, char *action, int node, char *type, int upstream_node, char *cluster_name, char *node_name, char *conninfo, int priority, char *slot_name, bool active);

View File

@@ -3,7 +3,7 @@
* dirmod.c * dirmod.c
* directory handling functions * directory handling functions
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California

View File

@@ -1,6 +1,6 @@
/* /*
* dirmod.h * dirmod.h
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* /*
* errcode.h * errcode.h
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

2
log.c
View File

@@ -1,6 +1,6 @@
/* /*
* log.c - Logging methods * log.c - Logging methods
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This module is a set of methods for logging (currently only syslog) * This module is a set of methods for logging (currently only syslog)
* *

2
log.h
View File

@@ -1,6 +1,6 @@
/* /*
* log.h * log.h
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

303
repmgr.c
View File

@@ -1,7 +1,7 @@
/* /*
* repmgr.c - Command interpreter for the repmgr package * repmgr.c - Command interpreter for the repmgr package
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This module is a command-line utility to easily setup a cluster of * This module is a command-line utility to easily setup a cluster of
* hot standby servers for an HA environment * hot standby servers for an HA environment
@@ -62,13 +62,7 @@
#include "check_dir.h" #include "check_dir.h"
#include "strutil.h" #include "strutil.h"
#include "version.h" #include "version.h"
#if (PG_VERSION_NUM < 90600)
#include "compat.h" #include "compat.h"
#else
#include "fe_utils/string_utils.h"
#include "postgres_fe.h"
#endif
#ifndef RECOVERY_COMMAND_FILE #ifndef RECOVERY_COMMAND_FILE
#define RECOVERY_COMMAND_FILE "recovery.conf" #define RECOVERY_COMMAND_FILE "recovery.conf"
@@ -172,6 +166,8 @@ static void config_file_list_add(t_configfile_list *list, const char *file, cons
static void matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id, int connection_node_id, int connection_status); static void matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id, int connection_node_id, int connection_status);
static void cube_set_node_status(t_node_status_cube **cube, int n, int node_id, int matrix_node_id, int connection_node_id, int connection_status); static void cube_set_node_status(t_node_status_cube **cube, int n, int node_id, int matrix_node_id, int connection_node_id, int connection_status);
static void drop_replication_slot_if_exists(PGconn *conn, int node_id, char *slot_name);
/* Global variables */ /* Global variables */
static PQconninfoOption *opts = NULL; static PQconninfoOption *opts = NULL;
@@ -762,7 +758,7 @@ main(int argc, char **argv)
{ {
if (optind < argc) if (optind < argc)
{ {
if (runtime_options.host[0]) if (runtime_options.host_param_provided == true)
{ {
PQExpBufferData additional_host_arg; PQExpBufferData additional_host_arg;
initPQExpBuffer(&additional_host_arg); initPQExpBuffer(&additional_host_arg);
@@ -946,7 +942,7 @@ main(int argc, char **argv)
*/ */
if (strcmp(repmgr_schema, DEFAULT_REPMGR_SCHEMA_PREFIX) == 0 && !runtime_options.force) if (strcmp(repmgr_schema, DEFAULT_REPMGR_SCHEMA_PREFIX) == 0 && !runtime_options.force)
{ {
log_err(_("unable to determine cluster name - please provide a valid configuration file with -c/--config-file\n")); log_err(_("unable to determine cluster name - please provide a valid configuration file with -f/--config-file\n"));
log_hint(_("Use -F/--force to continue anyway\n")); log_hint(_("Use -F/--force to continue anyway\n"));
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
@@ -1877,6 +1873,7 @@ do_master_register(void)
int primary_node_id = UNKNOWN_NODE_ID; int primary_node_id = UNKNOWN_NODE_ID;
bool record_created; bool record_created;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
conn = establish_db_connection(options.conninfo, true); conn = establish_db_connection(options.conninfo, true);
@@ -1949,42 +1946,51 @@ do_master_register(void)
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
/* Delete any existing record for this node if --force set */ begin_transaction(conn);
if (runtime_options.force)
/*
* Check whether there's an existing record for this node, and
* update it if --force set
*/
if (get_node_record(conn, options.cluster_name, options.node, &node_info))
{ {
bool node_record_deleted; if (!runtime_options.force)
t_node_info node_info = T_NODE_INFO_INITIALIZER;
begin_transaction(conn);
if (get_node_record(conn, options.cluster_name, options.node, &node_info))
{ {
log_notice(_("deleting existing master record with id %i\n"), options.node); log_err(_("this node is already registered\n"));
log_hint(_("use -F/--force to overwrite the existing node record\n"));
node_record_deleted = delete_node_record(conn, rollback_transaction(conn);
options.node, PQfinish(conn);
"master register"); exit(ERR_BAD_CONFIG);
if (node_record_deleted == false)
{
rollback_transaction(conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
} }
}
/* Now register the master */ record_created = update_node_record(conn,
record_created = create_node_record(conn, "master register",
"master register", options.node,
options.node, "master",
"master", NO_UPSTREAM_NODE,
NO_UPSTREAM_NODE, options.cluster_name,
options.cluster_name, options.node_name,
options.node_name, options.conninfo,
options.conninfo, options.priority,
options.priority, repmgr_slot_name_ptr,
repmgr_slot_name_ptr, true);
true);
}
else
{
/* Now register the master */
record_created = create_node_record(conn,
"master register",
options.node,
"master",
NO_UPSTREAM_NODE,
options.cluster_name,
options.node_name,
options.conninfo,
options.priority,
repmgr_slot_name_ptr,
true);
}
if (record_created == false) if (record_created == false)
{ {
@@ -2846,11 +2852,18 @@ do_standby_clone(void)
maxlen_snprintf(local_repmgr_directory, "%s/repmgr", local_data_directory ); maxlen_snprintf(local_repmgr_directory, "%s/repmgr", local_data_directory );
maxlen_snprintf(datadir_list_filename, "%s/data.txt", local_repmgr_directory); maxlen_snprintf(datadir_list_filename, "%s/data.txt", local_repmgr_directory);
if (!create_pg_dir(local_data_directory, runtime_options.force))
{
log_err(_("unable to use directory %s ...\n"),
local_data_directory);
log_hint(_("use -F/--force option to force this directory to be overwritten\n"));
exit(ERR_BAD_CONFIG);
}
if (!create_pg_dir(local_repmgr_directory, runtime_options.force)) if (!create_pg_dir(local_repmgr_directory, runtime_options.force))
{ {
log_err(_("unable to use directory \"%s\" ...\n"), log_err(_("unable to create directory \"%s\" ...\n"),
local_repmgr_directory); local_repmgr_directory);
log_hint(_("use -F/--force option to force this directory to be overwritten\n"));
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
@@ -2958,8 +2971,6 @@ do_standby_clone(void)
primary_conn = source_conn; primary_conn = source_conn;
} }
/* /*
* Sanity-check that the master node has a repmgr schema - if not * Sanity-check that the master node has a repmgr schema - if not
* present, fail with an error (unless -F/--force is used) * present, fail with an error (unless -F/--force is used)
@@ -2979,7 +2990,6 @@ do_standby_clone(void)
log_warning(_("expected repmgr schema '%s' not found on master server\n"), get_repmgr_schema()); log_warning(_("expected repmgr schema '%s' not found on master server\n"), get_repmgr_schema());
} }
/* Fetch the source's data directory */ /* Fetch the source's data directory */
if (get_pg_setting(source_conn, "data_directory", master_data_directory) == false) if (get_pg_setting(source_conn, "data_directory", master_data_directory) == false)
{ {
@@ -3001,8 +3011,6 @@ do_standby_clone(void)
log_hint(_("use -D/--data-dir to explicitly specify a data directory\n")); log_hint(_("use -D/--data-dir to explicitly specify a data directory\n"));
} }
/* /*
* Copy the source connection so that we have some default values, * Copy the source connection so that we have some default values,
* particularly stuff like passwords extracted from PGPASSFILE; * particularly stuff like passwords extracted from PGPASSFILE;
@@ -3587,6 +3595,9 @@ do_standby_clone(void)
/* /*
* We must create some PGDATA subdirectories because they are * We must create some PGDATA subdirectories because they are
* not included in the Barman backup. * not included in the Barman backup.
*
* See class RsyncBackupExecutor in the Barman source (barman/backup_executor.py)
* for a definitive list of excluded directories.
*/ */
{ {
const char* const dirs[] = { const char* const dirs[] = {
@@ -3597,14 +3608,14 @@ do_standby_clone(void)
/* Only from 9.4 */ /* Only from 9.4 */
"pg_dynshmem", "pg_logical", "pg_logical/snapshots", "pg_logical/mappings", "pg_replslot", "pg_dynshmem", "pg_logical", "pg_logical/snapshots", "pg_logical/mappings", "pg_replslot",
/* Already in 9.3 */ /* Already in 9.3 */
"pg_serial", "pg_snapshots", "pg_stat", "pg_stat_tmp", "pg_tblspc", "pg_notify", "pg_serial", "pg_snapshots", "pg_stat", "pg_stat_tmp", "pg_tblspc",
"pg_twophase", "pg_xlog", 0 "pg_twophase", "pg_xlog", 0
}; };
const int vers[] = { const int vers[] = {
100000, 100000,
90500, 90500,
90400, 90400, 90400, 90400, 90400, 90400, 90400, 90400, 90400, 90400,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, -100000, 0 0, -100000, 0
}; };
for (i = 0; dirs[i]; i++) for (i = 0; dirs[i]; i++)
@@ -3614,7 +3625,7 @@ do_standby_clone(void)
continue; continue;
/* directory existed in earlier versions than this server but has been removed/renamed - skip */ /* directory existed in earlier versions than this server but has been removed/renamed - skip */
if (vers[1] < 0 && server_version_num >= abs(vers[i])) if (vers[i] < 0 && server_version_num >= abs(vers[i]))
continue; continue;
maxlen_snprintf(filename, "%s/%s", local_data_directory, dirs[i]); maxlen_snprintf(filename, "%s/%s", local_data_directory, dirs[i]);
@@ -3634,17 +3645,6 @@ do_standby_clone(void)
initPQExpBuffer(&tablespace_map); initPQExpBuffer(&tablespace_map);
} }
/*
* From 9.1 default is to wait for a sync standby to ack, avoid that by
* turning off sync rep for this session
*/
if (set_config_bool(source_conn, "synchronous_commit", false) == false)
{
r = ERR_BAD_CONFIG;
retval = ERR_BAD_CONFIG;
goto stop_backup;
}
if (start_backup(source_conn, first_wal_segment, runtime_options.fast_checkpoint) == false) if (start_backup(source_conn, first_wal_segment, runtime_options.fast_checkpoint) == false)
{ {
r = ERR_BAD_BASEBACKUP; r = ERR_BAD_BASEBACKUP;
@@ -3674,15 +3674,16 @@ do_standby_clone(void)
master_data_directory, local_data_directory, master_data_directory, local_data_directory,
true, server_version_num); true, server_version_num);
/* /*
Exit code 0 means no error, but we want to ignore exit code 24 as well * Exit code 0 means no error, but we want to ignore exit code 24 as well
as rsync returns that code on "Partial transfer due to vanished source files". * as rsync returns that code on "Partial transfer due to vanished source files".
It's quite common for this to happen on the data directory, particularly * It's quite common for this to happen on the data directory, particularly
with long running rsync on a busy server. * with long running rsync on a busy server.
*/ */
if (!WIFEXITED(r) && WEXITSTATUS(r) != 24) if (WIFEXITED(r) && WEXITSTATUS(r) && WEXITSTATUS(r) != 24)
{ {
log_warning(_("standby clone: failed copying master data directory '%s'\n"), log_err(_("standby clone: failed copying master data directory '%s'\n"),
master_data_directory); master_data_directory);
r = retval = ERR_BAD_RSYNC;
goto stop_backup; goto stop_backup;
} }
@@ -3766,15 +3767,16 @@ do_standby_clone(void)
true, server_version_num); true, server_version_num);
/* /*
Exit code 0 means no error, but we want to ignore exit code 24 as well * Exit code 0 means no error, but we want to ignore exit code 24 as well
as rsync returns that code on "Partial transfer due to vanished source files". * as rsync returns that code on "Partial transfer due to vanished source files".
It's quite common for this to happen on the data directory, particularly * It's quite common for this to happen on the data directory, particularly
with long running rsync on a busy server. * with long running rsync on a busy server.
*/ */
if (!WIFEXITED(r) && WEXITSTATUS(r) != 24) if (WIFEXITED(r) && WEXITSTATUS(r) && WEXITSTATUS(r) != 24)
{ {
log_warning(_("standby clone: failed copying tablespace directory '%s'\n"), log_err(_("standby clone: failed copying tablespace directory '%s'\n"),
cell_t->location); cell_t->location);
r = retval = ERR_BAD_RSYNC;
goto stop_backup; goto stop_backup;
} }
} }
@@ -3782,7 +3784,7 @@ do_standby_clone(void)
/* /*
* If a valid mapping was provide for this tablespace, arrange for it to * If a valid mapping was provide for this tablespace, arrange for it to
* be remapped * be remapped
* (if no tablespace mappings was provided, the link will be copied as-is * (if no tablespace mapping was provided, the link will be copied as-is
* by pg_basebackup or rsync and no action is required) * by pg_basebackup or rsync and no action is required)
*/ */
if (mapping_found == true || mode == barman) if (mapping_found == true || mode == barman)
@@ -3941,7 +3943,7 @@ do_standby_clone(void)
r = copy_remote_files(runtime_options.host, runtime_options.remote_user, r = copy_remote_files(runtime_options.host, runtime_options.remote_user,
file->filepath, dest_path, false, server_version_num); file->filepath, dest_path, false, server_version_num);
if (r != 0) if (WEXITSTATUS(r))
{ {
log_err(_("standby clone: unable to copy config file '%s'\n"), log_err(_("standby clone: unable to copy config file '%s'\n"),
file->filename); file->filename);
@@ -3975,7 +3977,7 @@ do_standby_clone(void)
r = copy_remote_files(runtime_options.host, runtime_options.remote_user, r = copy_remote_files(runtime_options.host, runtime_options.remote_user,
master_control_file, local_control_file, master_control_file, local_control_file,
false, server_version_num); false, server_version_num);
if (r != 0) if (WEXITSTATUS(r))
{ {
log_warning(_("standby clone: failed copying master control file '%s'\n"), log_warning(_("standby clone: failed copying master control file '%s'\n"),
master_control_file); master_control_file);
@@ -4533,7 +4535,8 @@ do_standby_follow(void)
char script[MAXLEN]; char script[MAXLEN];
char master_conninfo[MAXLEN]; char master_conninfo[MAXLEN];
PGconn *master_conn; PGconn *master_conn;
int master_id = 0; int master_id = UNKNOWN_NODE_ID,
original_upstream_node_id = UNKNOWN_NODE_ID;
int r, int r,
retval; retval;
@@ -4680,7 +4683,11 @@ do_standby_follow(void)
} }
/* Fetch our node record so we can write application_name, if set */ /*
* Fetch our node record so we can write application_name, if set,
* and to get the upstream node ID, which we'll need to know if
* replication slots are in use and we want to delete the old slot.
*/
query_result = get_node_record(master_conn, query_result = get_node_record(master_conn,
options.cluster_name, options.cluster_name,
options.node, options.node,
@@ -4713,6 +4720,15 @@ do_standby_follow(void)
if (application_name != NULL && strlen(application_name)) if (application_name != NULL && strlen(application_name))
param_set(&recovery_conninfo, "application_name", application_name); param_set(&recovery_conninfo, "application_name", application_name);
} }
if (local_node_record.upstream_node_id != UNKNOWN_NODE_ID)
{
original_upstream_node_id = local_node_record.upstream_node_id;
}
else
{
original_upstream_node_id = master_id;
}
} }
log_info(_("changing standby's master to node %i\n"), master_id); log_info(_("changing standby's master to node %i\n"), master_id);
@@ -4742,6 +4758,54 @@ do_standby_follow(void)
exit(ERR_NO_RESTART); exit(ERR_NO_RESTART);
} }
/*
* If replication slots are in use, and an inactive one for this node
* (a former standby) exists on the former upstream, drop it.
*/
if (options.use_replication_slots && original_upstream_node_id != UNKNOWN_NODE_ID)
{
t_node_info upstream_node_record = T_NODE_INFO_INITIALIZER;
int upstream_query_result;
log_verbose(LOG_INFO, "attempting to remove replication slot from old upstream node %i\n",
original_upstream_node_id);
/* XXX should we poll for server restart? */
conn = establish_db_connection(options.conninfo, true);
upstream_query_result = get_node_record(conn,
options.cluster_name,
original_upstream_node_id,
&upstream_node_record);
PQfinish(conn);
if (upstream_query_result != 1)
{
log_warning(_("unable to retrieve node record for old upstream node %i"),
original_upstream_node_id);
}
else
{
conn = establish_db_connection_quiet(upstream_node_record.conninfo_str);
if (PQstatus(conn) != CONNECTION_OK)
{
log_info(_("unable to connect to old upstream node %i to remove replication slot\n"),
original_upstream_node_id);
log_hint(_("if reusing this node, you should manually remove any inactive replication slots\n"));
}
else
{
drop_replication_slot_if_exists(conn,
original_upstream_node_id,
local_node_record.slot_name);
}
}
}
/* /*
* It's possible this node was an inactive primary - update the * It's possible this node was an inactive primary - update the
* relevant fields to ensure it's marked as an active standby * relevant fields to ensure it's marked as an active standby
@@ -4759,6 +4823,8 @@ do_standby_follow(void)
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
log_notice(_("STANDBY FOLLOW successful\n"));
create_event_record(master_conn, create_event_record(master_conn,
&options, &options,
options.node, options.node,
@@ -4794,8 +4860,6 @@ do_standby_follow(void)
* *
* TODO: * TODO:
* - make connection test timeouts/intervals configurable (see below) * - make connection test timeouts/intervals configurable (see below)
* - add command line option --remote_pg_bindir or similar to
* optionally handle cases where the remote pg_bindir is different
*/ */
static void static void
@@ -5529,6 +5593,8 @@ do_standby_switchover(void)
/* Check for entry in the new master's pg_stat_replication */ /* Check for entry in the new master's pg_stat_replication */
local_conn = establish_db_connection(options.conninfo, true);
{ {
int i, int i,
replication_check_timeout = 60, replication_check_timeout = 60,
@@ -5538,8 +5604,6 @@ do_standby_switchover(void)
initPQExpBuffer(&event_details); initPQExpBuffer(&event_details);
local_conn = establish_db_connection(options.conninfo, true);
i = 0; i = 0;
for (;;) for (;;)
{ {
@@ -5635,30 +5699,9 @@ do_standby_switchover(void)
} }
else else
{ {
t_replication_slot slot_info; drop_replication_slot_if_exists(remote_conn,
int query_res; remote_node_id,
local_node_record.slot_name);
query_res = get_slot_record(remote_conn, local_node_record.slot_name, &slot_info);
if (query_res)
{
if (slot_info.active == false)
{
if (drop_replication_slot(remote_conn, local_node_record.slot_name) == true)
{
log_notice(_("replication slot \"%s\" deleted on former master\n"), local_node_record.slot_name);
}
else
{
log_err(_("unable to delete replication slot \"%s\" on former master\n"), local_node_record.slot_name);
}
}
/* if active replication slot exists, call Houston as we have a problem */
else
{
log_err(_("replication slot \"%s\" is still active on former master\n"), local_node_record.slot_name);
}
}
} }
PQfinish(remote_conn); PQfinish(remote_conn);
@@ -6168,7 +6211,7 @@ do_witness_create(void)
r = copy_remote_files(runtime_options.host, runtime_options.remote_user, r = copy_remote_files(runtime_options.host, runtime_options.remote_user,
master_hba_file, runtime_options.dest_dir, false, -1); master_hba_file, runtime_options.dest_dir, false, -1);
if (r != 0) if (WEXITSTATUS(r))
{ {
char *errmsg = _("Unable to copy pg_hba.conf from master"); char *errmsg = _("Unable to copy pg_hba.conf from master");
log_err("%s\n", errmsg); log_err("%s\n", errmsg);
@@ -6934,9 +6977,11 @@ copy_remote_files(char *host, char *remote_user, char *remote_path,
r = system(script); r = system(script);
if (r != 0) log_debug("copy_remote_files(): r = %i; WIFEXITED: %i; WEXITSTATUS: %i\n", r, WIFEXITED(r), WEXITSTATUS(r));
log_err(_("unable to rsync from remote host (%s:%s)\n"),
host_string, remote_path); /* exit code 24 indicates vanished files, which isn't a problem for us */
if (WEXITSTATUS(r) && WEXITSTATUS(r) != 24)
log_verbose(LOG_WARNING, "copy_remote_files(): rsync returned unexpected exit status %i \n", WEXITSTATUS(r));
return r; return r;
} }
@@ -8760,3 +8805,33 @@ config_file_list_add(t_configfile_list *list, const char *file, const char *file
list->entries ++; list->entries ++;
} }
static void
drop_replication_slot_if_exists(PGconn *conn, int node_id, char *slot_name)
{
t_replication_slot slot_info;
int query_res;
query_res = get_slot_record(conn,slot_name, &slot_info);
if (query_res)
{
if (slot_info.active == false)
{
if (drop_replication_slot(conn, slot_name) == true)
{
log_notice(_("replication slot \"%s\" deleted on node %i\n"), slot_name, node_id);
}
else
{
log_err(_("unable to delete replication slot \"%s\" on node %i\n"), slot_name, node_id);
}
}
/* if active replication slot exists, call Houston as we have a problem */
else
{
log_err(_("replication slot \"%s\" is still active on node %i\n"), slot_name, node_id);
}
}
}

View File

@@ -80,12 +80,6 @@
# #
#logfile='/var/log/repmgr/repmgr.log' #logfile='/var/log/repmgr/repmgr.log'
# By default only repmgrd log output will be written to a file,
# if defined in "logfile"
# enable this to restore old behaviour where output from the repmgr
# client will be written to the logfile too
#log_repmgr_to_file = 0
# event notifications can be passed to an arbitrary external program # event notifications can be passed to an arbitrary external program
# together with the following parameters: # together with the following parameters:
# #
@@ -149,8 +143,15 @@
# external command arguments. Values shown are examples. # external command arguments. Values shown are examples.
#pg_ctl_options='-s' #pg_ctl_options='-s'
#pg_basebackup_options='--xlog-method=s' #pg_basebackup_options='--label=repmgr_backup'
# This is the host name of the barman server, which is used for connecting over
# to the barman server (passwordless ssh keys should be in place)
#barman_server='backup_server'
# If you are placing the barman.conf file in a non-standard path, or using
# a name other than barman.conf, use this parameter to specify the path and
# name of the barman configuration file.
#barman_config='/path/to/barman.conf'
# Standby clone settings # Standby clone settings
# ---------------------- # ----------------------

View File

@@ -1,6 +1,6 @@
/* /*
* repmgr.h * repmgr.h
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
* repmgr.sql * repmgr.sql
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
*/ */

View File

@@ -1,7 +1,7 @@
/* /*
* repmgrd.c - Replication manager daemon * repmgrd.c - Replication manager daemon
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This module connects to the nodes of a replication cluster and monitors * This module connects to the nodes of a replication cluster and monitors
* how far are they from master * how far are they from master
@@ -1187,10 +1187,22 @@ standby_monitor(void)
PQclear(res); PQclear(res);
lsn_master_current_xlog_location = lsn_to_xlogrecptr(last_wal_primary_location, NULL); lsn_master_current_xlog_location = lsn_to_xlogrecptr(last_wal_primary_location, NULL);
lsn_last_xlog_replay_location = lsn_to_xlogrecptr(last_xlog_replay_location, NULL);
lsn_last_xlog_receive_location = lsn_to_xlogrecptr(last_xlog_receive_location, NULL); lsn_last_xlog_receive_location = lsn_to_xlogrecptr(last_xlog_receive_location, NULL);
lsn_last_xlog_replay_location = lsn_to_xlogrecptr(last_xlog_replay_location, NULL);
if (lsn_last_xlog_receive_location >= lsn_last_xlog_replay_location)
{
apply_lag = (long long unsigned int)lsn_last_xlog_receive_location - lsn_last_xlog_replay_location;
}
else
{
/* This should never happen, but in case it does set apply lag to zero */
log_warning("Standby receive (%s) location appears less than standby replay location (%s)\n",
last_xlog_receive_location,
last_xlog_replay_location);
apply_lag = 0;
}
apply_lag = (long long unsigned int)lsn_last_xlog_receive_location - lsn_last_xlog_replay_location;
/* Calculate replication lag */ /* Calculate replication lag */
if (lsn_master_current_xlog_location >= lsn_last_xlog_receive_location) if (lsn_master_current_xlog_location >= lsn_last_xlog_receive_location)
@@ -1199,7 +1211,7 @@ standby_monitor(void)
} }
else else
{ {
/* This should never happen, but in case it does set lag to zero */ /* This should never happen, but in case it does set replication lag to zero */
log_warning("Master xlog (%s) location appears less than standby receive location (%s)\n", log_warning("Master xlog (%s) location appears less than standby receive location (%s)\n",
last_wal_primary_location, last_wal_primary_location,
last_xlog_receive_location); last_xlog_receive_location);
@@ -2327,13 +2339,13 @@ lsn_to_xlogrecptr(char *lsn, bool *format_ok)
if (format_ok != NULL) if (format_ok != NULL)
*format_ok = true; *format_ok = true;
return (((XLogRecPtr) xlogid * 16 * 1024 * 1024 * 255) + xrecoff); return (XLogRecPtr) ((uint64) xlogid) << 32 | (uint64) xrecoff;
} }
void void
usage(void) usage(void)
{ {
log_err(_("%s: Replicator manager daemon \n"), progname()); log_err(_("%s: replication management daemon for PostgreSQL\n"), progname());
log_err(_("Try \"%s --help\" for more information.\n"), progname()); log_err(_("Try \"%s --help\" for more information.\n"), progname());
} }

View File

@@ -1,7 +1,7 @@
# #
# Makefile # Makefile
# #
# Copyright (c) 2ndQuadrant, 2010-2016 # Copyright (c) 2ndQuadrant, 2010-2017
# #
MODULE_big = repmgr_funcs MODULE_big = repmgr_funcs

View File

@@ -1,6 +1,6 @@
/* /*
* repmgr_function.sql * repmgr_function.sql
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
* uninstall_repmgr_funcs.sql * uninstall_repmgr_funcs.sql
* Copyright (c) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
*/ */

View File

@@ -1,7 +1,7 @@
/* /*
* strutil.c * strutil.c
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* /*
* strutil.h * strutil.h
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify

View File

@@ -1,7 +1,7 @@
/* /*
* uninstall_repmgr.sql * uninstall_repmgr.sql
* *
* Copyright (C) 2ndQuadrant, 2010-2016 * Copyright (c) 2ndQuadrant, 2010-2017
* *
*/ */

View File

@@ -1,6 +1,6 @@
#ifndef _VERSION_H_ #ifndef _VERSION_H_
#define _VERSION_H_ #define _VERSION_H_
#define REPMGR_VERSION "3.3" #define REPMGR_VERSION "3.3.1"
#endif #endif