From 7626b5fef8ef18feab477354006a56b46a47436e Mon Sep 17 00:00:00 2001 From: "Gunnar \"Nick\" Bluth" Date: Thu, 24 Mar 2022 13:56:16 +0100 Subject: [PATCH] Fix pg_rewind on typical Debian/Ubuntu systems (#2225) On Debian/Ubuntu systems it is common to keep Postgres config files outside of the data directory. It created a couple of problems for pg_rewind support in Patroni. 1. The `--config_file` argument must be supplied while figuring out the `restore_command` GUC value on Postgres v12+ 2. With Postgres v13+ pg_rewind by itself can't find postgresql.conf in order to figure out `restore_command` and therefore we have to use Patroni as a fallback for fetching missing WAL's that are required for rewind. This commit addresses both problems. --- patroni/postgresql/__init__.py | 3 ++- patroni/postgresql/rewind.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/patroni/postgresql/__init__.py b/patroni/postgresql/__init__.py index aeadc3e9..3b9f2507 100644 --- a/patroni/postgresql/__init__.py +++ b/patroni/postgresql/__init__.py @@ -798,7 +798,8 @@ class Postgresql(object): return True def get_guc_value(self, name): - cmd = [self.pgcommand('postgres'), '-D', self._data_dir, '-C', name] + cmd = [self.pgcommand('postgres'), '-D', self._data_dir, '-C', name, + '--config-file={}'.format(self.config.postgresql_conf)] try: data = subprocess.check_output(cmd) if data: diff --git a/patroni/postgresql/rewind.py b/patroni/postgresql/rewind.py index fb754f58..5a2e4a39 100644 --- a/patroni/postgresql/rewind.py +++ b/patroni/postgresql/rewind.py @@ -311,8 +311,14 @@ class Rewind(object): restore_command = self._postgresql.config.get('recovery_conf', {}).get('restore_command') \ if self._postgresql.major_version < 120000 else self._postgresql.get_guc_value('restore_command') + # currently, pg_rewind expects postgresql.conf to be inside $PGDATA, which is not the case on e.g. Debian + # Fix this logic if e.g. PG15 receives an update for pg_rewind: + pg_rewind_can_restore = self._postgresql.major_version >= 130000 \ + and restore_command \ + and self._postgresql.config._config_dir == self._postgresql.data_dir + cmd = [self._postgresql.pgcommand('pg_rewind')] - if self._postgresql.major_version >= 130000 and restore_command: + if pg_rewind_can_restore: cmd.append('--restore-target-wal') cmd.extend(['-D', self._postgresql.data_dir, '--source-server', dsn]) @@ -329,7 +335,7 @@ class Rewind(object): if ret == 0: return True - if not restore_command or self._postgresql.major_version >= 130000: + if not restore_command or pg_rewind_can_restore: return False missing_wal = self._find_missing_wal(results['stderr']) or self._find_missing_wal(results['stdout'])