From 31d7540cc5914a744faf738c892f5718bc81a5c8 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Tue, 30 Nov 2021 14:20:03 +0100 Subject: [PATCH] Prefer members without nofailover when picking sync nodes (#2108) Previously sync nodes were selected only based on replication lag and hence the node with `nofailover` tag had the same chances to become synchronous as any other node. That behavior was confusing and dangerous at the same time, because in case of failed primary the failover couldn't happen automatically. Close https://github.com/zalando/patroni/issues/2089 --- patroni/postgresql/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/patroni/postgresql/__init__.py b/patroni/postgresql/__init__.py index 07d05a11..ab11a159 100644 --- a/patroni/postgresql/__init__.py +++ b/patroni/postgresql/__init__.py @@ -1107,11 +1107,12 @@ class Postgresql(object): " ORDER BY sync_state DESC, {0}_{1} DESC".format(sort_col, self.lsn_name, self.wal_name)): member = members.get(app_name) if member and not member.tags.get('nosync', False): - replica_list.append((member.name, sync_state, replica_lsn)) + replica_list.append((member.name, sync_state, replica_lsn, bool(member.nofailover))) max_lsn = max(replica_list, key=lambda x: x[2])[2] if len(replica_list) > 1 else int(str(self.last_operation())) - for app_name, sync_state, replica_lsn in replica_list: + # Prefer members without nofailover tag. We are relying on the fact that sorts are guaranteed to be stable. + for app_name, sync_state, replica_lsn, _ in sorted(replica_list, key=lambda x: x[3]): if sync_node_maxlag <= 0 or max_lsn - replica_lsn <= sync_node_maxlag: candidates.append(app_name) if sync_state == 'sync':