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:
Ian Barwick
2017-08-17 23:37:31 +09:00
parent 5e019a65e7
commit 594e9e5007
7 changed files with 252 additions and 22 deletions

View File

@@ -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,
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
and clarity e.g. `node` => `node_id`. `repmgr` will issue a warning
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.
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
--------
@@ -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`
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
PostgreSQL, and we recommend that they also run the same minor version.

View File

@@ -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"));
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,
_("parameter \"retry_promote_interval_secs\" has been removed; use \"primary_notification_timeout\" instead"));

88
contrib/convert-config.pl Executable file
View 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";
}

View 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.
* * *

View File

@@ -1,5 +1,5 @@
-- 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
-- NOTE: this assumes there will be only one schema matching 'repmgr_%';
@@ -12,18 +12,24 @@ SELECT nspname AS old_schema
WHERE nspname LIKE 'repmgr_%'
LIMIT 1;
DO $$
-- move old objects into new schema
DO $repmgr$
DECLARE
old_schema TEXT;
schema TEXT;
BEGIN
old_schema := SELECT old_schema FROM repmgr_old_schema;
ALTER SCHEMA RENAME TO repmgr;
END$$;
SELECT old_schema FROM repmgr_old_schema
INTO schema;
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"
CREATE TABLE nodes (
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,
node_name TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN('primary','standby','bdr')),
@@ -44,11 +50,11 @@ SELECT id, upstream_node_id, active, name,
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;
@@ -125,3 +131,5 @@ CREATE FUNCTION unset_bdr_failover_handler()
AS '$libdir/repmgr', 'unset_bdr_failover_handler'
LANGUAGE C STRICT;
-- remove temporary table
DROP TABLE repmgr_old_schema;

View File

@@ -571,6 +571,7 @@ check_barman_config(void)
* Event(s):
* - standby_register
*/
// XXX check --upstream-node-id works when re-registering
void
do_standby_register(void)

View File

@@ -3034,11 +3034,16 @@ init_node_record(t_node_info *node_record)
node_record->priority = config_file_options.priority;
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->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')
{
@@ -3048,11 +3053,16 @@ init_node_record(t_node_info *node_record)
else
{
/* 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)
{
maxlen_snprintf(node_record->slot_name, "repmgr_slot_%i", config_file_options.node_id);
}
}