Use pg_rewind with --restore-target-wal on 13 if possible (#1525)

On PostgreSQL 13 check if restore_command is configured and tell pg_rewind to use it
This commit is contained in:
Alexander Kukushkin
2020-05-15 16:05:07 +02:00
committed by GitHub
parent e6ef3c340a
commit 285bffc68d
3 changed files with 20 additions and 4 deletions
+9
View File
@@ -653,6 +653,15 @@ class Postgresql(object):
return False
return True
def get_guc_value(self, name):
cmd = [self.pgcommand('postgres'), self._data_dir, '-C', name]
try:
data = subprocess.check_output(cmd)
if data:
return data.decode('utf-8').strip()
except Exception as e:
logger.error('Failed to execute %s: %r', cmd, e)
def controldata(self):
""" return the contents of pg_controldata, or non-True value if pg_controldata call failed """
# Don't try to call pg_controldata during backup restore
+6 -2
View File
@@ -173,9 +173,13 @@ class Rewind(object):
env['PGOPTIONS'] = '-c statement_timeout=0'
dsn = self._postgresql.config.format_dsn(r, True)
logger.info('running pg_rewind from %s', dsn)
cmd = [self._postgresql.pgcommand('pg_rewind')]
if self._postgresql.major_version >= 130000 and self._postgresql.get_guc_value('restore_command'):
cmd.append('--restore-target-wal')
cmd.extend(['-D', self._postgresql.data_dir, '--source-server', dsn])
try:
return self._postgresql.cancellable.call([self._postgresql.pgcommand('pg_rewind'), '-D',
self._postgresql.data_dir, '--source-server', dsn], env=env) == 0
return self._postgresql.cancellable.call(cmd, env=env) == 0
except OSError:
return False
+5 -2
View File
@@ -35,13 +35,16 @@ class TestRewind(BaseTestPostgresql):
self.p.config._config['use_pg_rewind'] = False
self.assertFalse(self.r.can_rewind)
@patch.object(Postgresql, 'major_version', PropertyMock(return_value=130000))
@patch.object(CancellableSubprocess, 'call')
def test_pg_rewind(self, mock_cancellable_subprocess_call):
r = {'user': '', 'host': '', 'port': '', 'database': '', 'password': ''}
mock_cancellable_subprocess_call.return_value = 0
self.assertTrue(self.r.pg_rewind(r))
with patch('subprocess.check_output', Mock(return_value=b'foo')):
self.assertTrue(self.r.pg_rewind(r))
mock_cancellable_subprocess_call.side_effect = OSError
self.assertFalse(self.r.pg_rewind(r))
with patch('subprocess.check_output', Mock(side_effect=Exception)):
self.assertFalse(self.r.pg_rewind(r))
@patch.object(Rewind, 'can_rewind', PropertyMock(return_value=True))
def test__get_local_timeline_lsn(self):