mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-27 00:46:29 +00:00
Merge pull request #191 from gciolli/feature-barman-support
Add Barman support to repmgr standby clone
This commit is contained in:
76
README.md
76
README.md
@@ -522,6 +522,78 @@ standby's upstream server is the replication cluster master. While of limited
|
|||||||
use in a simple master/standby replication cluster, this information is required
|
use in a simple master/standby replication cluster, this information is required
|
||||||
to effectively manage cascading replication (see below).
|
to effectively manage cascading replication (see below).
|
||||||
|
|
||||||
|
### Using Barman to clone a standby
|
||||||
|
|
||||||
|
`repmgr standby clone` also supports Barman, the Backup and
|
||||||
|
Replication manager (http://www.pgbarman.org/), as a provider of both
|
||||||
|
base backups and WAL files.
|
||||||
|
|
||||||
|
Barman support provides the following advantages:
|
||||||
|
|
||||||
|
- the primary node does not need to perform a new backup every time a
|
||||||
|
new standby is cloned;
|
||||||
|
- a standby node can be disconnected for longer periods without losing
|
||||||
|
the ability to catch up, and without causing accumulation of WAL
|
||||||
|
files on the primary node;
|
||||||
|
- therefore, `repmgr` does not need to use replication slots, and the
|
||||||
|
primary node does not need to set `wal_keep_segments`.
|
||||||
|
|
||||||
|
> *NOTE*: In view of the above, Barman support is incompatible with
|
||||||
|
> the `use_replication_slots` setting in `repmgr.conf`.
|
||||||
|
|
||||||
|
In order to enable Barman support for `repmgr standby clone`, you must
|
||||||
|
ensure that:
|
||||||
|
|
||||||
|
- the name of the server configured in Barman is equal to the
|
||||||
|
`cluster_name` setting in `repmgr.conf`;
|
||||||
|
- the `barman_server` setting in `repmgr.conf` is set to the SSH
|
||||||
|
hostname of the Barman server;
|
||||||
|
- the `restore_command` setting in `repmgr.conf` is configured to
|
||||||
|
use a copy of the `barman-wal-restore.py` script shipped with Barman
|
||||||
|
(see below);
|
||||||
|
- the Barman catalogue includes at least one valid backup for this
|
||||||
|
server.
|
||||||
|
|
||||||
|
> *NOTE*: Barman support is automatically enabled if `barman_server`
|
||||||
|
> is set. Normally it is a good practice to use Barman, for instance
|
||||||
|
> when fetching a base backup while cloning a standby; in any case,
|
||||||
|
> Barman mode can be disabled using the `--without-barman` command
|
||||||
|
> line option.
|
||||||
|
|
||||||
|
> *NOTE*: if you have a non-default SSH configuration on the Barman
|
||||||
|
> server, e.g. using a port other than 22, then you can set those
|
||||||
|
> parameters in a dedicated Host section in `~/.ssh/config`
|
||||||
|
> corresponding to the value of `barman_server` in `repmgr.conf`. See
|
||||||
|
> the "Host" section in `man 5 ssh_config` for more details.
|
||||||
|
|
||||||
|
`barman-wal-restore.py` is a Python script provided by the Barman
|
||||||
|
development team, which must be copied in a location accessible to
|
||||||
|
`repmgr`, and marked as executable; `restore_command` must then be
|
||||||
|
set in `repmgr.conf` as follows:
|
||||||
|
|
||||||
|
<script> <Barman hostname> <cluster_name> %f %p
|
||||||
|
|
||||||
|
For instance, suppose that we have installed Barman on the `barmansrv`
|
||||||
|
host, and that we have placed a copy of `barman-wal-restore.py` into
|
||||||
|
the `/usr/local/bin` directory. First, we ensure that the script is
|
||||||
|
executable:
|
||||||
|
|
||||||
|
sudo chmod +x /usr/local/bin/barman-wal-restore.py
|
||||||
|
|
||||||
|
Then we check that `repmgr.conf` includes the following lines:
|
||||||
|
|
||||||
|
barman_server=barmansrv
|
||||||
|
restore_command=/usr/local/bin/barman-wal-restore.py barmansrv test %f %p
|
||||||
|
|
||||||
|
Now we can clone a standby using the Barman server:
|
||||||
|
|
||||||
|
$ repmgr -h node1 -D 9.5/main -f /etc/repmgr.conf standby clone
|
||||||
|
[2016-06-12 20:08:35] [NOTICE] destination directory '9.5/main' provided
|
||||||
|
[2016-06-12 20:08:35] [NOTICE] getting backup from Barman...
|
||||||
|
[2016-06-12 20:08:36] [NOTICE] standby clone (from Barman) complete
|
||||||
|
[2016-06-12 20:08:36] [NOTICE] you can now start your PostgreSQL server
|
||||||
|
[2016-06-12 20:08:36] [HINT] for example : pg_ctl -D 9.5/data start
|
||||||
|
[2016-06-12 20:08:36] [HINT] After starting the server, you need to register this standby with "repmgr standby register"
|
||||||
|
|
||||||
Advanced options for cloning a standby
|
Advanced options for cloning a standby
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
@@ -559,6 +631,10 @@ and destination server as the contents of files existing on both servers need
|
|||||||
to be compared, meaning this method is not necessarily faster than making a
|
to be compared, meaning this method is not necessarily faster than making a
|
||||||
fresh clone with `pg_basebackup`.
|
fresh clone with `pg_basebackup`.
|
||||||
|
|
||||||
|
> *NOTE*: `barman-wal-restore.py` supports command line switches to
|
||||||
|
> control parallelism (`--parallel=N`) and compression (`--bzip2`,
|
||||||
|
> `--gzip`).
|
||||||
|
|
||||||
### Dealing with PostgreSQL configuration files
|
### Dealing with PostgreSQL configuration files
|
||||||
|
|
||||||
By default, `repmgr` will attempt to copy the standard configuration files
|
By default, `repmgr` will attempt to copy the standard configuration files
|
||||||
|
|||||||
10
config.c
10
config.c
@@ -215,6 +215,7 @@ parse_config(t_configuration_options *options)
|
|||||||
options->upstream_node = NO_UPSTREAM_NODE;
|
options->upstream_node = NO_UPSTREAM_NODE;
|
||||||
options->use_replication_slots = 0;
|
options->use_replication_slots = 0;
|
||||||
memset(options->conninfo, 0, sizeof(options->conninfo));
|
memset(options->conninfo, 0, sizeof(options->conninfo));
|
||||||
|
memset(options->barman_server, 0, sizeof(options->barman_server));
|
||||||
options->failover = MANUAL_FAILOVER;
|
options->failover = MANUAL_FAILOVER;
|
||||||
options->priority = DEFAULT_PRIORITY;
|
options->priority = DEFAULT_PRIORITY;
|
||||||
memset(options->node_name, 0, sizeof(options->node_name));
|
memset(options->node_name, 0, sizeof(options->node_name));
|
||||||
@@ -310,6 +311,8 @@ parse_config(t_configuration_options *options)
|
|||||||
options->upstream_node = repmgr_atoi(value, "upstream_node", &config_errors, false);
|
options->upstream_node = repmgr_atoi(value, "upstream_node", &config_errors, false);
|
||||||
else if (strcmp(name, "conninfo") == 0)
|
else if (strcmp(name, "conninfo") == 0)
|
||||||
strncpy(options->conninfo, value, MAXLEN);
|
strncpy(options->conninfo, value, MAXLEN);
|
||||||
|
else if (strcmp(name, "barman_server") == 0)
|
||||||
|
strncpy(options->barman_server, value, MAXLEN);
|
||||||
else if (strcmp(name, "rsync_options") == 0)
|
else if (strcmp(name, "rsync_options") == 0)
|
||||||
strncpy(options->rsync_options, value, QUERY_STR_LEN);
|
strncpy(options->rsync_options, value, QUERY_STR_LEN);
|
||||||
else if (strcmp(name, "ssh_options") == 0)
|
else if (strcmp(name, "ssh_options") == 0)
|
||||||
@@ -635,6 +638,13 @@ reload_config(t_configuration_options *orig_options)
|
|||||||
config_changed = true;
|
config_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* barman_server */
|
||||||
|
if (strcmp(orig_options->barman_server, new_options.barman_server) != 0)
|
||||||
|
{
|
||||||
|
strcpy(orig_options->barman_server, new_options.barman_server);
|
||||||
|
config_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* node */
|
/* node */
|
||||||
if (orig_options->node != new_options.node)
|
if (orig_options->node != new_options.node)
|
||||||
{
|
{
|
||||||
|
|||||||
19
config.h
19
config.h
@@ -58,6 +58,7 @@ typedef struct
|
|||||||
int node;
|
int node;
|
||||||
int upstream_node;
|
int upstream_node;
|
||||||
char conninfo[MAXLEN];
|
char conninfo[MAXLEN];
|
||||||
|
char barman_server[MAXLEN];
|
||||||
int failover;
|
int failover;
|
||||||
int priority;
|
int priority;
|
||||||
char node_name[MAXLEN];
|
char node_name[MAXLEN];
|
||||||
@@ -91,7 +92,7 @@ typedef struct
|
|||||||
* The following will initialize the structure with a minimal set of options;
|
* The following will initialize the structure with a minimal set of options;
|
||||||
* actual defaults are set in parse_config() before parsing the configuration file
|
* actual defaults are set in parse_config() before parsing the configuration file
|
||||||
*/
|
*/
|
||||||
#define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", "", 0, 0, 0, 0, "", { NULL, NULL }, {NULL, NULL} }
|
#define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", "", 0, 0, 0, 0, "", { NULL, NULL }, {NULL, NULL} }
|
||||||
|
|
||||||
typedef struct ItemListCell
|
typedef struct ItemListCell
|
||||||
{
|
{
|
||||||
@@ -105,6 +106,22 @@ typedef struct ItemList
|
|||||||
ItemListCell *tail;
|
ItemListCell *tail;
|
||||||
} ItemList;
|
} ItemList;
|
||||||
|
|
||||||
|
typedef struct TablespaceDataListCell
|
||||||
|
{
|
||||||
|
struct TablespaceDataListCell *next;
|
||||||
|
char *name;
|
||||||
|
char *oid;
|
||||||
|
char *location;
|
||||||
|
/* optional payload */
|
||||||
|
FILE *f;
|
||||||
|
} TablespaceDataListCell;
|
||||||
|
|
||||||
|
typedef struct TablespaceDataList
|
||||||
|
{
|
||||||
|
TablespaceDataListCell *head;
|
||||||
|
TablespaceDataListCell *tail;
|
||||||
|
} TablespaceDataList;
|
||||||
|
|
||||||
void set_progname(const char *argv0);
|
void set_progname(const char *argv0);
|
||||||
const char * progname(void);
|
const char * progname(void);
|
||||||
|
|
||||||
|
|||||||
4
repmgr.h
4
repmgr.h
@@ -57,6 +57,7 @@
|
|||||||
#define OPT_PWPROMPT 7
|
#define OPT_PWPROMPT 7
|
||||||
#define OPT_CSV 8
|
#define OPT_CSV 8
|
||||||
#define OPT_NODE 9
|
#define OPT_NODE 9
|
||||||
|
#define OPT_WITHOUT_BARMAN 10
|
||||||
|
|
||||||
/* deprecated command line options */
|
/* deprecated command line options */
|
||||||
#define OPT_INITDB_NO_PWPROMPT 999
|
#define OPT_INITDB_NO_PWPROMPT 999
|
||||||
@@ -83,6 +84,7 @@ typedef struct
|
|||||||
bool fast_checkpoint;
|
bool fast_checkpoint;
|
||||||
bool ignore_external_config_files;
|
bool ignore_external_config_files;
|
||||||
bool csv_mode;
|
bool csv_mode;
|
||||||
|
bool without_barman;
|
||||||
char masterport[MAXLEN];
|
char masterport[MAXLEN];
|
||||||
/*
|
/*
|
||||||
* configuration file parameters which can be overridden on the
|
* configuration file parameters which can be overridden on the
|
||||||
@@ -106,7 +108,7 @@ typedef struct
|
|||||||
char recovery_min_apply_delay[MAXLEN];
|
char recovery_min_apply_delay[MAXLEN];
|
||||||
} t_runtime_options;
|
} t_runtime_options;
|
||||||
|
|
||||||
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, false, false, false, false, "", "", "", "", "fast", "", 0, 0, "", ""}
|
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, false, false, false, false, false, "", "", "", "", "fast", "", 0, 0, "", ""}
|
||||||
|
|
||||||
struct BackupLabel
|
struct BackupLabel
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user