mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
First of all, this patch changes the behavior of `on_start`/`on_restart` callbacks, they will be called only when postgres is started or restarted without role changes. In case if the member is promoted or demoted only the `on_role_change` callback will be executed. `on_role_change` was never called for standby leader, only `on_start`/`on_restart` and with a wrong role argument. Before that `on_role_change` was never called for standby leader, only `on_start`/`on_restart` and with a wrong role argument. In addition to that, the REST API will return standby_leader role for the leader of the standby cluster. Closes https://github.com/zalando/patroni/issues/988
79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
import os
|
|
import time
|
|
|
|
from behave import step
|
|
|
|
|
|
select_replication_query = """
|
|
SELECT * FROM pg_catalog.pg_stat_replication
|
|
WHERE application_name = '{0}'
|
|
"""
|
|
|
|
callback = "bash -c 'echo \"${*: -3:1} ${*: -2:1} ${*: -1:1}\" >> data/$1/$1_cb.log' -- "
|
|
|
|
|
|
@step('I start {name:w} with callback configured')
|
|
def start_patroni_with_callbacks(context, name):
|
|
return context.pctl.start(name, custom_config={
|
|
"postgresql": {
|
|
"callbacks": {
|
|
"on_role_change": "features/callback.sh"
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
@step('I start {name:w} in a cluster {cluster_name:w}')
|
|
def start_patroni(context, name, cluster_name):
|
|
return context.pctl.start(name, custom_config={
|
|
"scope": cluster_name,
|
|
"postgresql": {
|
|
"callbacks": {c: callback + name for c in ('on_start', 'on_stop', 'on_restart', 'on_role_change')}
|
|
}
|
|
})
|
|
|
|
|
|
@step('I start {name:w} in a standby cluster {cluster_name:w} as a clone of {name2:w}')
|
|
def start_patroni_standby_cluster(context, name, cluster_name, name2):
|
|
# we need to remove patroni.dynamic.json in order to "bootstrap" standby cluster with existing PGDATA
|
|
os.unlink(os.path.join(context.pctl._processes[name]._data_dir, 'patroni.dynamic.json'))
|
|
port = context.pctl._processes[name2]._connkwargs.get('port')
|
|
context.pctl._processes[name].update_config({
|
|
"scope": cluster_name,
|
|
"bootstrap": {
|
|
"dcs": {
|
|
"ttl": 20,
|
|
"loop_wait": 2,
|
|
"retry_timeout": 5,
|
|
"standby_cluster": {
|
|
"host": "localhost",
|
|
"port": port,
|
|
"primary_slot_name": "pm_1",
|
|
}
|
|
}
|
|
},
|
|
"postgresql": {
|
|
"callbacks": {c: callback + name for c in ('on_start', 'on_stop', 'on_restart', 'on_role_change')}
|
|
}
|
|
})
|
|
return context.pctl.start(name)
|
|
|
|
|
|
@step('{pg_name1:w} is replicating from {pg_name2:w} after {timeout:d} seconds')
|
|
def check_replication_status(context, pg_name1, pg_name2, timeout):
|
|
bound_time = time.time() + timeout
|
|
|
|
while time.time() < bound_time:
|
|
cur = context.pctl.query(
|
|
pg_name2,
|
|
select_replication_query.format(pg_name1),
|
|
fail_ok=True
|
|
)
|
|
|
|
if cur and len(cur.fetchall()) != 0:
|
|
break
|
|
|
|
time.sleep(1)
|
|
else:
|
|
assert False, "{0} is not replicating from {1} after {2} seconds".format(pg_name1, pg_name2, timeout)
|