mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-27 17:06:29 +00:00
Document upgrade process from repmgr3
Also provide unpackaged extension upgrade SQL, and a script to assist converting repmgr.conf files.
This commit is contained in:
17
README.md
17
README.md
@@ -26,14 +26,6 @@ objects used by repmgr are stored in a dedicated `repmgr` schema, rather
|
|||||||
than `repmgr_$cluster_name`. Note there is no need to install the extension,
|
than `repmgr_$cluster_name`. Note there is no need to install the extension,
|
||||||
this will be done automatically by `repmgr primary register`.
|
this will be done automatically by `repmgr primary register`.
|
||||||
|
|
||||||
Metadata tables have been revised and are not backwards-compatible with repmgr 3.x,
|
|
||||||
however future DDL updates will be easier as they can be carried out via the
|
|
||||||
`ALTER EXTENSION` mechanism.
|
|
||||||
|
|
||||||
An extension upgrade script will be provided for pre-4.0 installations;
|
|
||||||
note this will require the existing `repmgr_$cluster_name` schema to
|
|
||||||
be renamed to `repmgr` beforehand.
|
|
||||||
|
|
||||||
Some configuration items have had their names changed for consistency
|
Some configuration items have had their names changed for consistency
|
||||||
and clarity e.g. `node` => `node_id`. `repmgr` will issue a warning
|
and clarity e.g. `node` => `node_id`. `repmgr` will issue a warning
|
||||||
about deprecated/altered options.
|
about deprecated/altered options.
|
||||||
@@ -44,6 +36,12 @@ upstream ID, which might change over time.
|
|||||||
|
|
||||||
See file `doc/changes-in-repmgr4.md` for more details.
|
See file `doc/changes-in-repmgr4.md` for more details.
|
||||||
|
|
||||||
|
To upgrade from repmgr 3.x, both the `repmgr` metadatabase and all
|
||||||
|
repmgr configuration files need to be converted. This is quite
|
||||||
|
straightforward and scripts are provided to assist with this.
|
||||||
|
See document `docs/upgrading-from-repmgr3.md` for further details.
|
||||||
|
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -148,6 +146,9 @@ UNIX-like system supported by PostgreSQL itself.
|
|||||||
`repmgr 4` supports PostgreSQL from version 9.5. If you need to using `repmgr`
|
`repmgr 4` supports PostgreSQL from version 9.5. If you need to using `repmgr`
|
||||||
on earlier versions of PostgreSQL 9.3 or 9.4, please use `repmgr 3.3`.
|
on earlier versions of PostgreSQL 9.3 or 9.4, please use `repmgr 3.3`.
|
||||||
|
|
||||||
|
If upgrading from `repmgr 3`, please see the separate upgrade guide
|
||||||
|
`docs/upgrading-from-repmgr3.md`.
|
||||||
|
|
||||||
All servers in the replication cluster must be running the same major version of
|
All servers in the replication cluster must be running the same major version of
|
||||||
PostgreSQL, and we recommend that they also run the same minor version.
|
PostgreSQL, and we recommend that they also run the same minor version.
|
||||||
|
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
|
|||||||
_("parameter \"master_reponse_timeout\" has been removed; use \"async_query_timeout\" instead"));
|
_("parameter \"master_reponse_timeout\" has been removed; use \"async_query_timeout\" instead"));
|
||||||
known_parameter = false;
|
known_parameter = false;
|
||||||
}
|
}
|
||||||
else if (strcmp(name, "master_reponse_timeout") == 0)
|
else if (strcmp(name, "retry_promote_interval_secs") == 0)
|
||||||
{
|
{
|
||||||
item_list_append(warning_list,
|
item_list_append(warning_list,
|
||||||
_("parameter \"retry_promote_interval_secs\" has been removed; use \"primary_notification_timeout\" instead"));
|
_("parameter \"retry_promote_interval_secs\" has been removed; use \"primary_notification_timeout\" instead"));
|
||||||
|
|||||||
88
contrib/convert-config.pl
Executable file
88
contrib/convert-config.pl
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
|
||||||
|
if (scalar @ARGV < 1) {
|
||||||
|
print qq|Please provide path to the repmgr.conf file as first parameter\n|;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $file = $ARGV[0];
|
||||||
|
|
||||||
|
if (!-e $file) {
|
||||||
|
print qq|Provide file "$file" does not exist\n|;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!-f $file) {
|
||||||
|
print qq|Provide path "$file" does not point to a file\n|;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my @outp = ();
|
||||||
|
my $fh = undef;
|
||||||
|
|
||||||
|
if (!open ($fh, $file)){
|
||||||
|
print qq|Unable to open "$file"\n|;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $data_directory_found = 0;
|
||||||
|
|
||||||
|
while(<$fh>) {
|
||||||
|
my $line = $_;
|
||||||
|
chomp $line;
|
||||||
|
if ($line =~ m|\s*#|) {
|
||||||
|
push @outp, $line;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($line !~ m|\s*(\S+?)\s*=(.+?)$|) {
|
||||||
|
push @outp, $line;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $param = $1;
|
||||||
|
my $value = $2;
|
||||||
|
|
||||||
|
# These parameters can be removed:
|
||||||
|
next if ($param eq 'cluster');
|
||||||
|
|
||||||
|
# These parameters can be renamed:
|
||||||
|
if ($param eq 'node') {
|
||||||
|
push @outp, qq|node_id=${value}|;
|
||||||
|
}
|
||||||
|
elsif ($param eq 'failover') {
|
||||||
|
push @outp, qq|failover_mode=${value}|;
|
||||||
|
}
|
||||||
|
elsif ($param eq 'loglevel') {
|
||||||
|
push @outp, qq|log_level=${value}|;
|
||||||
|
}
|
||||||
|
elsif ($param eq 'logfacility') {
|
||||||
|
push @outp, qq|log_facility=${value}|;
|
||||||
|
}
|
||||||
|
elsif ($param eq 'logfile') {
|
||||||
|
push @outp, qq|log_file=${value}|;
|
||||||
|
}
|
||||||
|
elsif ($param eq 'master_reponse_timeout') {
|
||||||
|
push @outp, qq|async_query_timeout=${value}|;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ($param eq 'data_directory') {
|
||||||
|
$data_directory_found = 1;
|
||||||
|
}
|
||||||
|
push @outp, $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close $fh;
|
||||||
|
|
||||||
|
print join("\n", @outp);
|
||||||
|
print "\n";
|
||||||
|
|
||||||
|
if ($data_directory_found == 0) {
|
||||||
|
print "data_directory=\n";
|
||||||
|
}
|
||||||
|
|
||||||
122
doc/upgrading-from-repmgr3.md
Normal file
122
doc/upgrading-from-repmgr3.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
Upgrading from repmgr 3
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The upgrade process consists of two steps:
|
||||||
|
|
||||||
|
1) converting the repmgr.conf configuration files
|
||||||
|
2) upgrading the repmgr schema.
|
||||||
|
|
||||||
|
Scripts are provided to assist both with converting repmgr.conf
|
||||||
|
and upgrading the schema.
|
||||||
|
|
||||||
|
Converting repmgr.conf configuration files
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
With a completely new repmgr version, we've taken the opportunity
|
||||||
|
to rename some configuration items have had their names changed for
|
||||||
|
clarity and consistency, both between the configuration file and
|
||||||
|
the column names in `repmgr.nodes` (e.g. `node` → `node_id`), and
|
||||||
|
also for consistency with PostgreSQL naming conventions
|
||||||
|
(e.g. `loglevel` → `log_level`).
|
||||||
|
|
||||||
|
Other configuration items have been changed to command line options,
|
||||||
|
and vice-versa, e.g. to avoid hard-coding items such as a a node's
|
||||||
|
upstream ID, which might change oer time.
|
||||||
|
|
||||||
|
`repmgr` will issue a warning about deprecated/altered options.
|
||||||
|
|
||||||
|
|
||||||
|
### Changed parameters
|
||||||
|
|
||||||
|
Following parameters have been added:
|
||||||
|
|
||||||
|
- `data_directory`: this is mandatory and must contain the path
|
||||||
|
to the node's data directory
|
||||||
|
- `monitoring_history`: this replaces the `repmgrd` command line
|
||||||
|
option `--monitoring-history`
|
||||||
|
|
||||||
|
Following parameters have been renamed:
|
||||||
|
|
||||||
|
- `failover` → `failover_mode`
|
||||||
|
- `node` → `node_id`
|
||||||
|
- `loglevel` → `log_level`
|
||||||
|
- `logfacility` → `log_facility`
|
||||||
|
- `logfile` → `log_file`
|
||||||
|
- `master_reponse_timeout` → `async_query_timeout`
|
||||||
|
|
||||||
|
Following parameters have been removed:
|
||||||
|
|
||||||
|
- `cluster` is no longer required and will be ignored.
|
||||||
|
- `upstream_node_id` is replaced by the command-line parameter
|
||||||
|
`--upstream-node-id`
|
||||||
|
|
||||||
|
### Conversion script
|
||||||
|
|
||||||
|
To assist with conversion of `repmgr.conf` files, a Perl script
|
||||||
|
is provided in `contrib/convert-config.pl`. Use like this:
|
||||||
|
|
||||||
|
$ ./convert-config.pl /etc/repmgr.conf
|
||||||
|
node_id=2
|
||||||
|
node_name=node2
|
||||||
|
conninfo=host=localhost dbname=repmgr user=repmgr port=5602
|
||||||
|
pg_ctl_options='-l /tmp/postgres.5602.log'
|
||||||
|
pg_bindir=/home/barwick/devel/builds/HEAD/bin
|
||||||
|
rsync_options=--exclude=postgresql.local.conf --archive
|
||||||
|
log_level=DEBUG
|
||||||
|
pg_basebackup_options=--no-slot
|
||||||
|
data_directory=
|
||||||
|
|
||||||
|
The converted file is printed to `STDOUT` and the original file is not
|
||||||
|
changed.
|
||||||
|
|
||||||
|
Please note that the parameter `data_directory` *must* be provided;
|
||||||
|
if not already present, the conversion script will add an empty
|
||||||
|
placeholder parameter.
|
||||||
|
|
||||||
|
|
||||||
|
Upgrading the repmgr schema
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Ensure `repmgrd` is not running, or any cronjobs which execute the
|
||||||
|
`repmgr` binary.
|
||||||
|
|
||||||
|
Install `repmgr4`; any `repmgr3` packages should be uninstalled
|
||||||
|
(if not automatically installed already).
|
||||||
|
|
||||||
|
### Manually create the repmgr extension
|
||||||
|
|
||||||
|
In the database used by the existing `repmgr` configuration, execute:
|
||||||
|
|
||||||
|
CREATE EXTENSION repmgr FROM unpackaged;
|
||||||
|
|
||||||
|
This will move and convert all objects from the existing schema
|
||||||
|
into the new, standard `repmgr` schema.
|
||||||
|
|
||||||
|
> *NOTE* there must be only one schema matching 'repmgr_%' in the
|
||||||
|
> database, otherwise this step may not work.
|
||||||
|
|
||||||
|
### Re-register each node
|
||||||
|
|
||||||
|
This is necessary to update the `repmgr` metadata with some additional items.
|
||||||
|
|
||||||
|
On the primary node, execute e.g.
|
||||||
|
|
||||||
|
repmgr primary register -f /etc/repmgr.conf --force
|
||||||
|
|
||||||
|
On each standby node, execute e.g.
|
||||||
|
|
||||||
|
repmgr standby register -f /etc/repmgr.conf --force
|
||||||
|
|
||||||
|
Check the data is updated as expected by examining the `repmgr.nodes` table;
|
||||||
|
restart `repmgrd` if required.
|
||||||
|
|
||||||
|
The original `repmgr_$cluster` schema can be dropped at any time.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
> *TIP* If you don't care about any data from the existing `repmgr` installation,
|
||||||
|
> (e.g. the contents of the `events` and `monitoring` tables), the manual
|
||||||
|
> "CREATE EXTENSION" step can be skipped; just re-register each node, starting
|
||||||
|
> with the primary node, and the `repmgr` extension will be automatically created.
|
||||||
|
|
||||||
|
* * *
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
-- \echo Use "CREATE EXTENSION repmgr" to load this file. \quit
|
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
|
||||||
|
|
||||||
-- extract the current schema name
|
-- extract the current schema name
|
||||||
-- NOTE: this assumes there will be only one schema matching 'repmgr_%';
|
-- NOTE: this assumes there will be only one schema matching 'repmgr_%';
|
||||||
@@ -12,18 +12,24 @@ SELECT nspname AS old_schema
|
|||||||
WHERE nspname LIKE 'repmgr_%'
|
WHERE nspname LIKE 'repmgr_%'
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
DO $$
|
-- move old objects into new schema
|
||||||
|
DO $repmgr$
|
||||||
DECLARE
|
DECLARE
|
||||||
old_schema TEXT;
|
schema TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
old_schema := SELECT old_schema FROM repmgr_old_schema;
|
SELECT old_schema FROM repmgr_old_schema
|
||||||
ALTER SCHEMA RENAME TO repmgr;
|
INTO schema;
|
||||||
END$$;
|
EXECUTE format('ALTER TABLE %I.repl_nodes SET SCHEMA repmgr', schema);
|
||||||
|
EXECUTE format('ALTER TABLE %I.repl_events SET SCHEMA repmgr', schema);
|
||||||
|
EXECUTE format('ALTER TABLE %I.repl_monitor SET SCHEMA repmgr', schema);
|
||||||
|
EXECUTE format('ALTER VIEW %I.repl_show_nodes SET SCHEMA repmgr', schema);
|
||||||
|
EXECUTE format('ALTER VIEW %I.repl_status SET SCHEMA repmgr', schema);
|
||||||
|
END$repmgr$;
|
||||||
|
|
||||||
-- convert "repmgr_$cluster.repl_nodes" to "repmgr.nodes"
|
-- convert "repmgr_$cluster.repl_nodes" to "repmgr.nodes"
|
||||||
CREATE TABLE nodes (
|
CREATE TABLE nodes (
|
||||||
node_id INTEGER PRIMARY KEY,
|
node_id INTEGER PRIMARY KEY,
|
||||||
upstream_node_id INTEGER NULL REFERENCES nodes (node_id) DEFERRABLE,
|
upstream_node_id INTEGER NULL REFERENCES repmgr.nodes (node_id) DEFERRABLE,
|
||||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
node_name TEXT NOT NULL,
|
node_name TEXT NOT NULL,
|
||||||
type TEXT NOT NULL CHECK (type IN('primary','standby','bdr')),
|
type TEXT NOT NULL CHECK (type IN('primary','standby','bdr')),
|
||||||
@@ -44,11 +50,11 @@ SELECT id, upstream_node_id, active, name,
|
|||||||
ORDER BY id;
|
ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
-- convert "repmgr_$cluster.repl_event" to "repmgr.event"
|
-- convert "repmgr_$cluster.repl_event" to "event"
|
||||||
|
|
||||||
ALTER TABLE repl_events RENAME TO event;
|
ALTER TABLE repl_events RENAME TO events;
|
||||||
|
|
||||||
-- convert "repmgr_$cluster.repl_monitor" to "repmgr.monitor"
|
-- convert "repmgr_$cluster.repl_monitor" to "monitor"
|
||||||
|
|
||||||
ALTER TABLE repl_monitor RENAME TO monitor;
|
ALTER TABLE repl_monitor RENAME TO monitor;
|
||||||
|
|
||||||
@@ -125,3 +131,5 @@ CREATE FUNCTION unset_bdr_failover_handler()
|
|||||||
AS '$libdir/repmgr', 'unset_bdr_failover_handler'
|
AS '$libdir/repmgr', 'unset_bdr_failover_handler'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
|
-- remove temporary table
|
||||||
|
DROP TABLE repmgr_old_schema;
|
||||||
|
|||||||
@@ -571,6 +571,7 @@ check_barman_config(void)
|
|||||||
* Event(s):
|
* Event(s):
|
||||||
* - standby_register
|
* - standby_register
|
||||||
*/
|
*/
|
||||||
|
// XXX check --upstream-node-id works when re-registering
|
||||||
|
|
||||||
void
|
void
|
||||||
do_standby_register(void)
|
do_standby_register(void)
|
||||||
|
|||||||
@@ -3034,11 +3034,16 @@ init_node_record(t_node_info *node_record)
|
|||||||
node_record->priority = config_file_options.priority;
|
node_record->priority = config_file_options.priority;
|
||||||
node_record->active = true;
|
node_record->active = true;
|
||||||
|
|
||||||
strncpy(node_record->location, config_file_options.location, MAXLEN);
|
|
||||||
|
if (config_file_options.location[0] != '\0')
|
||||||
|
strncpy(node_record->location, config_file_options.location, MAXLEN);
|
||||||
|
else
|
||||||
|
strncpy(node_record->location, "default", MAXLEN);
|
||||||
|
|
||||||
|
|
||||||
strncpy(node_record->node_name, config_file_options.node_name, MAXLEN);
|
strncpy(node_record->node_name, config_file_options.node_name, MAXLEN);
|
||||||
strncpy(node_record->conninfo, config_file_options.conninfo, MAXLEN);
|
strncpy(node_record->conninfo, config_file_options.conninfo, MAXLEN);
|
||||||
strncpy(node_record->config_file, config_file_path, MAXLEN);
|
strncpy(node_record->config_file, config_file_path, MAXPGPATH);
|
||||||
|
|
||||||
if (config_file_options.replication_user[0] != '\0')
|
if (config_file_options.replication_user[0] != '\0')
|
||||||
{
|
{
|
||||||
@@ -3048,11 +3053,16 @@ init_node_record(t_node_info *node_record)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* use the "user" value from "conninfo" */
|
/* use the "user" value from "conninfo" */
|
||||||
(void)get_conninfo_value(config_file_options.conninfo, "user", node_record->repluser);
|
char repluser[MAXLEN] = "";
|
||||||
|
|
||||||
|
(void)get_conninfo_value(config_file_options.conninfo, "user", repluser);
|
||||||
|
strncpy(node_record->repluser, repluser, NAMEDATALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_file_options.use_replication_slots == true)
|
if (config_file_options.use_replication_slots == true)
|
||||||
{
|
{
|
||||||
maxlen_snprintf(node_record->slot_name, "repmgr_slot_%i", config_file_options.node_id);
|
maxlen_snprintf(node_record->slot_name, "repmgr_slot_%i", config_file_options.node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user