mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
@@ -67,6 +67,7 @@ For an example file, see `postgres0.yml`. Below is an explanation of settings:
|
|||||||
* *connect_address*: ip address + port through which Postgres is accessible from other nodes and applications.
|
* *connect_address*: ip address + port through which Postgres is accessible from other nodes and applications.
|
||||||
* *data_dir*: file path to initialize and store Postgres data files
|
* *data_dir*: file path to initialize and store Postgres data files
|
||||||
* *maximum_lag_on_failover*: the maximum bytes a follower may lag before it is not eligible become leader
|
* *maximum_lag_on_failover*: the maximum bytes a follower may lag before it is not eligible become leader
|
||||||
|
* *use_slots*: whether or not to use replication_slots. Must be False for PostgreSQL 9.3, and you should comment out max_replication_slots.
|
||||||
* *pg_hba*: list of lines which should be added to pg_hba.conf
|
* *pg_hba*: list of lines which should be added to pg_hba.conf
|
||||||
* *- host all all 0.0.0.0/0 md5*
|
* *- host all all 0.0.0.0/0 md5*
|
||||||
* *replication*
|
* *replication*
|
||||||
@@ -84,8 +85,8 @@ For an example file, see `postgres0.yml`. Below is an explanation of settings:
|
|||||||
* *admin*:
|
* *admin*:
|
||||||
* *username*: admin username, user will be created during initialization. It would have CREATEDB and CREATEROLE privileges
|
* *username*: admin username, user will be created during initialization. It would have CREATEDB and CREATEROLE privileges
|
||||||
* *password*: admin password, user will be created during initialization.
|
* *password*: admin password, user will be created during initialization.
|
||||||
* *recovery_conf*: configuration settings written to recovery.conf when configuring follower
|
* *recovery_conf*: additional configuration settings written to recovery.conf when configuring follower
|
||||||
* *parameters*: list of configuration settings for Postgres
|
* *parameters*: list of configuration settings for Postgres. Many of these are required for replication to work.
|
||||||
|
|
||||||
## Replication choices
|
## Replication choices
|
||||||
|
|
||||||
|
|||||||
+24
-21
@@ -50,6 +50,7 @@ class Postgresql:
|
|||||||
self.superuser = config['superuser']
|
self.superuser = config['superuser']
|
||||||
self.admin = config['admin']
|
self.admin = config['admin']
|
||||||
self.callback = config.get('callbacks', {})
|
self.callback = config.get('callbacks', {})
|
||||||
|
self.use_slots = config.get('use_slots',True)
|
||||||
self.recovery_conf = os.path.join(self.data_dir, 'recovery.conf')
|
self.recovery_conf = os.path.join(self.data_dir, 'recovery.conf')
|
||||||
self.configuration_to_save = (os.path.join(self.data_dir, 'pg_hba.conf'),
|
self.configuration_to_save = (os.path.join(self.data_dir, 'pg_hba.conf'),
|
||||||
os.path.join(self.data_dir, 'postgresql.conf'))
|
os.path.join(self.data_dir, 'postgresql.conf'))
|
||||||
@@ -255,9 +256,9 @@ class Postgresql:
|
|||||||
member_conn = psycopg2.connect(**r)
|
member_conn = psycopg2.connect(**r)
|
||||||
member_conn.autocommit = True
|
member_conn.autocommit = True
|
||||||
member_cursor = member_conn.cursor()
|
member_cursor = member_conn.cursor()
|
||||||
member_cursor.execute(
|
member_cursor.execute("""SELECT pg_is_in_recovery(),
|
||||||
"SELECT pg_is_in_recovery(), %s - (pg_last_xlog_replay_location() - '0/0000000'::pg_lsn)",
|
%s - pg_xlog_location_diff(pg_last_xlog_replay_location(),'0/00000')""",
|
||||||
(self.xlog_position(), ))
|
(self.xlog_position(), ))
|
||||||
row = member_cursor.fetchone()
|
row = member_cursor.fetchone()
|
||||||
member_cursor.close()
|
member_cursor.close()
|
||||||
member_conn.close()
|
member_conn.close()
|
||||||
@@ -305,10 +306,9 @@ class Postgresql:
|
|||||||
recovery_target_timeline = 'latest'
|
recovery_target_timeline = 'latest'
|
||||||
""")
|
""")
|
||||||
if leader and leader.conn_url:
|
if leader and leader.conn_url:
|
||||||
f.write("""
|
f.write("""primary_conninfo = '{}'\n""".format(self.primary_conninfo(leader.conn_url)))
|
||||||
primary_slot_name = '{}'
|
if self.use_slots:
|
||||||
primary_conninfo = '{}'
|
f.write("""primary_slot_name = '{}'\n""".format(self.name))
|
||||||
""".format(self.name, self.primary_conninfo(leader.conn_url)))
|
|
||||||
for name, value in self.config.get('recovery_conf', {}).items():
|
for name, value in self.config.get('recovery_conf', {}).items():
|
||||||
f.write("{} = '{}'\n".format(name, value))
|
f.write("{} = '{}'\n".format(name, value))
|
||||||
|
|
||||||
@@ -362,25 +362,28 @@ primary_conninfo = '{}'
|
|||||||
|
|
||||||
def xlog_position(self):
|
def xlog_position(self):
|
||||||
return self.query("""SELECT CASE WHEN pg_is_in_recovery()
|
return self.query("""SELECT CASE WHEN pg_is_in_recovery()
|
||||||
THEN pg_last_xlog_replay_location() - '0/0000000'::pg_lsn
|
THEN pg_xlog_location_diff(pg_last_xlog_replay_location(),'0/0000000')
|
||||||
ELSE pg_current_xlog_location() - '0/00000'::pg_lsn END""").fetchone()[0]
|
ELSE pg_xlog_location_diff(pg_current_xlog_location(),'0/00000') END""").fetchone()[0]
|
||||||
|
|
||||||
def load_replication_slots(self):
|
def load_replication_slots(self):
|
||||||
cursor = self.query("SELECT slot_name FROM pg_replication_slots WHERE slot_type='physical'")
|
if self.use_slots:
|
||||||
self.members = [r[0] for r in cursor]
|
cursor = self.query("SELECT slot_name FROM pg_replication_slots WHERE slot_type='physical'")
|
||||||
|
self.members = [r[0] for r in cursor]
|
||||||
|
|
||||||
def sync_replication_slots(self, members):
|
def sync_replication_slots(self, members):
|
||||||
# drop unused slots
|
if self.use_slots:
|
||||||
for slot in set(self.members) - set(members):
|
# drop unused slots
|
||||||
self.query("""SELECT pg_drop_replication_slot(%s)
|
for slot in set(self.members) - set(members):
|
||||||
WHERE EXISTS(SELECT 1 FROM pg_replication_slots
|
self.query("""SELECT pg_drop_replication_slot(%s)
|
||||||
WHERE slot_name = %s)""", slot, slot)
|
WHERE EXISTS(SELECT 1 FROM pg_replication_slots
|
||||||
|
WHERE slot_name = %s)""", slot, slot)
|
||||||
|
|
||||||
|
# create new slots
|
||||||
|
for slot in set(members) - set(self.members):
|
||||||
|
self.query("""SELECT pg_create_physical_replication_slot(%s)
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots
|
||||||
|
WHERE slot_name = %s)""", slot, slot)
|
||||||
|
|
||||||
# create new slots
|
|
||||||
for slot in set(members) - set(self.members):
|
|
||||||
self.query("""SELECT pg_create_physical_replication_slot(%s)
|
|
||||||
WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots
|
|
||||||
WHERE slot_name = %s)""", slot, slot)
|
|
||||||
self.members = members
|
self.members = members
|
||||||
|
|
||||||
def create_replication_slots(self, cluster):
|
def create_replication_slots(self, cluster):
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ postgresql:
|
|||||||
connect_address: 127.0.0.1:5432
|
connect_address: 127.0.0.1:5432
|
||||||
data_dir: data/postgresql0
|
data_dir: data/postgresql0
|
||||||
maximum_lag_on_failover: 1048576 # 1 megabyte in bytes
|
maximum_lag_on_failover: 1048576 # 1 megabyte in bytes
|
||||||
|
use_slots: True
|
||||||
pg_hba:
|
pg_hba:
|
||||||
- host all all 0.0.0.0/0 md5
|
- host all all 0.0.0.0/0 md5
|
||||||
- hostssl all all 0.0.0.0/0 md5
|
- hostssl all all 0.0.0.0/0 md5
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ postgresql:
|
|||||||
connect_address: 127.0.0.1:5433
|
connect_address: 127.0.0.1:5433
|
||||||
data_dir: data/postgresql1
|
data_dir: data/postgresql1
|
||||||
maximum_lag_on_failover: 1048576 # 1 megabyte in bytes
|
maximum_lag_on_failover: 1048576 # 1 megabyte in bytes
|
||||||
|
use_slots: True
|
||||||
pg_hba:
|
pg_hba:
|
||||||
- host all all 0.0.0.0/0 md5
|
- host all all 0.0.0.0/0 md5
|
||||||
- hostssl all all 0.0.0.0/0 md5
|
- hostssl all all 0.0.0.0/0 md5
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ class TestPostgresql(unittest.TestCase):
|
|||||||
'pg_hba': ['hostssl all all 0.0.0.0/0 md5', 'host all all 0.0.0.0/0 md5'],
|
'pg_hba': ['hostssl all all 0.0.0.0/0 md5', 'host all all 0.0.0.0/0 md5'],
|
||||||
'superuser': {'password': ''},
|
'superuser': {'password': ''},
|
||||||
'admin': {'username': 'admin', 'password': 'admin'},
|
'admin': {'username': 'admin', 'password': 'admin'},
|
||||||
|
'use_slots' : True,
|
||||||
'replication': {'username': 'replicator',
|
'replication': {'username': 'replicator',
|
||||||
'password': 'rep-pass',
|
'password': 'rep-pass',
|
||||||
'network': '127.0.0.1/32'},
|
'network': '127.0.0.1/32'},
|
||||||
|
|||||||
Reference in New Issue
Block a user