mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Restore recovery GUCs when joining running standby (#2998)
Close https://github.com/zalando/patroni/issues/2993
This commit is contained in:
@@ -336,12 +336,24 @@ class ConfigHandler(object):
|
||||
|
||||
def load_current_server_parameters(self) -> None:
|
||||
"""Read GUC's values from ``pg_settings`` when Patroni is joining the the postgres that is already running."""
|
||||
exclude = [name.lower() for name, value in self.CMDLINE_OPTIONS.items() if value[1] == _false_validator] \
|
||||
+ [name.lower() for name in self._RECOVERY_PARAMETERS]
|
||||
self._server_parameters = CaseInsensitiveDict({r[0]: r[1] for r in self._postgresql.query(
|
||||
exclude = [name.lower() for name, value in self.CMDLINE_OPTIONS.items() if value[1] == _false_validator]
|
||||
keep_values = {k: self._server_parameters[k] for k in exclude}
|
||||
server_parameters = CaseInsensitiveDict({r[0]: r[1] for r in self._postgresql.query(
|
||||
"SELECT name, pg_catalog.current_setting(name) FROM pg_catalog.pg_settings"
|
||||
" WHERE (source IN ('command line', 'environment variable') OR sourcefile = %s)"
|
||||
" AND pg_catalog.lower(name) != ALL(%s)", self._postgresql_conf, exclude)})
|
||||
recovery_params = CaseInsensitiveDict({k: server_parameters.pop(k) for k in self._RECOVERY_PARAMETERS
|
||||
if k in server_parameters})
|
||||
# We also want to load current settings of recovery parameters, including primary_conninfo
|
||||
# and primary_slot_name, otherwise patronictl restart will update postgresql.conf
|
||||
# and remove them, what in the worst case will cause another restart.
|
||||
# We are doing it only for PostgresSQL v12 onwards, because older version still have recovery.conf
|
||||
if not self._postgresql.is_primary() and self._postgresql.major_version >= 120000:
|
||||
# primary_conninfo is expected to be a dict, therefore we need to parse it
|
||||
recovery_params['primary_conninfo'] = parse_dsn(recovery_params.pop('primary_conninfo', '')) or {}
|
||||
self._recovery_params = recovery_params
|
||||
|
||||
self._server_parameters = CaseInsensitiveDict({**server_parameters, **keep_values})
|
||||
|
||||
def setup_server_parameters(self) -> None:
|
||||
self._server_parameters = self.get_server_parameters(self._config)
|
||||
|
||||
@@ -18,6 +18,7 @@ from patroni.exceptions import PostgresConnectionException, PatroniException
|
||||
from patroni.postgresql import Postgresql, STATE_REJECT, STATE_NO_RESPONSE
|
||||
from patroni.postgresql.bootstrap import Bootstrap
|
||||
from patroni.postgresql.callback_executor import CallbackAction
|
||||
from patroni.postgresql.config import _false_validator
|
||||
from patroni.postgresql.postmaster import PostmasterProcess
|
||||
from patroni.postgresql.validator import (ValidatorFactoryNoType, ValidatorFactoryInvalidType,
|
||||
ValidatorFactoryInvalidSpec, ValidatorFactory, InvalidGucValidatorsFile,
|
||||
@@ -1058,3 +1059,14 @@ class TestPostgresql2(BaseTestPostgresql):
|
||||
self.assertIn('diff(pg_catalog.pg_current_xlog_flush_location(', self.p.cluster_info_query)
|
||||
self.p._major_version = 90500
|
||||
self.assertIn('diff(pg_catalog.pg_current_xlog_location(', self.p.cluster_info_query)
|
||||
|
||||
@patch.object(Postgresql, 'is_primary', Mock(return_value=False))
|
||||
@patch.object(Postgresql, '_query', Mock(return_value=[('primary_conninfo', 'host=a port=5433 passfile=/blabla')]))
|
||||
def test_load_current_server_parameters(self):
|
||||
keep_values = {name: self.p.config._server_parameters[name]
|
||||
for name, value in self.p.config.CMDLINE_OPTIONS.items() if value[1] == _false_validator}
|
||||
self.p.config.load_current_server_parameters()
|
||||
self.assertTrue(all(self.p.config._server_parameters[name] == value for name, value in keep_values.items()))
|
||||
self.assertEqual(dict(self.p.config._recovery_params),
|
||||
{'primary_conninfo': {'host': 'a', 'port': '5433', 'passfile': '/blabla',
|
||||
'gssencmode': 'prefer', 'sslmode': 'prefer', 'channel_binding': 'prefer'}})
|
||||
|
||||
Reference in New Issue
Block a user