From b58ddc559ec3c2fff57dfbcc7c46178405ff4c55 Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Tue, 23 Aug 2016 17:29:21 +0200 Subject: [PATCH 1/2] Do not drop active replication slots. Master tried to delete all slots that did not correspond to the replica registered in Patroni. That produced an error for the slots that were active, potentially preventing drop and creation of other slots. Reported by Murat Kabilov. --- patroni/postgresql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patroni/postgresql.py b/patroni/postgresql.py index 7dff8b32..e04b8f45 100644 --- a/patroni/postgresql.py +++ b/patroni/postgresql.py @@ -884,7 +884,7 @@ $$""".format(name, ' '.join(options)), name, password, password) for slot in set(self._replication_slots) - set(slots): self.query("""SELECT pg_drop_replication_slot(%s) WHERE EXISTS(SELECT 1 FROM pg_replication_slots - WHERE slot_name = %s)""", slot, slot) + WHERE slot_name = %s AND NOT active)""", slot, slot) # create new slots for slot in set(slots) - set(self._replication_slots): From 96da6340a942ef0959265d2bac3812565237e770 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Wed, 24 Aug 2016 09:46:56 +0200 Subject: [PATCH 2/2] Calculate future restart time dynamically (#268) `do_POST_restart` was ramdomly showing not 100% coverage after 2016-08-20 due to hardcoded timestamps. --- tests/test_api.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 1b36d34f..3e90346a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -188,7 +188,8 @@ class TestRestApiHandler(unittest.TestCase): post = request + '\nContent-Length: ' - def make_request(request): + def make_request(request=None, **kwargs): + request = json.dumps(kwargs) if request is None else request return '{0}{1}\n\n{2}'.format(post, len(request), request) # empty request @@ -198,26 +199,26 @@ class TestRestApiHandler(unittest.TestCase): request = make_request('foobar=baz') MockRestApiServer(RestApiHandler, request) # wrong role - request = make_request('{"schedule": "2016-08-20 12:45TZ+1", "role": "unknown", "postgres_version": "9.5.3"}') + request = make_request(schedule=future_restart_time.isoformat(), role='unknown', postgres_version='9.5.3') MockRestApiServer(RestApiHandler, request) # wrong version - request = make_request('{"schedule": "2016-08-20 12:45TZ+1", "role": "master", "postgres_version": "9.5.3.1"}') + request = make_request(schedule=future_restart_time.isoformat(), role='master', postgres_version='9.5.3.1') MockRestApiServer(RestApiHandler, request) # unknown filter - request = make_request('{"schedule": "2016-08-29 12:45TZ+1", "batman": "lives"}') + request = make_request(schedule=future_restart_time.isoformat(), batman='lives') MockRestApiServer(RestApiHandler, request) # incorrect schedule - request = make_request('{"schedule": "2016-08-42 12:45TZ+1", "role": "master"}') + request = make_request(schedule='2016-08-42 12:45TZ+1', role='master') MockRestApiServer(RestApiHandler, request) # everything fine, but the schedule is missing - request = make_request('{"role": "master", "postgres_version": "9.5.2"}') + request = make_request(role='master', postgres_version='9.5.2') MockRestApiServer(RestApiHandler, request) for retval in (True, False): with patch.object(MockHa, 'schedule_future_restart', Mock(return_value=retval)): - request = make_request('{"schedule": "2016-08-29 12:45TZ+1"}') + request = make_request(schedule=future_restart_time.isoformat()) MockRestApiServer(RestApiHandler, request) with patch.object(MockHa, 'restart', Mock(return_value=(retval, "foo"))): - request = make_request('{"role": "master", "postgres_version": "9.5.2"}') + request = make_request(role='master', postgres_version='9.5.2') MockRestApiServer(RestApiHandler, request) def test_do_DELETE_restart(self):