Standby cluster can't have synchronous nodes (#3079)

`synchronous_standby_names` and synchronous replication only work on a real primary node and in case of cascading replication simply ignored by Postgres.
This fact was already addressed by `global_config.is_synchronous_mode`, but in case if in a standby cluster the `/sync` key in DCS is not empty, `patronictl list` and `GET /cluster` were falsely reporting some nodes as synchronous because this check was missing.

Close https://github.com/zalando/patroni/issues/3078
This commit is contained in:
Alexander Kukushkin
2024-06-14 09:16:57 +02:00
committed by GitHub
parent 14a44e14ba
commit af03c619ec
2 changed files with 9 additions and 1 deletions
+1 -1
View File
@@ -952,7 +952,7 @@ def cluster_as_json(cluster: 'Cluster') -> Dict[str, Any]:
for m in cluster.members:
if m.name == leader_name:
role = 'standby_leader' if config.is_standby_cluster else 'leader'
elif cluster.sync.matches(m.name):
elif config.is_synchronous_mode and cluster.sync.matches(m.name):
role = 'sync_standby'
else:
role = 'replica'
+8
View File
@@ -503,6 +503,14 @@ class TestCtl(unittest.TestCase):
assert '2100' in result.output
assert 'Scheduled restart' in result.output
def test_list_standby_cluster(self):
cluster = get_cluster_initialized_without_leader(leader=True, sync=('leader', 'other'))
cluster.config.data.update(synchronous_mode=True, standby_cluster={'port': 5433})
with patch('patroni.dcs.AbstractDCS.get_cluster', Mock(return_value=cluster)):
result = self.runner.invoke(ctl, ['list'])
self.assertEqual(result.exit_code, 0)
self.assertNotIn('Sync Standby', result.output)
def test_topology(self):
cluster = get_cluster_initialized_with_leader()
cluster.members.append(Member(0, 'cascade', 28,