mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-31 16:49:46 +00:00
Use create_replica_methods from standby_cluster for replica bootstrap (#981)
It might happen that the standby cluster is configured to be created and replay WAL files from the different source than when it is running not in standby mode. This is necessary to avoid writing WAL files and backups into the old place after promotion. The easiest way to achieve such behavior is passing RemoteMember object to `Postgresql.clone` method instead of the usual Member object.
This commit is contained in:
+11
-4
@@ -206,6 +206,9 @@ class Ha(object):
|
||||
return self.dcs.touch_member(data)
|
||||
|
||||
def clone(self, clone_member=None, msg='(without leader)'):
|
||||
if self.is_standby_cluster() and not isinstance(clone_member, RemoteMember):
|
||||
clone_member = self.get_remote_member(clone_member)
|
||||
|
||||
if self.state_handler.clone(clone_member):
|
||||
logger.info('bootstrapped %s', msg)
|
||||
cluster = self.dcs.get_cluster()
|
||||
@@ -1341,7 +1344,7 @@ class Ha(object):
|
||||
This usually happens on the master or if the node is running async action"""
|
||||
self.dcs.event.set()
|
||||
|
||||
def get_remote_master(self):
|
||||
def get_remote_member(self, member=None):
|
||||
""" In case of standby cluster this will tel us from which remote
|
||||
master to stream. Config can be both patroni config or
|
||||
cluster.config.data
|
||||
@@ -1349,12 +1352,16 @@ class Ha(object):
|
||||
cluster_params = self.get_standby_cluster_config()
|
||||
|
||||
if cluster_params:
|
||||
unique_name = 'remote_master:{}'.format(uuid.uuid1())
|
||||
name = member.name if member else 'remote_master:{}'.format(uuid.uuid1())
|
||||
|
||||
data = {k: v for k, v in cluster_params.items() if k in RemoteMember.allowed_keys()}
|
||||
data['no_replication_slot'] = 'primary_slot_name' not in cluster_params
|
||||
conn_kwargs = {k: cluster_params[k] for k in ('host', 'port') if k in cluster_params}
|
||||
conn_kwargs = member.conn_kwargs() if member else \
|
||||
{k: cluster_params[k] for k in ('host', 'port') if k in cluster_params}
|
||||
if conn_kwargs:
|
||||
data['conn_kwargs'] = conn_kwargs
|
||||
|
||||
return RemoteMember(unique_name, data)
|
||||
return RemoteMember(name, data)
|
||||
|
||||
def get_remote_master(self):
|
||||
return self.get_remote_member()
|
||||
|
||||
+2
-1
@@ -211,7 +211,8 @@ class TestHa(unittest.TestCase):
|
||||
self.assertEqual(self.ha.run_cycle(), 'trying to bootstrap a new standby leader')
|
||||
|
||||
@patch.object(Cluster, 'get_clone_member',
|
||||
Mock(return_value=Member(0, 'test', 1, {'api_url': 'http://127.0.0.1:8011/patroni'})))
|
||||
Mock(return_value=Member(0, 'test', 1, {'api_url': 'http://127.0.0.1:8011/patroni',
|
||||
'conn_url': 'postgres://127.0.0.1:5432/postgres'})))
|
||||
@patch.object(Postgresql, 'create_replica', Mock(return_value=0))
|
||||
def test_start_as_cascade_replica_in_standby_cluster(self):
|
||||
self.p.data_directory_empty = true
|
||||
|
||||
Reference in New Issue
Block a user