Explicitly enable synchronous mode (#2820)

Close https://github.com/zalando/patroni/issues/2819

Co-authored-by: Polina Bungina <[email protected]>
This commit is contained in:
Alexander Kukushkin
2023-08-17 12:33:15 +02:00
committed by GitHub
co-authored by Polina Bungina
parent 4138d0b830
commit 704d36815a
2 changed files with 24 additions and 2 deletions
+11 -2
View File
@@ -656,11 +656,20 @@ class Ha(object):
promoting standbys that were guaranteed to be replicating synchronously.
"""
if self.is_synchronous_mode():
current = CaseInsensitiveSet(self.cluster.sync.members)
sync = self.cluster.sync
if sync.is_empty:
# corner case: we need to explicitly enable synchronous mode by updating the
# ``/sync`` key with the current leader name and empty members. In opposite case
# it will never be automatically enabled if there are not eligible candidates.
sync = self.dcs.write_sync_state(self.state_handler.name, None, version=sync.version)
if not sync:
return logger.warning("Updating sync state failed")
logger.info("Enabled synchronous replication")
current = CaseInsensitiveSet(sync.members)
picked, allow_promote = self.state_handler.sync_handler.current_state(self.cluster)
if picked != current:
sync = self.cluster.sync
# update synchronous standby list in dcs temporarily to point to common nodes in current and picked
sync_common = current & allow_promote
if sync_common != current:
+13
View File
@@ -1294,6 +1294,19 @@ class TestHa(PostgresInit):
mock_restart.assert_called_once()
self.ha.dcs.get_cluster.assert_not_called()
def test_enable_synchronous_mode(self):
self.ha.is_synchronous_mode = true
self.ha.has_lock = true
self.p.name = 'leader'
self.ha.dcs.write_sync_state = Mock(return_value=SyncState.empty())
with patch('patroni.ha.logger.info') as mock_logger:
self.ha.run_cycle()
self.assertEqual(mock_logger.call_args[0][0], 'Enabled synchronous replication')
self.ha.dcs.write_sync_state = Mock(return_value=None)
with patch('patroni.ha.logger.warning') as mock_logger:
self.ha.run_cycle()
self.assertEqual(mock_logger.call_args[0][0], 'Updating sync state failed')
def test_effective_tags(self):
self.ha._disable_sync = True
self.assertEqual(self.ha.get_effective_tags(), {'foo': 'bar', 'nosync': True})