Compare commits

...

21 Commits

Author SHA1 Message Date
Ian Barwick
48099e9c5f Clean up whitespace 2015-07-22 16:18:04 +09:00
Marco Nenciarini
e7ca8c369f Allow repmgr to be compiled with a libpq newer than PostgreSQL
Fixes #44
2015-04-29 17:57:51 +02:00
Ian Barwick
782fae6239 Fix typo 2015-04-20 08:31:37 +09:00
Ian Barwick
a492745db1 Update version number for minor release 2.0.3 2015-04-16 11:14:04 +09:00
Ian Barwick
9ac066db51 Add 2.0.3 HISTORY file items 2015-04-16 11:01:31 +09:00
Ian Barwick
20db2f52b1 Clean up indentation, trailing whitespace 2015-04-16 08:47:05 +09:00
Ian Barwick
341831ad69 Change '-X/--fast-checkpoint' option to '-c/--fast-checkpoint'
Make consistent with same option added in 3.0. '-c' is similar to
pg_basebackup's '-c, --checkpoint=fast|spread' option; we may also
want to use -X for something more pg_xlog-related in future.

Also add missing 'break' statement
2015-04-16 08:24:29 +09:00
Ian Barwick
e8bc5521a5 Add option "--initdb-no-pwprompt"
Previously repmgr passed the -W flag to initdb, which forced
manual input of a password; this option removes the -W flag
to make repetitive testing easier.

Conflicts:
	repmgr.c
	repmgr.h
2015-04-16 07:58:41 +09:00
Ian Barwick
1d9aacfed9 Add -S/--superuser option for witness database creation
Previously the witness database creation code was hard-coding the
username 'postgres' when accessing the previously initialised database.
However initdb was not passed any explicit username, meaning the
default database superuser name was the same as the user running
repmgr.

With this patch, a superuser user name (default: postgres) will
be passed to initdb.

Per report by eggyknap [1]

[1] https://github.com/2ndQuadrant/repmgr/issues/38

Conflicts:
	repmgr.c
	repmgr.h
2015-04-15 08:10:58 +09:00
Ian Barwick
e39ec70ef0 Prevent compiler warnings with 9.0
PG_PRINTF_ATTRIBUTE was introduced with 9.1.
2015-04-14 20:21:54 +09:00
Christoph Monech-Tegeder
196585c78a optional fast checkpointing
commandline -X/--fast-checkpoint
2015-04-08 23:09:12 +02:00
Martín Marqués
79728ba6dd Updated RHEL files. 2015-03-30 11:07:11 -03:00
Martín Marqués
c4a47c467f Add check for wal_level = logical so we don't fail on 9.4
On 9.4 we have logical decoding, which introduced a new wal_level called
logical. This level includes all the previous ones, so you can run a
hot_standby if wal_level = logical, because the relevant information for
hot_standby will be there, plus other information needed for logical
decoding.

We fix this be adding a second check when wal_level is not hot_standby.
2015-03-30 10:47:17 -03:00
Ian Barwick
36e5944b2c Add items for future 2.0.3 release 2015-03-27 11:12:11 +09:00
John Galt
097bbdebfd Fixed typo 2015-03-24 10:47:48 +09:00
Germ van Ek
4fa75afa26 Added postgresql-9.4 to debian control file 2015-03-24 10:03:38 +09:00
Ian Barwick
0aae96008f Parse config file before daemonizing
Daemonizing changes the current working directory to '/',
which breaks configuration file parsing if the file is in
the previous working directory and provided without an
explicit path.

Also it makes general sense to parse the configuration file
before daemonizing.
2015-03-09 08:26:59 +09:00
Ian Barwick
2349e182d2 Prevent trim() from segfaulting on an empty string 2015-03-07 23:48:14 +09:00
Ian Barwick
03a8f2eaba Clarify repmgr.conf usage 2015-02-27 10:02:30 +09:00
Ian Barwick
b6a263a40e Update QUICKSTART.md 2015-02-24 08:52:36 +09:00
Magnus Hagander
81050899e8 Fix markup
This was broken in commit  8faf41dd94,
most likely because of a runaway search/replace.
2015-02-24 08:49:55 +09:00
16 changed files with 329 additions and 203 deletions

View File

@@ -1,3 +1,8 @@
2.0.3 2015-04-16
Add -S/--superuser option for witness database creation (Ian)
Add -c/--fast-checkpoint option for cloning (Christoph)
Add option "--initdb-no-pwprompt" (Ian)
2.0.2 2015-02-17
Add "--checksum" in rsync when using "--force" (Jaime)
Use createdb/createuser instead of psql (Jaime)

View File

@@ -1,7 +1,7 @@
repmgr: Quickstart guide
========================
repmgr is an open-source tool suite for mananaging replication and failover
`repmgr` is an open-source tool suite for mananaging replication and failover
among multiple PostgreSQL server nodes. It enhances PostgreSQL's built-in
hot-standby capabilities with a set of administration tools for monitoring
replication, setting up standby servers and performing failover/switchover
@@ -14,14 +14,14 @@ covering setup on a variety of different systems, see the README.rst file.
Conceptual Overview
-------------------
repmgr provides two binaries:
`repmgr` provides two binaries:
- `repmgr`: a command-line client to manage replication and repmgr configuration
- `repmgr`: a command-line client to manage replication and `repmgr` configuration
- `repmgrd`: an optional daemon process which runs on standby nodes to monitor
replication and node status
Each PostgreSQL node requires a repmgr configuration file; additionally
it must be "registered" using the repmgr command-line client. repmgr stores
Each PostgreSQL node requires a `repmgr.conf` configuration file; additionally
it must be "registered" using the `repmgr` command-line client. `repmgr` stores
information about managed nodes in a custom schema on the node's current master
database.
@@ -29,33 +29,33 @@ database.
Requirements
------------
repmgr works with PostgreSQL 9.0 and later. All server nodes must be running the
`repmgr` works with PostgreSQL 9.0 and later. All server nodes must be running the
same PostgreSQL major version, and preferably should be running the same minor
version.
repmgr will work on any Linux or UNIX-like environment capable of running
PostgreSQL. rsync must also be installed.
`repmgr` will work on any Linux or UNIX-like environment capable of running
PostgreSQL. `rsync` must also be installed.
Installation
------------
repmgr must be installed on each PostgreSQL server node.
`repmgr` must be installed on each PostgreSQL server node.
* Packages
- RPM packages for RedHat-based distributions are available from PGDG
- Debian/Ubuntu provide .deb packages.
It is also possible to build .deb packages directly from the repmgr source;
It is also possible to build .deb packages directly from the `repmgr` source;
see README.rst for further details.
* Source installation
- repmgr source code is hosted at github (https://github.com/2ndQuadrant/repmgr);
- `repmgr` source code is hosted at github (https://github.com/2ndQuadrant/repmgr);
tar.gz files can be downloaded from https://github.com/2ndQuadrant/repmgr/releases .
repmgr can be built easily using PGXS:
`repmgr` can be built easily using PGXS:
sudo make USE_PGXS=1 install
sudo make USE_PGXS=1 install
Configuration
@@ -64,42 +64,42 @@ Configuration
### Server configuration
Password-less SSH logins must be enabled for the database system user (typically `postgres`)
between all server nodes to enable repmgr to copy required files.
between all server nodes to enable `repmgr` to copy required files.
### PostgreSQL configuration
The master PostgreSQL node needs to be configured for replication with the
following settings:
wal_level = 'hot_standby' # minimal, archive, hot_standby, or logical
archive_mode = on # allows archiving to be done
archive_command = 'cd .' # command to use to archive a logfile segment
max_wal_senders = 10 # max number of walsender processes
wal_keep_segments = 5000 # in logfile segments, 16MB each; 0 disables
hot_standby = on # "on" allows queries during recovery
wal_level = 'hot_standby' # minimal, archive, hot_standby, or logical
archive_mode = on # allows archiving to be done
archive_command = 'cd .' # command to use to archive a logfile segment
max_wal_senders = 10 # max number of walsender processes
wal_keep_segments = 5000 # in logfile segments, 16MB each; 0 disables
hot_standby = on # "on" allows queries during recovery
Note that repmgr expects a default of 5000 wal_keep_segments, although this
Note that `repmgr` expects a default of 5000 wal_keep_segments, although this
value can be overridden when executing the `repmgr` client.
Additionally, repmgr requires a dedicated PostgreSQL superuser account
and a database in which to store monitoring and replication data. The repmgr
Additionally, `repmgr` requires a dedicated PostgreSQL superuser account
and a database in which to store monitoring and replication data. The `repmgr`
user account will also be used for replication connections from the standby,
so a seperate replication user with the `REPLICATION` privilege is not required.
The database can in principle be any database, including the default `postgres`
one, however it's probably advisable to create a dedicated database for repmgr
one, however it's probably advisable to create a dedicated database for `repmgr`
usage.
### repmgr configuration
Each PostgreSQL node requires a repmgr configuration file containing
Each PostgreSQL node requires a `repmgr.conf` configuration file containing
identification and database connection information:
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
* `cluster`: common name for the replication cluster; this must be the same on all nodes
* `node`: a unique, abitrary integer identifier
@@ -110,12 +110,15 @@ identification and database connection information:
resolvable by all nodes on the cluster.
* `pg_bindir`: (optional) location of PostgreSQL binaries, if not in the default $PATH
Note that the configuration file should not be stored inside the PostgreSQL
data directory.
Note that the configuration file should *not* be stored inside the PostgreSQL
data directory. The configuration file can be specified with the
`-f, --config-file=PATH` option and can have any arbitrary name. If no
configuration file is specified, `repmgr` will search for `repmgr.conf`
in the current working directory.
Each node configuration needs to be registered with repmgr, either using the
repmgr command line tool, or the repmgrd daemon; for details see below. Details
about each node are inserted into the repmgr database (for details see below).
Each node configuration needs to be registered with `repmgr`, either using the
`repmgr` command line tool, or the `repmgrd` daemon; for details see below. Details
about each node are inserted into the `repmgr` database (for details see below).
Replication setup and monitoring
@@ -141,9 +144,9 @@ Master setup
CREATE DATABASE repmgr_db OWNER repmgr_usr;
```
- configure postgresql.conf for replication (see above)
- configure `postgresql.conf` for replication (see above)
- update pg_hba.conf, e.g.:
- update `pg_hba.conf`, e.g.:
```
host repmgr_db repmgr_usr 192.168.1.0/24 trust
@@ -151,45 +154,47 @@ Master setup
```
Restart the PostgreSQL server after making these changes.
2. Create the `repmgr` configuration file:
2. Create the repmgr configuration file:
$ cat $HOME/repmgr/repmgr.conf
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
$ cat $HOME/repmgr/repmgr.conf
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
(For an annotated `repmgr.conf` file, see `repmgr.conf.sample` in the
repository's root directory).
3. Register the master node with repmgr:
3. Register the master node with `repmgr`:
$ repmgr -f $HOME/repmgr/repmgr.conf --verbose master register
[2014-07-04 10:43:42] [INFO] repmgr mgr connecting to master database
[2014-07-04 10:43:42] [INFO] repmgr connected to master, checking its state
[2014-07-04 10:43:42] [INFO] master register: creating database objects inside the repmgr_test schema
[2014-07-04 10:43:43] [NOTICE] Master node correctly registered for cluster test with id 1 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
$ repmgr -f $HOME/repmgr/repmgr.conf --verbose master register
[2014-07-04 10:43:42] [INFO] repmgr mgr connecting to master database
[2014-07-04 10:43:42] [INFO] repmgr connected to master, checking its state
[2014-07-04 10:43:42] [INFO] master register: creating database objects inside the repmgr_test schema
[2014-07-04 10:43:43] [NOTICE] Master node correctly registered for cluster test with id 1 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
Slave/standby setup
-------------------
1. Use repmgr to clone the master:
1. Use `repmgr` to clone the master:
$ repmgr -f $HOME/repmgr/repmgr.conf -D $PGDATA -d repmgr_db -U repmgr_usr -R postgres --verbose standby clone 192.168.1.2
Opening configuration file: ./repmgr.conf
[2014-07-04 10:49:00] [ERROR] Did not find the configuration file './repmgr.conf', continuing
[2014-07-04 10:49:00] [INFO] repmgr connecting to master database
[2014-07-04 10:49:00] [INFO] repmgr connected to master, checking its state
[2014-07-04 10:49:00] [INFO] Successfully connected to primary. Current installation size is 1807 MB
[2014-07-04 10:49:00] [NOTICE] Starting backup...
[2014-07-04 10:49:00] [INFO] creating directory "/path/to/data/"...
(...)
[2014-07-04 10:53:19] [NOTICE] Finishing backup...
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
[2014-07-04 10:53:21] [INFO] repmgr requires primary to keep WAL files 0000000100000000000000AD until at least 0000000100000000000000AD
[2014-07-04 10:53:21] [NOTICE] repmgr standby clone complete
[2014-07-04 10:53:21] [NOTICE] HINT: You can now start your postgresql server
[2014-07-04 10:53:21] [NOTICE] for example : /etc/init.d/postgresql start
$ repmgr -D $PGDATA -d repmgr_db -U repmgr_usr -R postgres --verbose standby clone 192.168.1.2
Opening configuration file: ./repmgr.conf
[2014-07-04 10:49:00] [ERROR] Did not find the configuration file './repmgr.conf', continuing
[2014-07-04 10:49:00] [INFO] repmgr connecting to master database
[2014-07-04 10:49:00] [INFO] repmgr connected to master, checking its state
[2014-07-04 10:49:00] [INFO] Successfully connected to primary. Current installation size is 1807 MB
[2014-07-04 10:49:00] [NOTICE] Starting backup...
[2014-07-04 10:49:00] [INFO] creating directory "/path/to/data/"...
(...)
[2014-07-04 10:53:19] [NOTICE] Finishing backup...
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
[2014-07-04 10:53:21] [INFO] repmgr requires primary to keep WAL files 0000000100000000000000AD until at least 0000000100000000000000AD
[2014-07-04 10:53:21] [NOTICE] repmgr standby clone complete
[2014-07-04 10:53:21] [NOTICE] HINT: You can now start your postgresql server
[2014-07-04 10:53:21] [NOTICE] for example : /etc/init.d/postgresql start
-R is the database system user on the master node. At this point it does not matter
if the `repmgr.conf` file is not found.
@@ -201,28 +206,28 @@ Slave/standby setup
2. Start the PostgreSQL server
3. Create the repmgr configuration file:
3. Create the `repmgr` configuration file:
$ cat $HOME/repmgr/repmgr.conf
cluster=test
node=2
node_name=node2
conninfo='host=repmgr_node2 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
$ cat $HOME/repmgr/repmgr.conf
cluster=test
node=2
node_name=node2
conninfo='host=repmgr_node2 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
4. Register the master node with repmgr:
4. Register the master node with `repmgr`:
$ repmgr -f $HOME/repmgr/repmgr.conf --verbose standby register
Opening configuration file: /path/to/repmgr/repmgr.conf
[2014-07-04 11:48:13] [INFO] repmgr connecting to standby database
[2014-07-04 11:48:13] [INFO] repmgr connected to standby, checking its state
[2014-07-04 11:48:13] [INFO] repmgr connecting to master database
[2014-07-04 11:48:13] [INFO] finding node list for cluster 'test'
[2014-07-04 11:48:13] [INFO] checking role of cluster node 'host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
[2014-07-04 11:48:13] [INFO] repmgr connected to master, checking its state
[2014-07-04 11:48:13] [INFO] repmgr registering the standby
[2014-07-04 11:48:13] [INFO] repmgr registering the standby complete
[2014-07-04 11:48:13] [NOTICE] Standby node correctly registered for cluster test with id 2 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
$ repmgr -f $HOME/repmgr/repmgr.conf --verbose standby register
Opening configuration file: /path/to/repmgr/repmgr.conf
[2014-07-04 11:48:13] [INFO] repmgr connecting to standby database
[2014-07-04 11:48:13] [INFO] repmgr connected to standby, checking its state
[2014-07-04 11:48:13] [INFO] repmgr connecting to master database
[2014-07-04 11:48:13] [INFO] finding node list for cluster 'test'
[2014-07-04 11:48:13] [INFO] checking role of cluster node 'host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
[2014-07-04 11:48:13] [INFO] repmgr connected to master, checking its state
[2014-07-04 11:48:13] [INFO] repmgr registering the standby
[2014-07-04 11:48:13] [INFO] repmgr registering the standby complete
[2014-07-04 11:48:13] [NOTICE] Standby node correctly registered for cluster test with id 2 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
Monitoring
----------
@@ -259,8 +264,8 @@ To promote a standby to master, on the standby execute e.g.:
repmgr -f $HOME/repmgr/repmgr.conf --verbose standby promote
repmgr will attempt to connect to the current master to verify that it
is not available (if it is, repmgr will not promote the standby).
`repmgr` will attempt to connect to the current master to verify that it
is not available (if it is, `repmgr` will not promote the standby).
Other standby servers need to be told to follow the new master with:
@@ -273,7 +278,7 @@ automated failover.
repmgr database schema
----------------------
repmgr creates a small schema for its own use in the database specified in
`repmgr` creates a small schema for its own use in the database specified in
each node's conninfo configuration parameter. This database can in principle
be any database. The schema name is the global `cluster` name prefixed
with `repmgr_`, so for the example setup above the schema name is
@@ -290,3 +295,10 @@ and one view, `repl_status`, which summarizes the latest monitoring information
for each node.
Further reading
---------------
* http://blog.2ndquadrant.com/announcing-repmgr-2-0/
* http://blog.2ndquadrant.com/managing-useful-clusters-repmgr/
* http://blog.2ndquadrant.com/easier_postgresql_90_clusters/

View File

@@ -427,7 +427,7 @@ system you already have superuser access to.
Clearing the PostgreSQL installation on the Standby
---------------------------------------------------
To setup a new streaming replica, startin by removing any PostgreSQL
To setup a new streaming replica, start by removing any PostgreSQL
installation on the existing standby nodes.
* Stop any server on "node2" and "node3". You can confirm the database

View File

@@ -4,7 +4,7 @@ Version: 2.0
Release: 2
License: GPLv3
Group: System Environment/Daemons
URL: http://repmgr.org
URL: http://repmgr.org
Packager: Nathan Van Overloop <nathan.van.overloop@nexperteam.be>
Vendor: 2ndQuadrant Limited
Distribution: centos
@@ -32,7 +32,7 @@ export PATH=$PATH:/usr/pgsql-9.3/bin/
%clean
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
%files
%defattr(-,root,root)
@@ -45,7 +45,7 @@ export PATH=$PATH:/usr/pgsql-9.3/bin/
/usr/pgsql-9.3/share/contrib/repmgr_funcs.sql
/usr/pgsql-9.3/share/contrib/uninstall_repmgr.sql
/usr/pgsql-9.3/share/contrib/uninstall_repmgr_funcs.sql
%attr(0755,root,root)/etc/init.d/repmgrd
%attr(0755,root,root)/etc/init.d/repmgrd
%attr(0644,root,root)/etc/sysconfig/repmgrd
%attr(0644,root,root)/etc/repmgr/repmgr.conf.sample
@@ -54,4 +54,3 @@ export PATH=$PATH:/usr/pgsql-9.3/bin/
- fix witness creation to create db and user if needed
* Fri Apr 04 2014 Nathan Van Overloop <nathan.van.overloop@nexperteam.be> 2.0.1
- initial build for RHEL6

View File

@@ -1,89 +1,114 @@
#!/bin/bash
#!/bin/sh
#
# repmgrd Start up the repmgrd daemon
# repmrgd (replication manager daemon)
#
# chkconfig: - 75 16
# description: repmgrd is the repliation manager daemon \
# The repmgrd replication management and monitoring daemon for PostgreSQL.
### BEGIN INIT INFO
# Provides: repmgrd
# Required-Start: $local_fs $remote_fs $network $syslog postgresql
# Required-Stop: $local_fs $remote_fs $network $syslog postgresql
# Should-Start: $syslog postgresql-9.3
# Should-Stop: $syslog postgresql-9.3
# Short-Description: start and stop repmrgd
# Description: Enable repmgrd replication management and monitoring daemon for PostgreSQL
# this is used to monitor a postgresql cluster.
### END INIT INFO
# chkconfig: - 75 16
# description: Enable repmgrd replication management and monitoring daemon for PostgreSQL
# processname: repmgrd
# pidfile="/var/run/${NAME}.pid"
# Source function library.
. /etc/init.d/functions
INITD=/etc/rc.d/init.d
. $INITD/functions
# Source networking configuration.
# Get function listing for cross-distribution logic.
TYPESET=`typeset -f|grep "declare"`
# Get network config.
. /etc/sysconfig/network
prog=repmgrd
REPMGRD_ENABLED=yes
DESC="PostgreSQL replication management and monitoring daemon"
NAME=repmgrd
REPMGRD_ENABLED=no
REPMGRD_OPTS=
REPMGRD_USER=postgres
DAEMONIZE="-d"
REPMGRD_BIN=/usr/pgsql-9.3/bin/repmgrd
REPMGRD_PIDFILE=/var/run/repmgrd.pid
REPMGRD_LOCK=/var/lock/subsys/${NAME}
REPMGRD_LOG=/var/lib/pgsql/9.3/data/pg_log/repmgrd.log
# pull in sysconfig settings
[ -f /etc/sysconfig/repmgrd ] && . /etc/sysconfig/repmgrd
# Read configuration variable file if it is present
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
LOCKFILE=/var/lock/subsys/$prog
RETVAL=0
# For SELinux we need to use 'runuser' not 'su'
if [ -x /sbin/runuser ]
then
SU=runuser
else
SU=su
fi
test -x $REPMGRD_BIN || exit 0
case "$REPMGRD_ENABLED" in
[Yy]*)
#nothing to do here
break
;;
*)
exit 2
exit 0
;;
esac
if [ -z "$REPMGRD_OPTS" ]
if [ -z "${REPMGRD_OPTS}" ]
then
echo "Not starting $prog, REPMGRD_OPTS not set in /etc/sysconfig/$prog"
exit 2
echo "Not starting ${NAME}, REPMGRD_OPTS not set in /etc/sysconfig/${NAME}"
exit 0
fi
start() {
[ "$EUID" != "0" ] && exit 4
[ "$NETWORKING" = "no" ] && exit 1
start()
{
REPMGRD_START=$"Starting ${NAME} service: "
# Start daemons.
echo -n $"Starting $prog: "
daemon --user $REPMGRD_USER $prog $DAEMONIZE $REPMGRD_OPTS
RETVAL=$?
# Make sure startup-time log file is valid
if [ ! -e "${REPMGRD_LOG}" -a ! -h "${REPMGRD_LOG}" ]
then
touch "${REPMGRD_LOG}" || exit 1
chown ${REPMGRD_USER}:postgres "${REPMGRD_LOG}"
chmod go-rwx "${REPMGRD_LOG}"
[ -x /sbin/restorecon ] && /sbin/restorecon "${REPMGRD_LOG}"
fi
echo -n "${REPMGRD_START}"
$SU -l $REPMGRD_USER -c "${REPMGRD_BIN} ${REPMGRD_OPTS} -p ${REPMGRD_PIDFILE} &" >> "${REPMGRD_LOG}" 2>&1 < /dev/null
sleep 2
pid=`head -n 1 "${REPMGRD_PIDFILE}" 2>/dev/null`
if [ "x${pid}" != "x" ]
then
success "${REPMGRD_START}"
touch "${REPMGRD_LOCK}"
echo $pid > "${REPMGRD_PIDFILE}"
echo
[ $RETVAL -eq 0 ] && touch $LOCKFILE
return $RETVAL
else
failure "${REPMGRD_START}"
echo
script_result=1
fi
}
stop() {
[ "$EUID" != "0" ] && exit 4
echo -n $"Shutting down $prog: "
killproc $prog
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
return $RETVAL
}
status() {
if [ -f "$LOCKFILE" ]; then
echo "$prog is running"
stop()
{
echo -n $"Stopping ${NAME} service: "
if [ -e "${REPMGRD_LOCK}" ]
then
killproc ${NAME}
ret=$?
if [ $ret -eq 0 ]
then
echo_success
rm -f "${REPMGRD_PIDFILE}"
rm -f "${REPMGRD_LOCK}"
else
RETVAL=3
echo "$prog is stopped"
echo_failure
script_result=1
fi
return $RETVAL
else
# not running; per LSB standards this is "ok"
echo_success
fi
echo
}
# See how we were called.
case "$1" in
start)
@@ -93,22 +118,16 @@ case "$1" in
stop
;;
status)
status $prog
status -p $REPMGRD_PIDFILE $NAME
script_result=$?
;;
restart|force-reload)
restart)
stop
start
;;
try-restart|condrestart)
if status $prog > /dev/null; then
stop
start
fi
;;
reload)
exit 3
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart|try-restart|force-reload}"
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esac
exit $script_result

View File

@@ -1,4 +1,21 @@
#default sysconfig file for repmrgd
#custom overrides can be placed here
# default settings for repmgrd. This file is source by /bin/sh from
# /etc/init.d/repmgrd
REPMGRD_OPTS="-f /etc/repmgr/repmgr.conf"
# disable repmgrd by default so it won't get started upon installation
# valid values: yes/no
REPMGRD_ENABLED=no
# Options for repmgrd (required)
#REPMGRD_OPTS="--verbose -d -f /var/lib/pgsql/repmgr/repmgr.conf"
# User to run repmgrd as
#REPMGRD_USER=postgres
# repmgrd binary
#REPMGRD_BIN=/usr/bin/repmgr
# pid file
#REPMGRD_PIDFILE=/var/lib/pgsql/repmgr/repmgrd.pid
# log file
#REPMGRD_LOG=/var/lib/pgsql/repmgr/repmgrd.log

View File

@@ -25,7 +25,8 @@
#include <string.h>
/* NB: postgres_fe must be included BEFORE check_dir */
#include "postgres_fe.h"
#include <libpq-fe.h>
#include <postgres_fe.h>
#include "check_dir.h"
#include "strutil.h"

View File

@@ -185,6 +185,10 @@ trim(char *s)
char *s1 = s,
*s2 = &s[strlen(s) - 1];
/* If string is empty, no action needed */
if(s2 < s1)
return s;
/* Trim and delimit right side */
while ((isspace(*s2)) && (s2 >= s1))
--s2;

View File

@@ -3,7 +3,7 @@ Version: 2.0beta2
Section: database
Priority: optional
Architecture: all
Depends: rsync, postgresql-9.0 | postgresql-9.1 | postgresql-9.2 | postgresql-9.3
Depends: rsync, postgresql-9.0 | postgresql-9.1 | postgresql-9.2 | postgresql-9.3 | postgresql-9.4
Maintainer: Jaime Casanova <jaime@2ndQuadrant.com>
Description: PostgreSQL replication setup, magament and monitoring
has two main executables

6
log.h
View File

@@ -25,9 +25,15 @@
#define REPMGR_SYSLOG 1
#define REPMGR_STDERR 2
#if (PG_VERSION_NUM >= 90100)
void
stderr_log_with_level(const char *level_name, int level, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
#else
void
stderr_log_with_level(const char *level_name, int level, const char *fmt,...)
__attribute__((format(printf, 3, 4)));
#endif
/* Standard error logging */
#define stderr_log_debug(...) stderr_log_with_level("DEBUG", LOG_DEBUG, __VA_ARGS__)

View File

@@ -100,6 +100,7 @@ main(int argc, char **argv)
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
{"superuser", required_argument, NULL, 'S'},
{"dest-dir", required_argument, NULL, 'D'},
{"local-port", required_argument, NULL, 'l'},
{"config-file", required_argument, NULL, 'f'},
@@ -110,6 +111,8 @@ main(int argc, char **argv)
{"wait", no_argument, NULL, 'W'},
{"ignore-rsync-warning", no_argument, NULL, 'I'},
{"verbose", no_argument, NULL, 'v'},
{"fast-checkpoint", no_argument, NULL, 'c'},
{"initdb-no-pwprompt", no_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
@@ -134,7 +137,7 @@ main(int argc, char **argv)
}
while ((c = getopt_long(argc, argv, "d:h:p:U:D:l:f:R:w:k:FWIv", long_options,
while ((c = getopt_long(argc, argv, "d:h:p:U:S:D:l:f:R:w:k:FWIvc", long_options,
&optindex)) != -1)
{
switch (c)
@@ -152,6 +155,9 @@ main(int argc, char **argv)
case 'U':
strncpy(runtime_options.username, optarg, MAXLEN);
break;
case 'S':
strncpy(runtime_options.superuser, optarg, MAXLEN);
break;
case 'D':
strncpy(runtime_options.dest_dir, optarg, MAXFILENAME);
break;
@@ -187,6 +193,12 @@ main(int argc, char **argv)
case 'v':
runtime_options.verbose = true;
break;
case 'c':
runtime_options.fast_checkpoint = true;
break;
case 1:
runtime_options.initdb_no_pwprompt = true;
break;
default:
usage();
exit(ERR_BAD_CONFIG);
@@ -812,7 +824,7 @@ do_standby_clone(void)
int r = 0,
retval = SUCCESS;
int i,
int i,j,
is_standby_retval;
bool flag_success = false;
bool test_mode = false;
@@ -890,11 +902,30 @@ do_standby_clone(void)
i = guc_set(conn, "wal_level", "=", "hot_standby");
if (i == 0 || i == -1)
{
PQfinish(conn);
if (i == 0)
log_err(_("%s needs parameter 'wal_level' to be set to 'hot_standby'\n"),
progname);
exit(ERR_BAD_CONFIG);
{
/* We could be using PG 9.4 with log_level logical, which is good enough for
hot standby replication.
We should check if the wal_level is set to that value, in which case we are
good to proceed.
No need to check if we are in 9.4 first, as the query used in guc_set will just
return zero rows if on < 9.4, and so will work anyway.
*/
j = guc_set(conn, "wal_level", "=", "logical");
if (j == 0 || j == -1)
{
PQfinish(conn);
if (j == 0)
log_err(_("%s needs parameter 'wal_level' to be set to at least 'hot_standby'\n"),
progname);
exit(ERR_BAD_CONFIG);
}
}
else if (i == -1)
{
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
}
i = guc_set_typed(conn, "wal_keep_segments", ">=",
@@ -1087,8 +1118,9 @@ do_standby_clone(void)
*/
sqlquery_snprintf(
sqlquery,
"SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))",
time(NULL));
"SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld', %s))",
time(NULL),
runtime_options.fast_checkpoint ? "TRUE" : "FALSE");
log_debug(_("standby clone: %s\n"), sqlquery);
res = PQexec(conn, sqlquery);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
@@ -1688,8 +1720,13 @@ do_witness_create(void)
*/
/* Create the cluster for witness */
sprintf(script, "%s/pg_ctl %s -D %s init -o \"-W\"", options.pg_bindir,
options.pgctl_options, runtime_options.dest_dir);
if (!runtime_options.superuser[0])
strncpy(runtime_options.superuser, "postgres", MAXLEN);
sprintf(script, "%s/pg_ctl %s -D %s init -o \"%s-U %s\"", options.pg_bindir,
options.pgctl_options, runtime_options.dest_dir,
runtime_options.initdb_no_pwprompt ? "" : "-W ",
runtime_options.superuser);
log_info("Initialize cluster for witness: %s.\n", script);
r = system(script);
@@ -1742,13 +1779,13 @@ do_witness_create(void)
PQfinish(masterconn);
exit(ERR_BAD_CONFIG);
}
/* check if we need to create a user */
if (runtime_options.username[0] && runtime_options.localport[0] && strcmp(runtime_options.username,"postgres")!=0 )
{
/* create required user needs to be superuser to create untrusted language function in c */
sprintf(script, "%s/createuser -p %s --superuser --login -U postgres %s", options.pg_bindir,
runtime_options.localport,runtime_options.username);
sprintf(script, "%s/createuser -p %s --superuser --login -U %s %s", options.pg_bindir,
runtime_options.localport, runtime_options.superuser, runtime_options.username);
log_info("Create user for witness db: %s.\n", script);
r = system(script);
@@ -1759,13 +1796,13 @@ do_witness_create(void)
exit(ERR_BAD_CONFIG);
}
}
/* check if we need to create a database */
if(runtime_options.dbname[0] && strcmp(runtime_options.dbname,"postgres")!=0 && runtime_options.localport[0])
{
/* create required db */
sprintf(script, "%s/createdb -p %s -U postgres --owner=%s %s",
options.pg_bindir, runtime_options.localport,runtime_options.username, runtime_options.dbname);
sprintf(script, "%s/createdb -p %s -U %s --owner=%s %s",
options.pg_bindir, runtime_options.localport, runtime_options.superuser, runtime_options.username, runtime_options.dbname);
log_info("Create database for witness db: %s.\n", script);
r = system(script);
@@ -1809,7 +1846,7 @@ do_witness_create(void)
PQfinish(masterconn);
exit(ERR_BAD_CONFIG);
}
/* reload to adapt for changed pg_hba.conf */
sprintf(script, "%s/pg_ctl %s -w -D %s reload", options.pg_bindir,
options.pgctl_options, runtime_options.dest_dir);
@@ -1821,8 +1858,8 @@ do_witness_create(void)
PQfinish(masterconn);
exit(ERR_BAD_CONFIG);
}
/* register ourselves in the master */
sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes(id, cluster, name, conninfo, priority, witness) "
"VALUES (%d, '%s', '%s', '%s', %d, true)",
@@ -1917,6 +1954,8 @@ help(const char *progname)
printf(_(" -l, --local-port=PORT standby or witness server local port\n"));
printf(_(" -f, --config-file=PATH path to the configuration file\n"));
printf(_(" -R, --remote-user=USERNAME database server username for rsync\n"));
printf(_(" -S, --superuser=USERNAME superuser username for witness database\n" \
" (default: postgres)\n"));
printf(_(" -w, --wal-keep-segments=VALUE minimum value for the GUC\n" \
" wal_keep_segments (default: 5000)\n"));
printf(_(" -I, --ignore-rsync-warning ignore rsync partial transfer warning\n"));
@@ -1925,7 +1964,8 @@ help(const char *progname)
printf(_(" -F, --force force potentially dangerous operations\n" \
" to happen\n"));
printf(_(" -W, --wait wait for a master to appear\n"));
printf(_(" -c, --fast-checkpoint force fast checkpoint when cloning a standby\n"));
printf(_(" --initdb-no-pwprompt don't require superuser password when running initdb\n"));
printf(_("\n%s performs some tasks like clone a node, promote it or making follow\n"), progname);
printf(_("another node and then exits.\n\n"));
printf(_("COMMANDS:\n"));

View File

@@ -20,9 +20,9 @@
#ifndef _REPMGR_H_
#define _REPMGR_H_
#include "postgres_fe.h"
#include "getopt_long.h"
#include "libpq-fe.h"
#include <libpq-fe.h>
#include <postgres_fe.h>
#include <getopt_long.h>
#include "strutil.h"
#include "dbutils.h"
@@ -56,11 +56,14 @@ typedef struct
char dest_dir[MAXFILENAME];
char config_file[MAXFILENAME];
char remote_user[MAXLEN];
char superuser[MAXLEN];
char wal_keep_segments[MAXLEN];
bool verbose;
bool force;
bool wait_for_master;
bool ignore_rsync_warn;
bool initdb_no_pwprompt;
bool fast_checkpoint;
char masterport[MAXLEN];
char localport[MAXLEN];
@@ -69,6 +72,6 @@ typedef struct
int keep_history;
} t_runtime_options;
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, "", "", 0 }
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, "", "", 0}
#endif

View File

@@ -218,6 +218,17 @@ main(int argc, char **argv)
}
}
/*
* Read the configuration file: repmgr.conf
*/
parse_config(config_file, &local_options);
if (local_options.node == -1)
{
log_err(_("Node information is missing. "
"Check the configuration file, or provide one if you have not done so.\n"));
terminate(ERR_BAD_CONFIG);
}
if (daemonize)
{
do_daemonize();
@@ -232,17 +243,6 @@ main(int argc, char **argv)
setup_event_handlers();
#endif
/*
* Read the configuration file: repmgr.conf
*/
parse_config(config_file, &local_options);
if (local_options.node == -1)
{
log_err(_("Node information is missing. "
"Check the configuration file, or provide one if you have not done so.\n"));
terminate(ERR_BAD_CONFIG);
}
fd = freopen("/dev/null", "r", stdin);
if (fd == NULL)
{

View File

@@ -25,9 +25,15 @@
#include "log.h"
#include "strutil.h"
#if (PG_VERSION_NUM >= 90100)
static int
xvsnprintf(char *str, size_t size, const char *format, va_list ap)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
#else
static int
xvsnprintf(char *str, size_t size, const char *format, va_list ap)
__attribute__((format(printf, 3, 0)));
#endif
static int
xvsnprintf(char *str, size_t size, const char *format, va_list ap)

View File

@@ -31,6 +31,7 @@
#define MAXCONNINFO 1024
#if (PG_VERSION_NUM >= 90100)
extern int
xsnprintf(char *str, size_t size, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
@@ -42,5 +43,18 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern int
maxlen_snprintf(char *str, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
#else
extern int
xsnprintf(char *str, size_t size, const char *format,...)
__attribute__((format(printf, 3, 4)));
extern int
sqlquery_snprintf(char *str, const char *format,...)
__attribute__((format(printf, 2, 3)));
extern int
maxlen_snprintf(char *str, const char *format,...)
__attribute__((format(printf, 2, 3)));
#endif
#endif /* _STRUTIL_H_ */

View File

@@ -1,6 +1,6 @@
#ifndef _VERSION_H_
#define _VERSION_H_
#define REPMGR_VERSION "2.0.2"
#define REPMGR_VERSION "2.0.3"
#endif