Make it possible to change use_slots online (#1261)

Previously it required restarting Patroni and removing slots manually
Fixes https://github.com/zalando/patroni/issues/1158
This commit is contained in:
Alexander Kukushkin
2019-11-11 16:18:53 +01:00
committed by GitHub
parent 5ea73d50ed
commit 252a1b78ed
3 changed files with 9 additions and 11 deletions
+4 -2
View File
@@ -442,14 +442,16 @@ class Cluster(namedtuple('Cluster', 'initialize,config,leader,last_leader_operat
# the current master, because that member would replicate from elsewhere. We still create the slot if
# the replicatefrom destination member is currently not a member of the cluster (fallback to the
# master), or if replicatefrom destination member happens to be the current master
use_slots = self.config and self.config.data.get('postgresql', {}).get('use_slots', True)
if role in ('master', 'standby_leader'):
slot_members = [m.name for m in self.members if m.name != name and
slot_members = [m.name for m in self.members if use_slots and m.name != name and
(m.replicatefrom is None or m.replicatefrom == name or
not self.has_member(m.replicatefrom))]
permanent_slots = (self.config and self.config.permanent_slots or {}).copy()
else:
# only manage slots for replicas that replicate from this one, except for the leader among them
slot_members = [m.name for m in self.members if m.replicatefrom == name and m.name != self.leader.name]
slot_members = [m.name for m in self.members if use_slots and
m.replicatefrom == name and m.name != self.leader.name]
permanent_slots = {}
slots = {slot_name_from_member_name(name): {'type': 'physical'} for name in slot_members}
+2 -1
View File
@@ -502,7 +502,8 @@ class ConfigHandler(object):
primary_conninfo = self.primary_conninfo_params(member)
if primary_conninfo:
recovery_params['primary_conninfo'] = primary_conninfo
if self._postgresql.slots_handler.use_slots and not (is_remote_master and member.no_replication_slot):
if self.get('use_slots', True) and self._postgresql.major_version >= 90400 \
and not (is_remote_master and member.no_replication_slot):
recovery_params['primary_slot_name'] = member.primary_slot_name if is_remote_master \
else slot_name_from_member_name(self._postgresql.name)
+3 -8
View File
@@ -15,19 +15,14 @@ class SlotsHandler(object):
def __init__(self, postgresql):
self._postgresql = postgresql
self._use_slots = postgresql.config.get('use_slots', True)
self._replication_slots = {} # already existing replication slots
self.schedule()
@property
def use_slots(self):
return self._use_slots and self._postgresql.major_version >= 90400
def _query(self, sql, *params):
return self._postgresql.query(sql, *params, retry=False)
def load_replication_slots(self):
if self.use_slots and self._schedule_load_slots:
if self._postgresql.major_version >= 90400 and self._schedule_load_slots:
replication_slots = {}
cursor = self._query('SELECT slot_name, slot_type, plugin, database FROM pg_catalog.pg_replication_slots')
for r in cursor:
@@ -45,7 +40,7 @@ class SlotsHandler(object):
return cursor.rowcount == 1
def sync_replication_slots(self, cluster):
if self.use_slots:
if self._postgresql.major_version >= 90400:
try:
self.load_replication_slots()
@@ -104,5 +99,5 @@ class SlotsHandler(object):
def schedule(self, value=None):
if value is None:
value = self.use_slots
value = self._postgresql.major_version >= 90400
self._schedule_load_slots = value