mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-23 15:16:29 +00:00
Compare commits
2 Commits
update-doc
...
dev/drop_r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a73bdcfd0 | ||
|
|
e27f213949 |
37
.github/workflows/sonarqube-scan.yml
vendored
Normal file
37
.github/workflows/sonarqube-scan.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: SonarQube Scan
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
sonarQube:
|
||||||
|
name: SonarQube-Job
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout source repo
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
with:
|
||||||
|
ref: '${{ github.head_ref }}'
|
||||||
|
|
||||||
|
- name: Checkout GitHub Action Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
with:
|
||||||
|
repository: EnterpriseDB/edb-github-actions.git
|
||||||
|
ref: master
|
||||||
|
token: ${{ secrets.GH_SLONIK }}
|
||||||
|
path: .github/actions/edb-github-actions
|
||||||
|
|
||||||
|
- name: SonarQube Scan
|
||||||
|
uses: ./.github/actions/edb-github-actions/sonarqube
|
||||||
|
with:
|
||||||
|
REPO_NAME: '${{github.event.repository.name}}'
|
||||||
|
SONAR_PROJECT_KEY: EnterpriseDB_repmgr
|
||||||
|
SONAR_URL: '${{secrets.SONARQUBE_URL}}'
|
||||||
|
SONAR_LOGIN: '${{secrets.SONARQUBE_LOGIN}}'
|
||||||
|
PULL_REQUEST_KEY: '${{github.event.number}}'
|
||||||
|
PULL_REQUEST_BRANCH: '${{github.head_ref}}'
|
||||||
|
PULL_REQUEST_BASE_BRANCH: '${{github.base_ref}}'
|
||||||
|
REPO_DEFAULT_BRANCH: '${{github.event.repository.default_branch}}'
|
||||||
|
REPO_EXCLUDE_FILES: '*properties*,**/src/test/**/*,**/*.sql,**/docs/**/*,**/*/*.java'
|
||||||
18
.github/workflows/sonarqube/configure-env.sh
vendored
Executable file
18
.github/workflows/sonarqube/configure-env.sh
vendored
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DEBIAN_FRONTEND=noninteractive sudo apt-get -y install debhelper curl autoconf zlib1g-dev \
|
||||||
|
libedit-dev libxml2-dev libxslt1-dev libkrb5-dev libssl-dev libpam0g-dev systemtap-sdt-dev \
|
||||||
|
libselinux1-dev build-essential bison apt-utils lsb-release devscripts \
|
||||||
|
software-properties-common git shellcheck flex
|
||||||
|
|
||||||
|
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
|
||||||
|
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
|
sudo apt-get -y install libpq-dev postgresql-13 postgresql-server-dev-13
|
||||||
|
|
||||||
|
./configure
|
||||||
|
|
||||||
|
export PG_CONFIG=/usr/bin/pg_config
|
||||||
|
|
||||||
|
/home/buildfarm/sonar/depends/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir build_wrapper_output_directory make
|
||||||
11
HISTORY
11
HISTORY
@@ -1,15 +1,8 @@
|
|||||||
5.3.3 2022-10-17
|
5.3.2 2022-??-??
|
||||||
Support for PostgreSQL added
|
|
||||||
repmgrd: ensure event notification script is called for event
|
|
||||||
"repmgrd_upstream_disconnect"; GitHub #760 (Ian)
|
|
||||||
|
|
||||||
5.3.2 2022-05-25
|
|
||||||
standby clone: don't error out if unable to determine cluster size (Ian)
|
standby clone: don't error out if unable to determine cluster size (Ian)
|
||||||
node check: fix --downstream --nagios output; GitHub #749 (Ian)
|
node check: fix --downstream --nagios output; GitHub #749 (Ian)
|
||||||
repmgrd: ensure witness node marked active (hslightdb)
|
repmgrd: ensure witness node marked active (hslightdb)
|
||||||
repmgrd: improve walsender disable check (Ian)
|
repmgrd: improve walsender disable check (Ian)
|
||||||
general: ensure replication slots can be dropped by a
|
|
||||||
replication-only user (Ian)
|
|
||||||
|
|
||||||
5.3.1 2022-02-15
|
5.3.1 2022-02-15
|
||||||
repmgrd: fixes for potential connection leaks (hslightdb)
|
repmgrd: fixes for potential connection leaks (hslightdb)
|
||||||
@@ -74,7 +67,7 @@
|
|||||||
"standby clone" (Ian)
|
"standby clone" (Ian)
|
||||||
repmgr: add --upstream option to "node check"
|
repmgr: add --upstream option to "node check"
|
||||||
repmgr: report error code on follow/rejoin failure due to non-available
|
repmgr: report error code on follow/rejoin failure due to non-available
|
||||||
replication slot (Ian)
|
0 replication slot (Ian)
|
||||||
repmgr: ensure "node rejoin" checks for available replication slots (Ian)
|
repmgr: ensure "node rejoin" checks for available replication slots (Ian)
|
||||||
repmgr: improve "standby switchover" completion checks (Ian)
|
repmgr: improve "standby switchover" completion checks (Ian)
|
||||||
repmgr: add replication configuration file ownership check to
|
repmgr: add replication configuration file ownership check to
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ GIT_WORK_TREE=${repmgr_abs_srcdir}
|
|||||||
GIT_DIR=${repmgr_abs_srcdir}/.git
|
GIT_DIR=${repmgr_abs_srcdir}/.git
|
||||||
export GIT_DIR
|
export GIT_DIR
|
||||||
export GIT_WORK_TREE
|
export GIT_WORK_TREE
|
||||||
PG_LDFLAGS=-lcurl -ljson-c
|
|
||||||
include $(PGXS)
|
include $(PGXS)
|
||||||
|
|
||||||
-include ${repmgr_abs_srcdir}/Makefile.custom
|
-include ${repmgr_abs_srcdir}/Makefile.custom
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ REPMGR_CLIENT_OBJS = repmgr-client.o \
|
|||||||
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
||||||
repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
|
repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
|
||||||
configdata.o configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o \
|
configdata.o configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o \
|
||||||
dbutils.o sysutils.o pgbackupapi.o
|
dbutils.o sysutils.o
|
||||||
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o configdata.o configfile.o configfile-scan.o log.o \
|
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o configdata.o configfile.o configfile-scan.o log.o \
|
||||||
dbutils.o strutil.o controldata.o compat.o sysutils.o
|
dbutils.o strutil.o controldata.o compat.o sysutils.o
|
||||||
|
|
||||||
@@ -81,10 +81,10 @@ configfile-scan.c: configfile-scan.l
|
|||||||
$(REPMGR_CLIENT_OBJS): repmgr-client.h repmgr_version.h
|
$(REPMGR_CLIENT_OBJS): repmgr-client.h repmgr_version.h
|
||||||
|
|
||||||
repmgr: $(REPMGR_CLIENT_OBJS)
|
repmgr: $(REPMGR_CLIENT_OBJS)
|
||||||
$(CC) $(CFLAGS) $(REPMGR_CLIENT_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
$(CC) $(CFLAGS) $(REPMGR_CLIENT_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
|
||||||
|
|
||||||
repmgrd: $(REPMGRD_OBJS)
|
repmgrd: $(REPMGRD_OBJS)
|
||||||
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
|
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
|
||||||
|
|
||||||
$(REPMGR_CLIENT_OBJS): $(HEADERS)
|
$(REPMGR_CLIENT_OBJS): $(HEADERS)
|
||||||
$(REPMGRD_OBJS): $(HEADERS)
|
$(REPMGRD_OBJS): $(HEADERS)
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -7,8 +7,8 @@ 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 most recent `repmgr` version (5.3.2) supports all PostgreSQL versions from
|
The most recent `repmgr` version (5.2.1) supports all PostgreSQL versions from
|
||||||
9.5 to 14. PostgreSQL 9.4 is also supported, with some restrictions.
|
9.5 to 13. PostgreSQL 9.4 is also supported, with some restrictions.
|
||||||
|
|
||||||
`repmgr` is distributed under the GNU GPL 3 and maintained by EnterpriseDB.
|
`repmgr` is distributed under the GNU GPL 3 and maintained by EnterpriseDB.
|
||||||
|
|
||||||
@@ -19,6 +19,14 @@ The full `repmgr` documentation is available here:
|
|||||||
|
|
||||||
> [repmgr documentation](https://repmgr.org/docs/current/index.html)
|
> [repmgr documentation](https://repmgr.org/docs/current/index.html)
|
||||||
|
|
||||||
|
The old `README` file for `repmgr` 3.x is available here:
|
||||||
|
|
||||||
|
> https://github.com/EnterpriseDB/repmgr/blob/REL3_3_STABLE/README.md
|
||||||
|
|
||||||
|
Note that the `repmgr` 3.x series is no longer supported and contains known bugs;
|
||||||
|
please upgrade to the [current repmgr version](https://repmgr.org/docs/current/appendix-release-notes.html)
|
||||||
|
as soon as possible.
|
||||||
|
|
||||||
Versions
|
Versions
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -40,6 +48,7 @@ Directories
|
|||||||
- `contrib/`: additional utilities
|
- `contrib/`: additional utilities
|
||||||
- `doc/`: DocBook-based documentation files
|
- `doc/`: DocBook-based documentation files
|
||||||
- `expected/`: expected regression test output
|
- `expected/`: expected regression test output
|
||||||
|
- `scripts/`: example scripts
|
||||||
- `sql/`: regression test input
|
- `sql/`: regression test input
|
||||||
|
|
||||||
|
|
||||||
@@ -69,6 +78,7 @@ news are always welcome.
|
|||||||
|
|
||||||
Thanks from the repmgr core team.
|
Thanks from the repmgr core team.
|
||||||
|
|
||||||
|
* Ian Barwick
|
||||||
* Jaime Casanova
|
* Jaime Casanova
|
||||||
* Abhijit Menon-Sen
|
* Abhijit Menon-Sen
|
||||||
* Simon Riggs
|
* Simon Riggs
|
||||||
|
|||||||
40
configdata.c
40
configdata.c
@@ -291,46 +291,6 @@ struct ConfigFileSetting config_file_settings[] =
|
|||||||
{},
|
{},
|
||||||
{}
|
{}
|
||||||
},
|
},
|
||||||
/* pg_backupapi_backup_id*/
|
|
||||||
{
|
|
||||||
"pg_backupapi_backup_id",
|
|
||||||
CONFIG_STRING,
|
|
||||||
{ .strptr = config_file_options.pg_backupapi_backup_id },
|
|
||||||
{ .strdefault = "" },
|
|
||||||
{},
|
|
||||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_backup_id) },
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
/* pg_backupapi_host*/
|
|
||||||
{
|
|
||||||
"pg_backupapi_host",
|
|
||||||
CONFIG_STRING,
|
|
||||||
{ .strptr = config_file_options.pg_backupapi_host },
|
|
||||||
{ .strdefault = "" },
|
|
||||||
{},
|
|
||||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_host) },
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
/* pg_backupapi_node_name */
|
|
||||||
{
|
|
||||||
"pg_backupapi_node_name",
|
|
||||||
CONFIG_STRING,
|
|
||||||
{ .strptr = config_file_options.pg_backupapi_node_name },
|
|
||||||
{ .strdefault = "" },
|
|
||||||
{},
|
|
||||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_node_name) },
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
/* pg_backupapi_remote_ssh_command */
|
|
||||||
{
|
|
||||||
"pg_backupapi_remote_ssh_command",
|
|
||||||
CONFIG_STRING,
|
|
||||||
{ .strptr = config_file_options.pg_backupapi_remote_ssh_command },
|
|
||||||
{ .strdefault = "" },
|
|
||||||
{},
|
|
||||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_remote_ssh_command) },
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
|
|
||||||
/* =======================
|
/* =======================
|
||||||
* standby follow settings
|
* standby follow settings
|
||||||
|
|||||||
@@ -164,10 +164,6 @@ typedef struct
|
|||||||
char archive_cleanup_command[MAXLEN];
|
char archive_cleanup_command[MAXLEN];
|
||||||
bool use_primary_conninfo_password;
|
bool use_primary_conninfo_password;
|
||||||
char passfile[MAXPGPATH];
|
char passfile[MAXPGPATH];
|
||||||
char pg_backupapi_backup_id[NAMEDATALEN];
|
|
||||||
char pg_backupapi_host[NAMEDATALEN];
|
|
||||||
char pg_backupapi_node_name[NAMEDATALEN];
|
|
||||||
char pg_backupapi_remote_ssh_command[MAXLEN];
|
|
||||||
|
|
||||||
/* standby promote settings */
|
/* standby promote settings */
|
||||||
int promote_check_timeout;
|
int promote_check_timeout;
|
||||||
|
|||||||
20
configure.in
20
configure.in
@@ -60,7 +60,6 @@ AC_SUBST(vpath_build)
|
|||||||
AC_CHECK_PROG(HAVE_GNUSED,gnused,yes,no)
|
AC_CHECK_PROG(HAVE_GNUSED,gnused,yes,no)
|
||||||
AC_CHECK_PROG(HAVE_GSED,gsed,yes,no)
|
AC_CHECK_PROG(HAVE_GSED,gsed,yes,no)
|
||||||
AC_CHECK_PROG(HAVE_SED,sed,yes,no)
|
AC_CHECK_PROG(HAVE_SED,sed,yes,no)
|
||||||
AC_CHECK_PROG(HAVE_FLEX,flex,yes,no)
|
|
||||||
|
|
||||||
if test "$HAVE_GNUSED" = yes; then
|
if test "$HAVE_GNUSED" = yes; then
|
||||||
SED=gnused
|
SED=gnused
|
||||||
@@ -73,25 +72,6 @@ else
|
|||||||
fi
|
fi
|
||||||
AC_SUBST(SED)
|
AC_SUBST(SED)
|
||||||
|
|
||||||
AS_IF([test x"$HAVE_FLEX" != x"yes"], AC_MSG_ERROR([flex should be installed first]))
|
|
||||||
|
|
||||||
#Checking libraries
|
|
||||||
GENERIC_LIB_FAILED_MSG="library should be installed"
|
|
||||||
|
|
||||||
AC_CHECK_LIB(selinux, is_selinux_enabled, [],
|
|
||||||
[AC_MSG_ERROR(['selinux' $GENERIC_LIB_FAILED_MSG])])
|
|
||||||
|
|
||||||
AC_CHECK_LIB(lz4, LZ4_compress_default, [],
|
|
||||||
[AC_MSG_ERROR(['Z4' $GENERIC_LIB_FAILED_MSG])])
|
|
||||||
|
|
||||||
AC_CHECK_LIB(xslt, xsltCleanupGlobals, [],
|
|
||||||
[AC_MSG_ERROR(['xslt' $GENERIC_LIB_FAILED_MSG])])
|
|
||||||
|
|
||||||
AC_CHECK_LIB(pam, pam_start, [],
|
|
||||||
[AC_MSG_ERROR(['pam' $GENERIC_LIB_FAILED_MSG])])
|
|
||||||
|
|
||||||
AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, [],
|
|
||||||
[AC_MSG_ERROR([gssapi_krb5 $GENERIC_LIB_FAILED_MSG])])
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile])
|
AC_CONFIG_FILES([Makefile])
|
||||||
AC_CONFIG_FILES([Makefile.global])
|
AC_CONFIG_FILES([Makefile.global])
|
||||||
|
|||||||
@@ -4616,17 +4616,17 @@ drop_replication_slot_replprot(PGconn *repl_conn, char *slot_name)
|
|||||||
initPQExpBuffer(&query);
|
initPQExpBuffer(&query);
|
||||||
|
|
||||||
appendPQExpBuffer(&query,
|
appendPQExpBuffer(&query,
|
||||||
"DROP_REPLICATION_SLOT %s;",
|
"DROP_REPLICATION_SLOT %s",
|
||||||
slot_name);
|
slot_name);
|
||||||
|
|
||||||
log_verbose(LOG_DEBUG, "drop_replication_slot_replprot():\n %s", query.data);
|
log_verbose(LOG_DEBUG, "drop_replication_slot_replprot():\n %s", query.data);
|
||||||
|
|
||||||
res = PQexec(repl_conn, query.data);
|
res = PQexec(repl_conn, query.data);
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK || !PQntuples(res))
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
log_db_error(repl_conn, query.data,
|
log_db_error(repl_conn, query.data,
|
||||||
_("drop_replication_slot_replprot(): unable to drop replication slot \"%s\""),
|
_("drop_replication_slot_sql(): unable to drop replication slot \"%s\""),
|
||||||
slot_name);
|
slot_name);
|
||||||
|
|
||||||
success = false;
|
success = false;
|
||||||
|
|||||||
@@ -16,45 +16,12 @@
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<!-- remember to update the release date in ../repmgr_version.h.in -->
|
<!-- remember to update the release date in ../repmgr_version.h.in -->
|
||||||
<sect1 id="release-5.3.3">
|
|
||||||
<title id="release-current">Release 5.3.3</title>
|
|
||||||
<para><emphasis>Mon 17 October, 2022</emphasis></para>
|
|
||||||
<para>
|
|
||||||
&repmgr; 5.3.3 is a minor release providing support for
|
|
||||||
<ulink url="https://www.postgresql.org/docs/15/release-15.html">PostgreSQL 15</ulink>
|
|
||||||
and a &repmgrd; bug fix.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If upgrading from an earlier &repmgr; version, any running &repmgrd; instances should be restarted.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If upgrading from &repmgr; 5.2.1 or earlier, a PostgreSQL restart <emphasis>is</emphasis> required.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Bug fixes</title>
|
|
||||||
<para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
&repmgrd;: ensure <link linkend="event-notifications">event notification</link> script is called for event
|
|
||||||
<literal>repmgrd_upstream_disconnect</literal>. GitHub #760.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="release-5.3.2">
|
<sect1 id="release-5.3.2">
|
||||||
<title>Release 5.3.2</title>
|
<title id="release-current">Release 5.3.2</title>
|
||||||
<para><emphasis>Wed 25 May, 2022</emphasis></para>
|
<para><emphasis>??? ??? ???, 2022</emphasis></para>
|
||||||
<para>
|
<para>
|
||||||
&repmgr; 5.3.2 is a minor release.
|
&repmgr; 5.3.2 is a minor release.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
Any running &repmgrd; instances should be restarted following this upgrade.
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
If upgrading from &repmgr; 5.2.1 or earlier, a PostgreSQL restart <emphasis>is</emphasis> required.
|
If upgrading from &repmgr; 5.2.1 or earlier, a PostgreSQL restart <emphasis>is</emphasis> required.
|
||||||
</para>
|
</para>
|
||||||
@@ -94,13 +61,6 @@
|
|||||||
&repmgr; is a superuser before attempting to disable the WAL receiver.
|
&repmgr; is a superuser before attempting to disable the WAL receiver.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
If the &repmgr; user is a non-superuser, and a replication-only user exists,
|
|
||||||
ensure redundant replication slots are dropped correctly even
|
|
||||||
if the <option>-S/--superuser</option> option is not provided.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|||||||
@@ -225,109 +225,6 @@ description = "Main cluster"
|
|||||||
</note>
|
</note>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="cloning-from-barman-pg_backupapi-mode" xreflabel="Using Barman through its API (pg-backup-api)">
|
|
||||||
<title>Using Barman through its API (pg-backup-api)</title>
|
|
||||||
<indexterm>
|
|
||||||
<primary>cloning</primary>
|
|
||||||
<secondary>pg-backup-api</secondary>
|
|
||||||
</indexterm>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You can find information on how to install and setup pg-backup-api in
|
|
||||||
<ulink url="https://www.enterprisedb.com/docs/supported-open-source/barman/pg-backup-api/">the pg-backup-api
|
|
||||||
documentation</ulink>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This mode (`pg-backupapi`) was introduced in v5.4.0 as a way to further integrate with Barman letting Barman
|
|
||||||
handle the restore. This also reduces the ssh keys that need to share between the backup and postgres nodes.
|
|
||||||
As long as you have access to the API service by HTTP calls, you could perform recoveries right away.
|
|
||||||
You just need to instruct Barman through the API which backup you need and on which node the backup needs to
|
|
||||||
to be restored on.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In order to enable <literal>pg_backupapi mode</literal> support for <command>repmgr standby clone</command>,
|
|
||||||
you need the following lines in repmgr.conf:
|
|
||||||
<itemizedlist spacing="compact" mark="bullet">
|
|
||||||
<listitem><para>pg_backupapi_host: Where pg-backup-api is hosted</para></listitem>
|
|
||||||
<listitem><para>pg_backupapi_node_name: Name of the server as understood by Barman</para></listitem>
|
|
||||||
<listitem><para>pg_backupapi_remote_ssh_command: How Barman will be connecting as to the node</para></listitem>
|
|
||||||
<listitem><para>pg_backupapi_backup_id: ID of the existing backup you need to restore</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
This is an example of how repmgr.conf would look like:
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
pg_backupapi_host = '192.168.122.154'
|
|
||||||
pg_backupapi_node_name = 'burrito'
|
|
||||||
pg_backupapi_remote_ssh_command = 'ssh john_doe@192.168.122.1'
|
|
||||||
pg_backupapi_backup_id = '20230223T093201'
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<literal>pg_backupapi_host</literal> is the variable name that enables this mode, and when you set it,
|
|
||||||
all the rest of the above variables are required. Also, remember that this service is just an interface
|
|
||||||
between Barman and repmgr, hence if something fails during a recovery, you should check Barman's logs upon
|
|
||||||
why the process couldn't finish properly.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<simpara>
|
|
||||||
Despite in Barman you can define shortcuts like "lastest" or "oldest", they are not supported for the
|
|
||||||
time being in pg-backup-api. These shortcuts will be supported in a future release.
|
|
||||||
</simpara>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This is a real example of repmgr's output cloning with the API. Note that during this operation, we stopped
|
|
||||||
the service for a little while and repmgr had to retry but that doesn't affect the final outcome. The primary
|
|
||||||
is listening on localhost's port 6001:
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
$ repmgr -f ~/nodes/node_3/repmgr.conf standby clone -U repmgr -p 6001 -h localhost
|
|
||||||
NOTICE: destination directory "/home/mario/nodes/node_3/data" provided
|
|
||||||
INFO: Attempting to use `pg_backupapi` new restore mode
|
|
||||||
INFO: connecting to source node
|
|
||||||
DETAIL: connection string is: user=repmgr port=6001 host=localhost
|
|
||||||
DETAIL: current installation size is 8541 MB
|
|
||||||
DEBUG: 1 node records returned by source node
|
|
||||||
DEBUG: connecting to: "user=repmgr dbname=repmgr host=localhost port=6001 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
|
|
||||||
DEBUG: upstream_node_id determined as 1
|
|
||||||
INFO: Attempting to use `pg_backupapi` new restore mode
|
|
||||||
INFO: replication slot usage not requested; no replication slot will be set up for this standby
|
|
||||||
NOTICE: starting backup (using pg_backupapi)...
|
|
||||||
INFO: Success creating the task: operation id '20230309T150647'
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
Incorrect reply received for that operation ID.
|
|
||||||
INFO: Retrying...
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status IN_PROGRESS
|
|
||||||
INFO: status DONE
|
|
||||||
NOTICE: standby clone (from pg_backupapi) complete
|
|
||||||
NOTICE: you can now start your PostgreSQL server
|
|
||||||
HINT: for example: pg_ctl -D /home/mario/nodes/node_3/data start
|
|
||||||
HINT: after starting the server, you need to register this standby with "repmgr standby register"
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
</sect2> <!--END cloning-from-barman-pg_backupapi-mode !-->
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots">
|
<sect1 id="cloning-replication-slots" xreflabel="Cloning and replication slots">
|
||||||
|
|||||||
@@ -108,31 +108,10 @@
|
|||||||
<entry>
|
<entry>
|
||||||
Supported PostgreSQL versions
|
Supported PostgreSQL versions
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
Notes
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
&repmgr; 5.4
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
(dev)
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
9.4, 9.5, 9.6, 10, 11, 12, 13, 15
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
&repmgr; 5.3
|
&repmgr; 5.3
|
||||||
@@ -144,10 +123,7 @@
|
|||||||
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
|
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
9.4, 9.5, 9.6, 10, 11, 12, 13, 14, 15
|
9.4, 9.5, 9.6, 10, 11, 12, 13, 14
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
PostgreSQL 15 supported from &repmgr; 5.3.3
|
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@@ -164,9 +140,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.4, 9.5, 9.6, 10, 11, 12, 13
|
9.4, 9.5, 9.6, 10, 11, 12, 13
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
@@ -182,9 +155,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
@@ -200,9 +170,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
|
||||||
@@ -219,9 +186,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.3, 9.4, 9.5, 9.6, 10, 11
|
9.3, 9.4, 9.5, 9.6, 10, 11
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
@@ -237,9 +201,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.3, 9.4, 9.5, 9.6
|
9.3, 9.4, 9.5, 9.6
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
@@ -255,9 +216,6 @@
|
|||||||
<entry>
|
<entry>
|
||||||
9.0, 9.1, 9.2, 9.3, 9.4
|
9.0, 9.1, 9.2, 9.3, 9.4
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
|
||||||
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
|||||||
@@ -73,16 +73,16 @@
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--force-rewind</option></term>
|
<term><option>--force-rewind[=/path/to/pg_rewind]</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Execute <application>pg_rewind</application>.
|
Execute <application>pg_rewind</application>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
See <xref linkend="repmgr-node-rejoin-pg-rewind"/> for more details on using
|
It is only necessary to provide the <application>pg_rewind</application> path
|
||||||
<application>pg_rewind</application>.
|
if using PostgreSQL 9.4, and <application>pg_rewind</application>
|
||||||
|
is not installed in the PostgreSQL <filename>bin</filename> directory.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@@ -261,6 +261,8 @@
|
|||||||
<para>
|
<para>
|
||||||
<command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a
|
<command>repmgr node rejoin</command> can optionally use <command>pg_rewind</command> to re-integrate a
|
||||||
node which has diverged from the rest of the cluster, typically a failed primary.
|
node which has diverged from the rest of the cluster, typically a failed primary.
|
||||||
|
<command>pg_rewind</command> is available in PostgreSQL 9.5 and later as part of the core distribution,
|
||||||
|
and can be installed from external sources for PostgreSQL 9.4.
|
||||||
</para>
|
</para>
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
@@ -269,10 +271,6 @@
|
|||||||
data checksums were enabled when the cluster was initialized. See the
|
data checksums were enabled when the cluster was initialized. See the
|
||||||
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html"><command>pg_rewind</command> documentation</ulink> for details.
|
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html"><command>pg_rewind</command> documentation</ulink> for details.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
Additionally, <varname>full_page_writes</varname> must be enabled; this is the default and
|
|
||||||
normally should never be disabled.
|
|
||||||
</para>
|
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -384,29 +382,6 @@
|
|||||||
DETAIL: node 2 is now attached to node 3</programlisting>
|
DETAIL: node 2 is now attached to node 3</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
<refsect2 id="repmgr-node-rejoin-postgresql-94" xreflabel="pg_rewind and PostgreSQL 9.4">
|
|
||||||
|
|
||||||
<title><command>pg_rewind</command> and PostgreSQL 9.4</title>
|
|
||||||
|
|
||||||
<indexterm>
|
|
||||||
<primary>pg_rewind</primary>
|
|
||||||
<secondary>PostgreSQL 9.4</secondary>
|
|
||||||
</indexterm>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<application>pg_rewind</application> is available in PostgreSQL 9.5 and later as part of the core distribution.
|
|
||||||
Users of PostgreSQL 9.4 will need to manually install it; the source code is available here:
|
|
||||||
<ulink url="https://github.com/vmware/pg_rewind">https://github.com/vmware/pg_rewind</ulink>.
|
|
||||||
If the <application>pg_rewind</application>
|
|
||||||
binary is not installed in the PostgreSQL <filename>bin</filename> directory, provide
|
|
||||||
its full path on the demotion candidate with <option>--force-rewind</option>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Note that building the 9.4 version of <application>pg_rewind</application> requires the PostgreSQL
|
|
||||||
source code.
|
|
||||||
</para>
|
|
||||||
</refsect2>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats">
|
<refsect1 id="repmgr-node-rejoin-caveats" xreflabel="Caveats">
|
||||||
@@ -451,7 +426,7 @@
|
|||||||
|
|
||||||
<warning>
|
<warning>
|
||||||
<para>
|
<para>
|
||||||
In all PostgreSQL released before February 2021, <application>pg_rewind</application>
|
In all current PostgreSQL versions (as of September 2020), <application>pg_rewind</application>
|
||||||
contains a corner-case bug which affects standbys in a very specific situation.
|
contains a corner-case bug which affects standbys in a very specific situation.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@@ -481,7 +456,8 @@
|
|||||||
<para>
|
<para>
|
||||||
Currently it is not possible to resolve this situation using <application>pg_rewind</application>.
|
Currently it is not possible to resolve this situation using <application>pg_rewind</application>.
|
||||||
A <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2b4f3130382fe2f8705863e4d38589d4d69cd695">patch</ulink>
|
A <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2b4f3130382fe2f8705863e4d38589d4d69cd695">patch</ulink>
|
||||||
was submitted and is included in all PostgreSQL versions released in February 2021 or later.
|
has been successfully submitted and will be included the next PostgreSQL minor release round, scheduled for
|
||||||
|
February 2021.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
As a workaround, start the primary server the standby was previously attached to,
|
As a workaround, start the primary server the standby was previously attached to,
|
||||||
@@ -499,7 +475,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-standby-follow"/>, <xref linkend="repmgr-standby-switchover"/>
|
<xref linkend="repmgr-standby-follow"/>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
|
|||||||
@@ -154,12 +154,9 @@
|
|||||||
<para>
|
<para>
|
||||||
Use <application>pg_rewind</application> to reintegrate the old primary if necessary
|
Use <application>pg_rewind</application> to reintegrate the old primary if necessary
|
||||||
(and the prerequisites for using <application>pg_rewind</application> are met).
|
(and the prerequisites for using <application>pg_rewind</application> are met).
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If using PostgreSQL 9.4, and the <application>pg_rewind</application>
|
If using PostgreSQL 9.4, and the <application>pg_rewind</application>
|
||||||
binary is not installed in the PostgreSQL <filename>bin</filename> directory,
|
binary is not installed in the PostgreSQL <filename>bin</filename> directory,
|
||||||
provide its full path. For more details see also <xref linkend="switchover-pg-rewind"/>
|
provide its full path. For more details see also <xref linkend="switchover-pg-rewind"/>.
|
||||||
and <xref linkend="repmgr-node-rejoin-pg-rewind"/>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<abstract>
|
<abstract>
|
||||||
<para>
|
<para>
|
||||||
This is the official documentation of &repmgr; &repmgrversion; for
|
This is the official documentation of &repmgr; &repmgrversion; for
|
||||||
use with PostgreSQL 9.4 - PostgreSQL 15.
|
use with PostgreSQL 9.4 - PostgreSQL 14.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
&repmgr; is being continually developed and we strongly recommend using the
|
&repmgr; is being continually developed and we strongly recommend using the
|
||||||
|
|||||||
@@ -345,18 +345,14 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Indicates a preferred priority (default: <literal>100</literal>) for promoting nodes.
|
Indicates a preferred priority (default: <literal>100</literal>) for promoting nodes;
|
||||||
|
a value of zero prevents the node being promoted to primary.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Note that the priority setting is only applied if two or more nodes are
|
Note that the priority setting is only applied if two or more nodes are
|
||||||
determined as promotion candidates; in that case the node with the
|
determined as promotion candidates; in that case the node with the
|
||||||
higher priority is selected.
|
higher priority is selected.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
A value of zero will always prevent the node being promoted to primary, even if there
|
|
||||||
is no other promotion candidate.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<simpara>
|
<simpara>
|
||||||
option to execute custom scripts ("<link linkend="event-notifications">event notifications</link>")
|
option to execute custom scripts ("<link linkend="event-notifications">event notifications</link>
|
||||||
at different points in the failover sequence
|
at different points in the failover sequence
|
||||||
</simpara>
|
</simpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|||||||
@@ -242,12 +242,21 @@
|
|||||||
</simpara>
|
</simpara>
|
||||||
</note>
|
</note>
|
||||||
<para>
|
<para>
|
||||||
For more details on <application>pg_rewind</application>, see section <xref linkend="repmgr-node-rejoin-pg-rewind"/>
|
For more details on <application>pg_rewind</application>, see:
|
||||||
in the <link linkend="repmgr-node-rejoin"><command>repmgr node rejoin</command></link> documentation and
|
|
||||||
the PostgreSQL documentation at
|
|
||||||
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html">https://www.postgresql.org/docs/current/app-pgrewind.html</ulink>.
|
<ulink url="https://www.postgresql.org/docs/current/app-pgrewind.html">https://www.postgresql.org/docs/current/app-pgrewind.html</ulink>.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
<application>pg_rewind</application> has been part of the core PostgreSQL distribution since
|
||||||
|
version 9.5. Users of PostgreSQL 9.4 will need to manually install it; the source code is available here:
|
||||||
|
<ulink url="https://github.com/vmware/pg_rewind">https://github.com/vmware/pg_rewind</ulink>.
|
||||||
|
If the <application>pg_rewind</application>
|
||||||
|
binary is not installed in the PostgreSQL <filename>bin</filename> directory, provide
|
||||||
|
its full path on the demotion candidate with <option>--force-rewind</option>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Note that building the 9.4 version of <application>pg_rewind</application> requires the PostgreSQL
|
||||||
|
source code.
|
||||||
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,12 +71,6 @@
|
|||||||
<secondary>minor release</secondary>
|
<secondary>minor release</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
|
||||||
A minor release upgrade involves updating &repmgr; from one minor release to another
|
|
||||||
minor release within the same major release (e.g. <literal>5.3.1</literal> to <literal>5.3.2</literal>).
|
|
||||||
An upgrade between minor releases of differing major releases (e.g. <literal>5.2.1</literal> to <literal>5.3.2</literal>)
|
|
||||||
is a <link linkend="upgrading-major-version">major upgrade</link>.
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
The process for installing minor version upgrades is quite straightforward:
|
The process for installing minor version upgrades is quite straightforward:
|
||||||
|
|
||||||
@@ -111,17 +105,15 @@
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A PostgreSQL restart is usually <emphasis>not</emphasis> required for minor version upgrades
|
A PostgreSQL restart is <emphasis>not</emphasis> required for minor version upgrades.
|
||||||
within the same major version (e.g. <literal>5.3.1</literal> to <literal>5.3.2</literal>).
|
|
||||||
Be sure to check the <link linkend="appendix-release-notes">release notes</link>.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The same &repmgr; "major version" (e.g. <literal>5.3</literal>) must be
|
The same &repmgr; "major version" (e.g. <literal>4.2</literal>) must be
|
||||||
installed on all nodes in the replication cluster. While it's possible to have differing
|
installed on all nodes in the replication cluster. While it's possible to have differing
|
||||||
&repmgr; "minor versions" (e.g. <literal>5.3.1</literal> and <literal>5.3.2</literal>)
|
&repmgr; "minor versions" (e.g. <literal>4.2.1</literal>) on different nodes,
|
||||||
on different nodes, we strongly recommend updating all nodes to the latest minor version.
|
we strongly recommend updating all nodes to the latest minor version.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,5 @@
|
|||||||
#define ERR_NODE_STATUS 25
|
#define ERR_NODE_STATUS 25
|
||||||
#define ERR_REPMGRD_PAUSE 26
|
#define ERR_REPMGRD_PAUSE 26
|
||||||
#define ERR_REPMGRD_SERVICE 27
|
#define ERR_REPMGRD_SERVICE 27
|
||||||
#define ERR_PGBACKUPAPI_SERVICE 28
|
|
||||||
|
|
||||||
#endif /* _ERRCODE_H_ */
|
#endif /* _ERRCODE_H_ */
|
||||||
|
|||||||
147
pgbackupapi.c
147
pgbackupapi.c
@@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
* pgbackupapi.c
|
|
||||||
* Copyright (c) EnterpriseDB Corporation, 2010-2021
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <json-c/json.h>
|
|
||||||
|
|
||||||
#include "repmgr.h"
|
|
||||||
#include "pgbackupapi.h"
|
|
||||||
|
|
||||||
|
|
||||||
size_t receive_operations_cb(void *content, size_t size, size_t nmemb, char *buffer) {
|
|
||||||
short int max_chars_to_copy = MAX_BUFFER_LENGTH -2;
|
|
||||||
short int i = 0;
|
|
||||||
int operation_length = 0;
|
|
||||||
json_object *value;
|
|
||||||
|
|
||||||
json_object *root = json_tokener_parse(content);
|
|
||||||
json_object *operations = json_object_object_get(root, "operations");
|
|
||||||
|
|
||||||
operation_length = strlen(json_object_get_string(operations));
|
|
||||||
if (operation_length < max_chars_to_copy) {
|
|
||||||
max_chars_to_copy = operation_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(buffer, json_object_get_string(operations), max_chars_to_copy);
|
|
||||||
|
|
||||||
fprintf(stdout, "Success! The following operations were found\n");
|
|
||||||
for (i=0; i<json_object_array_length(operations); i++) {
|
|
||||||
value = json_object_array_get_idx(operations, i);
|
|
||||||
printf("%s\n", json_object_get_string(value));
|
|
||||||
}
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * define_base_url(operation_task *task) {
|
|
||||||
char *format = "http://%s:7480/servers/%s/operations";
|
|
||||||
char *url = malloc(MAX_BUFFER_LENGTH);
|
|
||||||
|
|
||||||
snprintf(url, MAX_BUFFER_LENGTH-1, format, task->host, task->node_name);
|
|
||||||
|
|
||||||
//`url` is freed on the function that called this
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode get_operations_on_server(CURL *curl, operation_task *task) {
|
|
||||||
char buffer[MAX_BUFFER_LENGTH];
|
|
||||||
char *url = define_base_url(task);
|
|
||||||
CURLcode ret;
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_operations_cb);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
|
|
||||||
ret = curl_easy_perform(curl);
|
|
||||||
free(url);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t receive_operation_id(void *content, size_t size, size_t nmemb, char *buffer) {
|
|
||||||
json_object *root = json_tokener_parse(content);
|
|
||||||
json_object *operation = json_object_object_get(root, "operation_id");
|
|
||||||
|
|
||||||
if (operation != NULL) {
|
|
||||||
strncpy(buffer, json_object_get_string(operation), MAX_BUFFER_LENGTH-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CURLcode create_new_task(CURL *curl, operation_task *task) {
|
|
||||||
PQExpBufferData payload;
|
|
||||||
char *url = define_base_url(task);
|
|
||||||
CURLcode ret;
|
|
||||||
json_object *root = json_object_new_object();
|
|
||||||
struct curl_slist *chunk = NULL;
|
|
||||||
|
|
||||||
json_object_object_add(root, "operation_type", json_object_new_string(task->operation_type));
|
|
||||||
json_object_object_add(root, "backup_id", json_object_new_string(task->backup_id));
|
|
||||||
json_object_object_add(root, "remote_ssh_command", json_object_new_string(task->remote_ssh_command));
|
|
||||||
json_object_object_add(root, "destination_directory", json_object_new_string(task->destination_directory));
|
|
||||||
|
|
||||||
initPQExpBuffer(&payload);
|
|
||||||
appendPQExpBufferStr(&payload, json_object_to_json_string(root));
|
|
||||||
|
|
||||||
chunk = curl_slist_append(chunk, "Content-type: application/json");
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.data);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
|
||||||
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_operation_id);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, task->operation_id);
|
|
||||||
ret = curl_easy_perform(curl);
|
|
||||||
free(url);
|
|
||||||
termPQExpBuffer(&payload);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t receive_operation_status(void *content, size_t size, size_t nmemb, char *buffer) {
|
|
||||||
json_object *root = json_tokener_parse(content);
|
|
||||||
json_object *status = json_object_object_get(root, "status");
|
|
||||||
if (status != NULL) {
|
|
||||||
strncpy(buffer, json_object_get_string(status), MAX_BUFFER_LENGTH-2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "Incorrect reply received for that operation ID.\n");
|
|
||||||
strcpy(buffer, "\0");
|
|
||||||
}
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode get_status_of_operation(CURL *curl, operation_task *task) {
|
|
||||||
CURLcode ret;
|
|
||||||
char *url = define_base_url(task);
|
|
||||||
|
|
||||||
strcat(url, "/");
|
|
||||||
strcat(url, task->operation_id);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_operation_status);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, task->operation_status);
|
|
||||||
|
|
||||||
ret = curl_easy_perform(curl);
|
|
||||||
free(url);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* pgbackupapi.h
|
|
||||||
* Copyright (c) EnterpriseDB Corporation, 2010-2021
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <json-c/json.h>
|
|
||||||
|
|
||||||
typedef struct operation_task {
|
|
||||||
char *backup_id;
|
|
||||||
char *destination_directory;
|
|
||||||
char *operation_type;
|
|
||||||
char *operation_id;
|
|
||||||
char *operation_status;
|
|
||||||
char *remote_ssh_command;
|
|
||||||
char *host;
|
|
||||||
char *node_name;
|
|
||||||
} operation_task;
|
|
||||||
|
|
||||||
//Default simplebuffer size in most of operations
|
|
||||||
#define MAX_BUFFER_LENGTH 72
|
|
||||||
|
|
||||||
//Callbacks to send/receive data from pg-backup-api endpoints
|
|
||||||
size_t receive_operations_cb(void *content, size_t size, size_t nmemb, char *buffer);
|
|
||||||
size_t receive_operation_id(void *content, size_t size, size_t nmemb, char *buffer);
|
|
||||||
size_t receive_operation_status(void *content, size_t size, size_t nmemb, char *buffer);
|
|
||||||
|
|
||||||
//Functions that implement the logic and know what to do and how to comunnicate wuth the API
|
|
||||||
CURLcode get_operations_on_server(CURL *curl, operation_task *task);
|
|
||||||
CURLcode create_new_task(CURL *curl, operation_task *task);
|
|
||||||
CURLcode get_status_of_operation(CURL *curl, operation_task *task);
|
|
||||||
|
|
||||||
//Helper to make simpler to read the handler where we set the URL
|
|
||||||
char * define_base_url(operation_task *task);
|
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "repmgr.h"
|
#include "repmgr.h"
|
||||||
#include "dirutil.h"
|
#include "dirutil.h"
|
||||||
@@ -30,7 +29,7 @@
|
|||||||
|
|
||||||
#include "repmgr-client-global.h"
|
#include "repmgr-client-global.h"
|
||||||
#include "repmgr-action-standby.h"
|
#include "repmgr-action-standby.h"
|
||||||
#include "pgbackupapi.h"
|
|
||||||
|
|
||||||
typedef struct TablespaceDataListCell
|
typedef struct TablespaceDataListCell
|
||||||
{
|
{
|
||||||
@@ -114,7 +113,6 @@ static void check_recovery_type(PGconn *conn);
|
|||||||
static void initialise_direct_clone(t_node_info *local_node_record, t_node_info *upstream_node_record);
|
static void initialise_direct_clone(t_node_info *local_node_record, t_node_info *upstream_node_record);
|
||||||
static int run_basebackup(t_node_info *node_record);
|
static int run_basebackup(t_node_info *node_record);
|
||||||
static int run_file_backup(t_node_info *node_record);
|
static int run_file_backup(t_node_info *node_record);
|
||||||
static int run_pg_backupapi(t_node_info *node_record);
|
|
||||||
|
|
||||||
static void copy_configuration_files(bool delete_after_copy);
|
static void copy_configuration_files(bool delete_after_copy);
|
||||||
|
|
||||||
@@ -689,18 +687,19 @@ do_standby_clone(void)
|
|||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode != barman)
|
||||||
|
{
|
||||||
|
initialise_direct_clone(&local_node_record, &upstream_node_record);
|
||||||
|
}
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case pg_basebackup:
|
case pg_basebackup:
|
||||||
initialise_direct_clone(&local_node_record, &upstream_node_record);
|
|
||||||
log_notice(_("starting backup (using pg_basebackup)..."));
|
log_notice(_("starting backup (using pg_basebackup)..."));
|
||||||
break;
|
break;
|
||||||
case barman:
|
case barman:
|
||||||
log_notice(_("retrieving backup from Barman..."));
|
log_notice(_("retrieving backup from Barman..."));
|
||||||
break;
|
break;
|
||||||
case pg_backupapi:
|
|
||||||
log_notice(_("starting backup (using pg_backupapi)..."));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* should never reach here */
|
/* should never reach here */
|
||||||
log_error(_("unknown clone mode"));
|
log_error(_("unknown clone mode"));
|
||||||
@@ -722,9 +721,6 @@ do_standby_clone(void)
|
|||||||
case barman:
|
case barman:
|
||||||
r = run_file_backup(&local_node_record);
|
r = run_file_backup(&local_node_record);
|
||||||
break;
|
break;
|
||||||
case pg_backupapi:
|
|
||||||
r = run_pg_backupapi(&local_node_record);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* should never reach here */
|
/* should never reach here */
|
||||||
log_error(_("unknown clone mode"));
|
log_error(_("unknown clone mode"));
|
||||||
@@ -818,6 +814,7 @@ do_standby_clone(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the recovery.conf file */
|
/* Write the recovery.conf file */
|
||||||
|
|
||||||
if (create_recovery_file(&local_node_record,
|
if (create_recovery_file(&local_node_record,
|
||||||
&recovery_conninfo,
|
&recovery_conninfo,
|
||||||
source_server_version_num,
|
source_server_version_num,
|
||||||
@@ -849,9 +846,6 @@ do_standby_clone(void)
|
|||||||
case barman:
|
case barman:
|
||||||
log_notice(_("standby clone (from Barman) complete"));
|
log_notice(_("standby clone (from Barman) complete"));
|
||||||
break;
|
break;
|
||||||
case pg_backupapi:
|
|
||||||
log_notice(_("standby clone (from pg_backupapi) complete"));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -943,9 +937,6 @@ do_standby_clone(void)
|
|||||||
case barman:
|
case barman:
|
||||||
appendPQExpBufferStr(&event_details, "barman");
|
appendPQExpBufferStr(&event_details, "barman");
|
||||||
break;
|
break;
|
||||||
case pg_backupapi:
|
|
||||||
appendPQExpBufferStr(&event_details, "pg_backupapi");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(&event_details,
|
appendPQExpBuffer(&event_details,
|
||||||
@@ -7779,117 +7770,6 @@ stop_backup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform a call to pg_backupapi endpoint to ask barman to write the backup
|
|
||||||
* for us. This will ensure that no matter the format on-disk of new backups,
|
|
||||||
* barman will always find a way how to read and write them.
|
|
||||||
* From repmgr 4 this is only used for Barman backups.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
run_pg_backupapi(t_node_info *local_node_record)
|
|
||||||
{
|
|
||||||
int r = ERR_PGBACKUPAPI_SERVICE;
|
|
||||||
long http_return_code = 0;
|
|
||||||
short seconds_to_sleep = 3;
|
|
||||||
operation_task *task = malloc(sizeof(operation_task));
|
|
||||||
CURL *curl = curl_easy_init();
|
|
||||||
CURLcode ret;
|
|
||||||
|
|
||||||
check_pg_backupapi_standby_clone_options();
|
|
||||||
|
|
||||||
task->host = malloc(strlen(config_file_options.pg_backupapi_host)+1);
|
|
||||||
task->remote_ssh_command = malloc(strlen(config_file_options.pg_backupapi_remote_ssh_command)+1);
|
|
||||||
task->node_name = malloc(strlen(config_file_options.pg_backupapi_node_name)+1);
|
|
||||||
task->operation_type = malloc(strlen(DEFAULT_STANDBY_PG_BACKUPAPI_OP_TYPE)+1);
|
|
||||||
task->backup_id = malloc(strlen(config_file_options.pg_backupapi_backup_id)+1);
|
|
||||||
task->destination_directory = malloc(strlen(local_data_directory)+1);
|
|
||||||
|
|
||||||
task->operation_id = malloc(MAX_BUFFER_LENGTH);
|
|
||||||
task->operation_status = malloc(MAX_BUFFER_LENGTH);
|
|
||||||
|
|
||||||
strcpy(task->host, config_file_options.pg_backupapi_host);
|
|
||||||
strcpy(task->remote_ssh_command, config_file_options.pg_backupapi_remote_ssh_command);
|
|
||||||
strcpy(task->node_name, config_file_options.pg_backupapi_node_name);
|
|
||||||
strcpy(task->operation_type, DEFAULT_STANDBY_PG_BACKUPAPI_OP_TYPE);
|
|
||||||
strcpy(task->backup_id, config_file_options.pg_backupapi_backup_id);
|
|
||||||
strcpy(task->destination_directory, local_data_directory);
|
|
||||||
strcpy(task->operation_id, "\0");
|
|
||||||
|
|
||||||
ret = create_new_task(curl, task);
|
|
||||||
|
|
||||||
if ((ret != CURLE_OK) || (strlen(task->operation_id) == 0)) {
|
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_return_code);
|
|
||||||
if (499 > http_return_code && http_return_code >= 400) {
|
|
||||||
log_error("Cannot find backup '%s' for node '%s'.", task->backup_id, task->node_name);
|
|
||||||
} else {
|
|
||||||
log_error("whilst reaching out pg_backup service: %s\n", curl_easy_strerror(ret));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_info("Success creating the task: operation id '%s'", task->operation_id);
|
|
||||||
|
|
||||||
//We call init again because previous call included POST calls
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl = curl_easy_init();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
ret = get_status_of_operation(curl, task);
|
|
||||||
if (strlen(task->operation_status) == 0) {
|
|
||||||
log_info("Retrying...");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_info("status %s", task->operation_status);
|
|
||||||
}
|
|
||||||
if (strcmp(task->operation_status, "FAILED") == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (strcmp(task->operation_status, "DONE") == 0) {
|
|
||||||
r = SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep(seconds_to_sleep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
free(task);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pg_backupapi mode is enabled when config_file_options.pg_backupapi_host is set hence, we
|
|
||||||
* should also check the other required variables too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void check_pg_backupapi_standby_clone_options() {
|
|
||||||
|
|
||||||
bool error = false;
|
|
||||||
|
|
||||||
if (*config_file_options.pg_backupapi_remote_ssh_command == '\0') {
|
|
||||||
log_hint("Check config: remote ssh command is required");
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
if (*config_file_options.pg_backupapi_node_name == '\0') {
|
|
||||||
log_hint("Check config: node name is required");
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
if (*config_file_options.pg_backupapi_backup_id == '\0') {
|
|
||||||
log_hint("Check config: backup_id is required");
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == true) {
|
|
||||||
log_error("Please fix the errors and try again");
|
|
||||||
exit(ERR_BAD_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
make_barman_ssh_command(char *buf)
|
make_barman_ssh_command(char *buf)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ extern void do_standby_help(void);
|
|||||||
|
|
||||||
extern bool do_standby_follow_internal(PGconn *primary_conn, PGconn *follow_target_conn, t_node_info *follow_target_node_record, PQExpBufferData *output, int general_error_code, int *error_code);
|
extern bool do_standby_follow_internal(PGconn *primary_conn, PGconn *follow_target_conn, t_node_info *follow_target_node_record, PQExpBufferData *output, int general_error_code, int *error_code);
|
||||||
|
|
||||||
void check_pg_backupapi_standby_clone_options(void);
|
|
||||||
|
|
||||||
#endif /* _REPMGR_ACTION_STANDBY_H_ */
|
#endif /* _REPMGR_ACTION_STANDBY_H_ */
|
||||||
|
|||||||
@@ -193,8 +193,7 @@ typedef struct
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
barman,
|
barman,
|
||||||
pg_basebackup,
|
pg_basebackup
|
||||||
pg_backupapi
|
|
||||||
} standy_clone_mode;
|
} standy_clone_mode;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|||||||
@@ -3096,14 +3096,9 @@ get_standby_clone_mode(void)
|
|||||||
|
|
||||||
if (*config_file_options.barman_host != '\0' && runtime_options.without_barman == false)
|
if (*config_file_options.barman_host != '\0' && runtime_options.without_barman == false)
|
||||||
mode = barman;
|
mode = barman;
|
||||||
else {
|
|
||||||
if (*config_file_options.pg_backupapi_host != '\0') {
|
|
||||||
log_info("Attempting to use `pg_backupapi` new restore mode");
|
|
||||||
mode = pg_backupapi;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
mode = pg_basebackup;
|
mode = pg_basebackup;
|
||||||
}
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3639,7 +3634,7 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
|
|||||||
/* "full_page_writes" must be on in any case */
|
/* "full_page_writes" must be on in any case */
|
||||||
if (guc_set(conn, "full_page_writes", "=", "off"))
|
if (guc_set(conn, "full_page_writes", "=", "off"))
|
||||||
{
|
{
|
||||||
appendPQExpBufferStr(reason,
|
appendPQExpBuffer(reason,
|
||||||
_("\"full_page_writes\" must be set to \"on\""));
|
_("\"full_page_writes\" must be set to \"on\""));
|
||||||
|
|
||||||
can_use = false;
|
can_use = false;
|
||||||
@@ -3658,18 +3653,18 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
|
|||||||
if (data_checksum_version == UNKNOWN_DATA_CHECKSUM_VERSION)
|
if (data_checksum_version == UNKNOWN_DATA_CHECKSUM_VERSION)
|
||||||
{
|
{
|
||||||
if (can_use == false)
|
if (can_use == false)
|
||||||
appendPQExpBufferStr(reason, "; ");
|
appendPQExpBuffer(reason, "; ");
|
||||||
|
|
||||||
appendPQExpBufferStr(reason,
|
appendPQExpBuffer(reason,
|
||||||
_("\"wal_log_hints\" is set to \"off\" but unable to determine data checksum version"));
|
_("\"wal_log_hints\" is set to \"off\" but unable to determine data checksum version"));
|
||||||
can_use = false;
|
can_use = false;
|
||||||
}
|
}
|
||||||
else if (data_checksum_version == 0)
|
else if (data_checksum_version == 0)
|
||||||
{
|
{
|
||||||
if (can_use == false)
|
if (can_use == false)
|
||||||
appendPQExpBufferStr(reason, "; ");
|
appendPQExpBuffer(reason, "; ");
|
||||||
|
|
||||||
appendPQExpBufferStr(reason,
|
appendPQExpBuffer(reason,
|
||||||
_("\"wal_log_hints\" is set to \"off\" and data checksums are disabled"));
|
_("\"wal_log_hints\" is set to \"off\" and data checksums are disabled"));
|
||||||
|
|
||||||
can_use = false;
|
can_use = false;
|
||||||
@@ -3878,17 +3873,19 @@ drop_replication_slot_if_exists(PGconn *conn, int node_id, char *slot_name)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool use_replication_protocol = false;
|
bool use_replication_protocol = false;
|
||||||
PGconn *slot_conn = _get_replication_slot_connection(conn,
|
PGconn *slot_conn = NULL;
|
||||||
|
|
||||||
|
slot_conn = _get_replication_slot_connection(conn,
|
||||||
replication_user,
|
replication_user,
|
||||||
&use_replication_protocol);
|
&use_replication_protocol);
|
||||||
|
|
||||||
if (use_replication_protocol == true)
|
if (use_replication_protocol == true)
|
||||||
{
|
{
|
||||||
success = drop_replication_slot_replprot(slot_conn, slot_name);
|
success = drop_replication_slot_replprot(conn, slot_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
success = drop_replication_slot_sql(slot_conn, slot_name);
|
success = drop_replication_slot_sql(conn, slot_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success == true)
|
if (success == true)
|
||||||
@@ -3968,15 +3965,11 @@ _determine_replication_slot_user(PGconn *conn, t_node_info *upstream_node_record
|
|||||||
/* This should never happen */
|
/* This should never happen */
|
||||||
log_error("unable to determine replication slot user");
|
log_error("unable to determine replication slot user");
|
||||||
if (upstream_node_record != NULL)
|
if (upstream_node_record != NULL)
|
||||||
{
|
|
||||||
log_debug("%i %s %s", upstream_node_record->node_id, upstream_node_record->repluser, PQuser(conn));
|
log_debug("%i %s %s", upstream_node_record->node_id, upstream_node_record->repluser, PQuser(conn));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
log_debug("upstream_node_record not provided");
|
log_debug("upstream_node_record not provided");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3991,12 +3984,12 @@ _get_replication_slot_connection(PGconn *conn, char *replication_user, bool *use
|
|||||||
switch (ReplicationSlotUser)
|
switch (ReplicationSlotUser)
|
||||||
{
|
{
|
||||||
case USER_TYPE_UNKNOWN:
|
case USER_TYPE_UNKNOWN:
|
||||||
log_error("unable to determine user for managing replication slots");
|
log_error("unable to determine user for replication slot creation");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case REPMGR_USER:
|
case REPMGR_USER:
|
||||||
slot_conn = conn;
|
slot_conn = conn;
|
||||||
log_verbose(LOG_INFO, _("managing replication slot as user \"%s\""),
|
log_info(_("creating replication slot as user \"%s\""),
|
||||||
PQuser(conn));
|
PQuser(conn));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4008,7 +4001,7 @@ _get_replication_slot_connection(PGconn *conn, char *replication_user, bool *use
|
|||||||
true);
|
true);
|
||||||
if (slot_conn == NULL || PQstatus(slot_conn) != CONNECTION_OK)
|
if (slot_conn == NULL || PQstatus(slot_conn) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
log_error(_("unable to manage replication connection as replication user \"%s\""),
|
log_error(_("unable to create replication connection as user \"%s\""),
|
||||||
runtime_options.replication_user);
|
runtime_options.replication_user);
|
||||||
log_detail("%s", PQerrorMessage(slot_conn));
|
log_detail("%s", PQerrorMessage(slot_conn));
|
||||||
|
|
||||||
@@ -4016,7 +4009,7 @@ _get_replication_slot_connection(PGconn *conn, char *replication_user, bool *use
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*use_replication_protocol = true;
|
*use_replication_protocol = true;
|
||||||
log_verbose(LOG_INFO, _("managing replication slot as replication user \"%s\""),
|
log_info(_("creating replication slot as replication user \"%s\""),
|
||||||
replication_user);
|
replication_user);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4028,7 +4021,7 @@ _get_replication_slot_connection(PGconn *conn, char *replication_user, bool *use
|
|||||||
false);
|
false);
|
||||||
if (slot_conn == NULL || PQstatus(slot_conn )!= CONNECTION_OK)
|
if (slot_conn == NULL || PQstatus(slot_conn )!= CONNECTION_OK)
|
||||||
{
|
{
|
||||||
log_error(_("unable to create superuser connection as user \"%s\""),
|
log_error(_("unable to create super connection as user \"%s\""),
|
||||||
runtime_options.superuser);
|
runtime_options.superuser);
|
||||||
log_detail("%s", PQerrorMessage(slot_conn));
|
log_detail("%s", PQerrorMessage(slot_conn));
|
||||||
|
|
||||||
@@ -4036,7 +4029,7 @@ _get_replication_slot_connection(PGconn *conn, char *replication_user, bool *use
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
log_verbose(LOG_INFO, _("creating replication slot as superuser \"%s\""),
|
log_info(_("creating replication slot as superuser \"%s\""),
|
||||||
runtime_options.superuser);
|
runtime_options.superuser);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
18
repmgr.c
18
repmgr.c
@@ -86,6 +86,7 @@ static shmem_request_hook_type prev_shmem_request_hook = NULL;
|
|||||||
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
|
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
|
||||||
|
|
||||||
void _PG_init(void);
|
void _PG_init(void);
|
||||||
|
void _PG_fini(void);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= 150000)
|
#if (PG_VERSION_NUM >= 150000)
|
||||||
static void repmgr_shmem_request(void);
|
static void repmgr_shmem_request(void);
|
||||||
@@ -144,6 +145,21 @@ _PG_init(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module unload callback
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_PG_fini(void)
|
||||||
|
{
|
||||||
|
/* Uninstall hook */
|
||||||
|
#if (PG_VERSION_NUM >= 150000)
|
||||||
|
shmem_request_hook = prev_shmem_request_hook;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shmem_startup_hook = prev_shmem_startup_hook;
|
||||||
|
}
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= 150000)
|
#if (PG_VERSION_NUM >= 150000)
|
||||||
/*
|
/*
|
||||||
* shmem_requst_hook: request shared memory
|
* shmem_requst_hook: request shared memory
|
||||||
@@ -161,7 +177,7 @@ repmgr_shmem_request(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shmem_startup hook: allocate or attach to shared memory
|
* shmem_ hook: allocate or attach to shared memory,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
repmgr_shmem_startup(void)
|
repmgr_shmem_startup(void)
|
||||||
|
|||||||
1
repmgr.h
1
repmgr.h
@@ -116,7 +116,6 @@
|
|||||||
#define DEFAULT_STANDBY_FOLLOW_TIMEOUT 30 /* seconds */
|
#define DEFAULT_STANDBY_FOLLOW_TIMEOUT 30 /* seconds */
|
||||||
#define DEFAULT_STANDBY_FOLLOW_RESTART false
|
#define DEFAULT_STANDBY_FOLLOW_RESTART false
|
||||||
#define DEFAULT_SHUTDOWN_CHECK_TIMEOUT 60 /* seconds */
|
#define DEFAULT_SHUTDOWN_CHECK_TIMEOUT 60 /* seconds */
|
||||||
#define DEFAULT_STANDBY_PG_BACKUPAPI_OP_TYPE "recovery"
|
|
||||||
#define DEFAULT_STANDBY_RECONNECT_TIMEOUT 60 /* seconds */
|
#define DEFAULT_STANDBY_RECONNECT_TIMEOUT 60 /* seconds */
|
||||||
#define DEFAULT_NODE_REJOIN_TIMEOUT 60 /* seconds */
|
#define DEFAULT_NODE_REJOIN_TIMEOUT 60 /* seconds */
|
||||||
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
|
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
|
||||||
|
|||||||
@@ -1587,7 +1587,7 @@ monitor_streaming_standby(void)
|
|||||||
/* TODO: possibly add pre-action event here */
|
/* TODO: possibly add pre-action event here */
|
||||||
if (upstream_node_info.type == STANDBY)
|
if (upstream_node_info.type == STANDBY)
|
||||||
{
|
{
|
||||||
create_event_notification(primary_conn,
|
create_event_record(primary_conn,
|
||||||
&config_file_options,
|
&config_file_options,
|
||||||
config_file_options.node_id,
|
config_file_options.node_id,
|
||||||
"repmgrd_upstream_disconnect",
|
"repmgrd_upstream_disconnect",
|
||||||
@@ -1597,7 +1597,7 @@ monitor_streaming_standby(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* primary connection lost - script notification only */
|
/* primary connection lost - script notification only */
|
||||||
create_event_notification(NULL,
|
create_event_record(NULL,
|
||||||
&config_file_options,
|
&config_file_options,
|
||||||
config_file_options.node_id,
|
config_file_options.node_id,
|
||||||
"repmgrd_upstream_disconnect",
|
"repmgrd_upstream_disconnect",
|
||||||
@@ -2482,7 +2482,7 @@ monitor_streaming_witness(void)
|
|||||||
_("unable to connect to primary node \"%s\" (ID: %i)"),
|
_("unable to connect to primary node \"%s\" (ID: %i)"),
|
||||||
upstream_node_info.node_name, upstream_node_info.node_id);
|
upstream_node_info.node_name, upstream_node_info.node_id);
|
||||||
|
|
||||||
create_event_notification(NULL,
|
create_event_record(NULL,
|
||||||
&config_file_options,
|
&config_file_options,
|
||||||
config_file_options.node_id,
|
config_file_options.node_id,
|
||||||
"repmgrd_upstream_disconnect",
|
"repmgrd_upstream_disconnect",
|
||||||
|
|||||||
Reference in New Issue
Block a user