From 30a9e0f7f5da186fdbc855f8f26d18bc6fde80b9 Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Thu, 10 Sep 2015 15:34:29 +0200 Subject: [PATCH] Move PostgreSQL data directory if init had failed. Prevent treating the incompletely-initialized PostgreSQL cluster as a valid on restart by forcefully moving the data directory. I don't want to remove it altogether, since a DBA might decide to analyze the failed PG cluster in order to resolve the init issue. --- patroni/__init__.py | 2 ++ patroni/postgresql.py | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/patroni/__init__.py b/patroni/__init__.py index b55c0dfc..6a4bf6aa 100644 --- a/patroni/__init__.py +++ b/patroni/__init__.py @@ -46,6 +46,8 @@ class Patroni: """ cleanup the DCS if initialization was not successfull """ logger.info("removing initialize key after failed attempt to initialize the cluster") self.ha.dcs.cancel_initialization() + self.postgresql.stop() + self.postgresql.move_data_directory() def initialize(self): # wait for etcd to be available diff --git a/patroni/postgresql.py b/patroni/postgresql.py index 8754bb65..3c1630a8 100644 --- a/patroni/postgresql.py +++ b/patroni/postgresql.py @@ -4,6 +4,7 @@ import psycopg2 import shlex import shutil import subprocess +import time from patroni.utils import sleep from six.moves.urllib_parse import urlparse @@ -159,7 +160,7 @@ class Postgresql: return ret def is_running(self): - return subprocess.call(' '.join(self._pg_ctl) + ' status > /dev/null', shell=True) == 0 + return subprocess.call(' '.join(self._pg_ctl) + ' status > /dev/null 2>&1', shell=True) == 0 def call_nowait(self, cb_name, is_leader=None): """ pick a callback command and call it without waiting for it to finish """ @@ -415,3 +416,9 @@ recovery_target_timeline = 'latest' self.write_recovery_conf(current_leader) ret = self.start() return ret + + def move_data_directory(self): + if os.path.isdir(self.data_dir) and not self.is_running(): + os.rename(self.data_dir, '{0}_{1}'.format(self.data_dir, str(long(time.time())))) + return True + return False