mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-09-01 00:59:24 +00:00
replace get_client_path("/members?recursive=true") with members()
replace do-plpgsq block by simple sql
79 lines
2.1 KiB
Python
Executable File
79 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import yaml
|
|
import time
|
|
import urllib2
|
|
import atexit
|
|
import logging
|
|
|
|
from helpers.etcd import Etcd
|
|
from helpers.postgresql import Postgresql
|
|
from helpers.ha import Ha
|
|
|
|
|
|
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO)
|
|
|
|
f = open(sys.argv[1], "r")
|
|
config = yaml.load(f.read())
|
|
f.close()
|
|
|
|
etcd = Etcd(config["etcd"])
|
|
postgresql = Postgresql(config["postgresql"])
|
|
ha = Ha(postgresql, etcd)
|
|
|
|
# stop postgresql on script exit
|
|
|
|
|
|
def stop_postgresql():
|
|
postgresql.stop()
|
|
atexit.register(stop_postgresql)
|
|
|
|
# wait for etcd to be available
|
|
etcd_ready = False
|
|
while not etcd_ready:
|
|
try:
|
|
etcd.touch_member(postgresql.name, postgresql.connection_string)
|
|
etcd_ready = True
|
|
except urllib2.URLError:
|
|
logging.info("waiting on etcd")
|
|
time.sleep(5)
|
|
|
|
# is data directory empty?
|
|
if postgresql.data_directory_empty():
|
|
# racing to initialize
|
|
if etcd.race("/initialize", postgresql.name):
|
|
postgresql.initialize()
|
|
etcd.take_leader(postgresql.name)
|
|
postgresql.start()
|
|
postgresql.create_replication_user()
|
|
else:
|
|
synced_from_leader = False
|
|
while not synced_from_leader:
|
|
leader = etcd.current_leader()
|
|
if not leader:
|
|
time.sleep(5)
|
|
continue
|
|
if postgresql.sync_from_leader(leader):
|
|
postgresql.write_recovery_conf(leader)
|
|
postgresql.start()
|
|
synced_from_leader = True
|
|
else:
|
|
time.sleep(5)
|
|
else:
|
|
postgresql.write_recovery_conf(None)
|
|
postgresql.start()
|
|
|
|
while True:
|
|
logging.info(ha.run_cycle())
|
|
|
|
# create replication slots
|
|
if postgresql.is_leader():
|
|
for member in etcd.members():
|
|
if member['hostname'] != postgresql.name:
|
|
postgresql.query("""SELECT pg_create_physical_replication_slot(%s)
|
|
WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots
|
|
WHERE slot_name = %s)""", member['hostname'], member['hostname'])
|
|
|
|
time.sleep(config["loop_wait"])
|