Handle the case when initialize flag is not set and leader is present.

This commit is contained in:
Oleksii Kliukin
2015-09-14 12:36:28 +02:00
parent be110c4ba0
commit 51eacc5042
3 changed files with 62 additions and 16 deletions
+20 -14
View File
@@ -6,6 +6,7 @@ import yaml
from patroni.api import RestApiServer
from patroni.etcd import Etcd
from patroni.exceptions import DCSError
from patroni.ha import Ha
from patroni.postgresql import Postgresql
from patroni.utils import setup_signal_handlers, sleep, reap_children
@@ -59,21 +60,26 @@ class Patroni:
# is data directory empty?
if self.postgresql.data_directory_empty():
while True:
# racing to initialize
if self.ha.dcs.initialize():
try:
self.postgresql.bootstrap()
except:
# bail out and clean the initialize flag.
self.cleanup_on_failed_initialization()
raise
self.ha.dcs.take_leader()
break
else:
leader = self.ha.dcs.current_leader()
if leader and self.postgresql.bootstrap(leader):
try:
cluster = self.ha.dcs.get_cluster()
if not cluster.is_unlocked(): # the leader already exists
if not cluster.initialize:
self.ha.dcs.initialize()
self.postgresql.bootstrap(cluster.leader)
break
sleep(5)
# racing to initialize
elif not cluster.initialize and self.ha.dcs.initialize():
try:
self.postgresql.bootstrap()
except:
# bail out and clean the initialize flag.
self.cleanup_on_failed_initialization()
raise
self.ha.dcs.take_leader()
break
except DCSError:
logger.info('waiting on DCS')
sleep(5)
elif self.postgresql.is_running():
self.postgresql.load_replication_slots()
+35 -2
View File
@@ -9,7 +9,7 @@ import yaml
from mock import Mock, patch
from patroni.api import RestApiServer
from patroni.dcs import Cluster, Member
from patroni.dcs import Cluster, Member, Leader
from patroni.etcd import Etcd
from patroni.exceptions import PostgresException
from patroni import Patroni, main
@@ -42,6 +42,30 @@ class Mock_BaseServer__is_shut_down:
pass
def get_cluster(initialize, leader):
return Cluster(initialize, leader, None, None)
def get_cluster_not_initialized_without_leader():
return get_cluster(None, None)
def get_cluster_initialized_without_leader():
return get_cluster(True, None)
def get_cluster_not_initialized_with_leader():
return get_cluster(False, Leader(0, 0, 0,
Member(0, 'leader', 'postgres://replicator:[email protected]:5435/postgres',
None, None, 28)))
def get_cluster_initialized_with_leader():
return get_cluster(True, Leader(0, 0, 0,
Member(0, 'leader', 'postgres://replicator:[email protected]:5435/postgres',
None, None, 28)))
class TestPatroni(unittest.TestCase):
def __init__(self, method_name='runTest'):
@@ -129,24 +153,31 @@ class TestPatroni(unittest.TestCase):
def test_patroni_initialize(self):
self.p.ha.dcs.client.write = etcd_write
self.p.ha.dcs.client.read = etcd_read
self.p.touch_member = self.touch_member
self.p.postgresql.data_directory_empty = true
self.p.ha.dcs.initialize = true
self.p.postgresql.initialize = true
self.p.postgresql.start = true
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_without_leader
self.p.initialize()
self.p.ha.dcs.initialize = false
self.p.ha.dcs.get_cluster = get_cluster_initialized_with_leader
time.sleep = time_sleep
self.p.ha.dcs.client.read = etcd_read
self.p.initialize()
self.p.ha.dcs.current_leader = nop
self.p.ha.dcs.get_cluster = get_cluster_initialized_without_leader
self.assertRaises(SleepException, self.p.initialize)
self.p.postgresql.data_directory_empty = false
self.p.initialize()
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_with_leader
self.p.postgresql.data_directory_empty = true
self.p.initialize()
def test_schedule_next_run(self):
self.p.next_run = time.time() - self.p.nap_time - 1
self.p.schedule_next_run()
@@ -156,6 +187,8 @@ class TestPatroni(unittest.TestCase):
def test_cleanup_on_initialization(self):
self.p.ha.dcs.client.write = etcd_write
self.p.ha.dcs.client.read = etcd_read
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_without_leader
self.p.touch_member = self.touch_member
self.p.postgresql.data_directory_empty = true
self.p.ha.dcs.initialize = true
+7
View File
@@ -6,6 +6,7 @@ import unittest
from patroni.dcs import Cluster, Leader, Member
from patroni.postgresql import Postgresql
from test_ha import true, false
def nop(*args, **kwargs):
@@ -217,3 +218,9 @@ class TestPostgresql(unittest.TestCase):
self.p.start()
self.p.query = self.mock_query
self.assertTrue(self.p.stop())
def test_move_data_directory(self):
self.p.is_running = is_running
os.rename = nop
os.path.isdir = true
self.p.move_data_directory()