patroni.dcs package

Submodules

Module contents

Abstract classes for Distributed Configuration Store.

class _patroni.dcs.AbstractDCS(_config: Dict[ str, Any]) View on GitHub

Bases: ABC + Abstract representation of DCS modules. + Implementations of a concrete DCS class, using appropriate backend client interfaces, must include the following methods and properties. + Functional methods that are critical in their timing, required to complete within retry_timeout period in order to prevent the DCS considered inaccessible, each perform construction of complex data objects: + __\\__ __\\__ + Functional methods that are critical in their timing and must be written with ACID transaction properties in mind: + __\\__ __\\__ + Functional method that relies on Compare-And-Create to ensure only one member creates the relevant key: + __\\__ __\\__ + DCS backend getter and setter methods and properties: + __\\__ __\\__ + DCS setter methods using Compare-And-Set which although important are less critical if they fail, attempts can be retried or may result in warning log messages: + __\\__ __\\__ + DCS data and key removal methods: + __\\__ __\\__ + If either of the sync_state set or delete methods fail, although not critical, this may result in Synchronous+ ``+replication+ +key+ +updated+ +by+ +someone+ +`else` messages being logged. + Care should be taken to consult each abstract method for any additional information and requirements such as expected exceptions that should be raised in certain conditions and the object types for arguments and return from methods and properties. +

CONFIG = 'config'_

+

FAILOVER = 'failover'_

+

FAILSAFE = 'failsafe'_

+

HISTORY = 'history'_

+

INITIALIZE = 'initialize'_

+

LEADER = 'leader'_

+

LEADER_OPTIME = 'optime/leader'_

+

MEMBERS = 'members/'_

+

OPTIME = 'optime'_

+

STATUS = 'status'_

+

SYNC = 'sync'_

+

__get_patroni_cluster(_path: str | None = None_) → Cluster

Low level method to load a Cluster object from DCS. +

Parameters

path – optional client path in DCS backend to load from.

Returns

a loaded Cluster instance. +

__init\\__(config: Dict[ str, Any]) → None View on GitHub

Prepare DCS paths, Citus group ID, initial values for state information and processing dependencies. +

Variables

configdict, reference to config section of selected DCS. i.e.: zookeeper for zookeeper, etcd for etcd, etc… +

abc_impl = <_abc._abc_data object>_

+

abstract \__citus_cluster_loader(_path: Any) → Cluster | Dict[ int, Cluster] View on GitHub

Load and build all Patroni clusters from a single Citus cluster. +

Parameters

path – the path in DCS where to load Cluster(s) from.

Returns

all Citus groups as dict, with group IDs as keys and Cluster objects as values or a Cluster object representing the coordinator with filled Cluster.workers attribute. +

abstract \__cluster_loader(_path: Any) → Cluster View on GitHub

Load and build the Cluster object from DCS, which represents a single Patroni or Citus cluster. +

Parameters

path – the path in DCS where to load Cluster(s) from.

Returns

Cluster instance. +

abstract \__delete_leader(_leader: Leader) → bool View on GitHub

Remove leader key from DCS. + This method should remove leader key if current instance is the leader. +

Parameters

leaderLeader object with information about the leader.

Returns

True if successfully committed to DCS. +

get_citus_cluster() → Cluster https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1629-L1640[View on GitHub]

Load Citus cluster from DCS. +

Returns

A Citus Cluster instance for the coordinator with workers clusters in the Cluster.workers dict. +

abstract \__load_cluster(_path: str, loader: Callable[[ Any], Cluster | Dict[ int, Cluster]]) → Cluster | Dict[ int, Cluster] View on GitHub

Main abstract method that implements the loading of Cluster instance. + Note

  Internally this method should call the _loader_ method that will build link:#patroni.dcs.Cluster[`+Cluster+`] object which represents current state and topology of the cluster in DCS. This method supposed to be called only by the link:#patroni.dcs.AbstractDCS.get_cluster[`+get_cluster()+`] method.
  +
  Parameters:::
  Raise:::
    `+DCSError+` in case of communication problems with DCS. If the current node was running as a primary and exception raised, instance would be demoted.
+
set_loop_wait(_loop_wait: int) → None View on GitHub

Set new loop_wait value. +

Parameters

loop_wait – value to set. +

abstract \__update_leader(_leader: Leader) → bool View on GitHub

Update leader key (or session) ttl. + Note

You have to use CAS (Compare And Swap) operation in order to update leader key, for example for etcd `+prevValue+` parameter must be used.
  If update fails due to DCS not being accessible or because it is not able to process requests (hopefully temporary), the `+DCSError+` exception should be raised.
  +
  Parameters:::
    *leader* – a reference to a current `+leader+` object.
  Returns:::
    `+True+` if `+leader+` key (or session) has been updated successfully.
+
abstract \__write_failsafe(_value: str) → bool View on GitHub

Write current cluster topology to DCS that will be used by failsafe mechanism (if enabled). +

Parameters

value – failsafe topology serialized in JSON format.

Returns

True if successfully committed to DCS. +

abstract \__write_leader_optime(_last_lsn: str) → bool View on GitHub

Write current WAL LSN into /optime/leader key in DCS. +

Parameters

last_lsn – absolute WAL LSN in bytes.

Returns

True if successfully committed to DCS. +

abstract \__write_status(_value: str) → bool View on GitHub

Write current WAL LSN and confirmed_flush_lsn of permanent slots into the /status key in DCS. +

Parameters

value – status serialized in JSON format.

Returns

True if successfully committed to DCS. +

abstract _attempt_to_acquire_leader() → bool https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1796-L1810[View on GitHub]

Attempt to acquire leader lock. + Note

This method should create `+/leader+` key with the value `+_name+`.
The key must be created atomically. In case the key already exists it should not be overwritten and `+False+` must be returned.
  If key creation fails due to DCS not being accessible or because it is not able to process requests (hopefully temporary), the `+DCSError+` exception should be raised.
  +
  Returns:::
    `+True+` if key has been created successfully.
+
abstract _cancel_initialization() → bool https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1919-L1924[View on GitHub]

Removes the initialize key for a cluster. +

Returns

True if successfully committed to DCS. +

client_path(path: str) → str View on GitHub

Construct the absolute key name from appropriate parts for the DCS type. +

Parameters

path – The key name within the current Patroni cluster.

Returns

absolute key name for the current Patroni cluster. +

property _cluster: Cluster | None_

Cached DCS cluster information that has not yet expired. +

property _config_path: str_

Get the client path for config. +

abstract _delete_cluster() → bool https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1926-L1931[View on GitHub]

Delete cluster from DCS. +

Returns

True if successfully committed to DCS. +

delete_leader(leader: Leader | None, last_lsn: int | None = None) → bool View on GitHub

Update optime/leader and voluntarily remove leader key from DCS. + This method should remove leader key if current instance is the leader. +

Parameters
Returns

boolean result of called abstract _delete_leader(). +

abstract _delete_sync_state(_version: Any | None = None) → bool View on GitHub

Delete the synchronous state from DCS. +

Parameters

version – for conditional deletion of the key/object.

Returns

True if delete successful. +

property _failover_path: str_

Get the client path for failover. +

property _failsafe: Dict[ str, str] | None_

Stored value of _last_failsafe. +

property _failsafe_path: str_

Get the client path for failsafe. +

get_citus_coordinator() → Cluster | None View on GitHub

Load the Patroni cluster for the Citus Coordinator. + __\\__ Note

  This method is only executed on the worker nodes (`+group!=0+`) to find the coordinator.
  \\__\\__
  +
  Returns:::
    Select link:#patroni.dcs.Cluster[`+Cluster+`] instance associated with the Citus Coordinator group ID.
+
get_cluster() → Cluster View on GitHub

Retrieve a fresh view of DCS. + Note

Stores copy of time, status and failsafe values for comparison in DCS update decisions. Caching is required to avoid overhead placed upon the REST API.
  Returns either a Citus or Patroni implementation of link:#patroni.dcs.Cluster[`+Cluster+`] depending on availability.
  +
  Returns:::
+
property _history_path: str_

Get the client path for history. +

abstract _initialize(_create_new: bool = True, sysid: str = '') → bool View on GitHub

Race for cluster initialization. + This method should atomically create initialize key and return True, otherwise it should return False. +

Parameters
Returns

True if key has been created successfully. +

property _initialize_path: str_

Get the client path for initialize. +

is_citus_coordinator() → bool View on GitHub

Cluster instance has a Citus Coordinator group ID. +

Returns

True if the given node is running as Citus Coordinator (group=0). +

property _last_seen: int_

The time recorded when the DCS was last reachable. +

property _leader_optime_path: str_

Get the client path for optime/leader (legacy key, superseded by status). +

property _leader_path: str_

Get the client path for leader. +

property _loop_wait: int_

The recorded value for cluster HA loop wait time in seconds. +

manual_failover(leader: str | None, candidate: str | None, scheduled_at: datetime | None = None, version: Any | None = None) → bool View on GitHub

Prepare dictionary with given values and set /failover key in DCS. +

Parameters
Returns

True if successfully committed to DCS. +

property _member_path: str_

Get the client path for member representing this node. +

property _members_path: str_

Get the client path for members. +

reload_config(config: Config | Dict[ str, Any]) → None View on GitHub

Load and set relevant values from configuration. + Sets loop_wait, ttl and retry_timeout properties. +

Parameters

config – Loaded configuration information object or dictionary of key value pairs. +

reset_cluster() → None View on GitHub

Clear cached state of DCS. +

abstract _set_config_value(_value: str, version: Any | None = None) → bool View on GitHub

Create or update /config key in DCS. +

Parameters
Returns

True if successfully committed to DCS. +

abstract _set_failover_value(_value: str, version: Any | None = None) → bool View on GitHub

Create or update /failover key. +

Parameters
Returns

True if successfully committed to DCS. +

abstract _set_history_value(_value: str) → bool View on GitHub

Set value for history in DCS. +

Parameters

value – new value of history key/object.

Returns

True if successfully committed to DCS. +

abstract _set_retry_timeout(_retry_timeout: int) → None View on GitHub

Set the new value for retry_timeout. +

abstract _set_sync_state_value(_value: str, version: Any | None = None) → Any | bool View on GitHub

Set synchronous state in DCS. +

Parameters
Returns

version of the new object or False in case of error. +

abstract _set_ttl(_ttl: int) → bool | None View on GitHub

Set the new ttl value for DCS keys. +

property _status_path: str_

Get the client path for status. +

property _sync_path: str_

Get the client path for sync. +

static _sync_state(_leader: str | None, sync_standby: Collection[ str] | None) → Dict[ str, Any] View on GitHub

Build sync_state dictionary. +

Parameters
Returns

dictionary that later could be serialized to JSON or saved directly to DCS. +

abstract _take_leader() → bool https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1867-L1879[View on GitHub]

Establish a new leader in DCS. + Note

This method should create leader key with value of `+_name+` and `+ttl+` of link:#patroni.dcs.AbstractDCS.ttl[`+ttl+`].
  Since it could be called only on initial cluster bootstrap it could create this key regardless, overwriting the key if necessary.
  +
  Returns:::
    `+True+` if successfully committed to DCS.
+
abstract _touch_member(_data: Dict[ str, Any]) → bool View on GitHub

Update member key in DCS. + Note

  This method should create or update key with the name with `+/members/+` + `+_name+` and the value of _data_ in a given DCS.
  +
  Parameters:::
    *data* – information about an instance (including connection strings).
  Returns:::
    `+True+` if successfully committed to DCS.
+
abstract property _ttl: int_

Get current ttl value. +

update_leader(leader: Leader, last_lsn: int | None, slots: Dict[ str, int] | None = None, failsafe: Dict[ str, str] | None = None) → bool View on GitHub

Update leader key (or session) ttl and optime/leader. +

Parameters
Returns

True if leader key (or session) has been updated successfully. +

watch(leader_version: Any | None, timeout: float) → bool View on GitHub

Sleep if the current node is a leader, otherwise, watch for changes of leader key with a given timeout. +

Parameters
Returns

if True this will reschedule the next run of the HA cycle. +

write_failsafe(value: Dict[ str, str]) → None View on GitHub

Write the /failsafe key in DCS. +

Parameters

value – dictionary value to set, consisting of the name and api_url of members. +

write_leader_optime(last_lsn: int) → None View on GitHub

Write value for WAL LSN to optime/leader key in DCS. + Note

  This method abstracts away the required data structure of `+write_status()+`, so it is not needed in the caller. However, the `+optime/leader+` is only written in `+write_status()+` when the cluster has members with a Patroni version that is old enough to require it (i.e. the old Patroni version doesn’t understand the new format).
  +
  Parameters:::
    *last_lsn* – absolute WAL LSN in bytes.
+
write_status(value: Dict[ str, Any]) → None View on GitHub

Write cluster status to DCS if changed. + Note

  The DCS key `+/status+` was introduced in Patroni version 2.1.0. Previous to this the position of last known leader LSN was stored in `+optime/leader+`. This method has detection for backwards compatibility of members with a version older than this.
  +
  Parameters:::
    *value* – JSON serializable dictionary with current WAL LSN and `+confirmed_flush_lsn+` of permanent slots.
+
write_sync_state(leader: str | None, sync_standby: Collection[ str] | None, version: Any | None = None) → SyncState | None View on GitHub

Write the new synchronous state to DCS. + Calls sync_state() to build a dictionary and then calls DCS specific set_sync_state_value(). +

Parameters
Returns

the new SyncState object or None.

class _patroni.dcs.Cluster(*args: Any, _**kwargs: Any) View on GitHub

Bases: Cluster + Immutable object (namedtuple) which represents PostgreSQL or Citus cluster. + Note

We are using an old-style attribute declaration here because otherwise it is not possible to override \\__new\\__ method. Without it the _workers_ by default gets always the same  https://docs.python.org/3/library/stdtypes.html#dict[`+dict+`] object that could be mutated.
+
Consists of the following fields:
+
Variables:;;
+
_property \\___permanent_logical_slots_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_link:#patroni.dcs.Cluster.\\__permanent_logical_slots[];;
  Dictionary of permanent `+logical+` replication slots.
+
_property \\___permanent_physical_slots_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_link:#patroni.dcs.Cluster.\\__permanent_physical_slots[];;
  Dictionary of permanent `+physical+` replication slots.
+
_property \\___permanent_slots_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]] |  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_link:#patroni.dcs.Cluster.\\__permanent_slots[];;
  Dictionary of permanent replication slots with their known LSN.
+
_get_members_slots(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _role:  https://docs.python.org/3/library/stdtypes.html#str[str]_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/stdtypes.html#str[str]]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1144-L1185[View on GitHub]link:#patroni.dcs.Cluster._get_members_slots[];;
  Get physical replication slots configuration for members that sourcing from this node.
  +
  If the `+replicatefrom+` tag is set on the member - we should not create the replication slot for it on the current primary, because that member would replicate from elsewhere. We still create the slot if the `+replicatefrom+` destination member is currently not a member of the cluster (fallback to the primary), or if `+replicatefrom+` destination member happens to be the current primary.
  +
  Will log an error if:
  +
  \\__\\__
  \\__\\__
  +
  Parameters:::
  Returns:::
    dictionary of physical replication slots that should exist on a given node.
+
_get_permanent_slots(_*_, _is_standby_cluster:  https://docs.python.org/3/library/functions.html#bool[bool]_, _role:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _nofailover:  https://docs.python.org/3/library/functions.html#bool[bool]_, _major_version:  https://docs.python.org/3/library/functions.html#int[int]_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1113-L1142[View on GitHub]link:#patroni.dcs.Cluster._get_permanent_slots[];;
  Get configured permanent replication slots.
  +
  Note
Permanent replication slots are only considered if `+use_slots+` configuration is enabled. A node that is not supposed to become a leader (_nofailover_) will not have permanent replication slots.
In a standby cluster we only support physical replication slots.
  The returned dictionary for a non-standby cluster always contains permanent logical replication slots in order to show a warning if they are not supported by PostgreSQL before v11.
  +
  Parameters:::
  Returns:::
    dictionary of permanent slot names mapped to attributes.
+
_has_permanent_logical_slots(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _nofailover:  https://docs.python.org/3/library/functions.html#bool[bool]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1232-L1241[View on GitHub]link:#patroni.dcs.Cluster._has_permanent_logical_slots[];;
  Check if the given member node has permanent `+logical+` replication slots configured.
  +
  Parameters:::
  Returns:::
    `+True+` if any detected replications slots are `+logical+`, otherwise `+False+`.
+
_merge_permanent_slots(_slots:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/stdtypes.html#str[str]]]_, _permanent_slots:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_, _my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _major_version:  https://docs.python.org/3/library/functions.html#int[int]_) →  https://docs.python.org/3/library/typing.html#typing.List[List][ https://docs.python.org/3/library/stdtypes.html#str[str]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1065-L1111[View on GitHub]link:#patroni.dcs.Cluster._merge_permanent_slots[];;
  Merge replication _slots_ for members with _permanent_slots_.
  +
  Perform validation of configured permanent slot name, skipping invalid names.
  +
  Will update _slots_ in-line based on `+type+` of slot, `+physical+` or `+logical+`, and name of node. Type is assumed to be `+physical+` if there are no attributes stored as the slot value.
  +
  Parameters:::
  Returns:::
    List of disabled permanent, logical slot names, if postgresql version < 11.
+
_static _empty() → link:#patroni.dcs.Cluster[Cluster] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L892-L895[View on GitHub]link:#patroni.dcs.Cluster.empty[];;
  Produce an empty link:#patroni.dcs.Cluster[`+Cluster+`] instance.
+
filter_permanent_slots(_slots:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/functions.html#int[int]]_, _is_standby_cluster:  https://docs.python.org/3/library/functions.html#bool[bool]_, _major_version:  https://docs.python.org/3/library/functions.html#int[int]_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/functions.html#int[int]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1208-L1230[View on GitHub]link:#patroni.dcs.Cluster.filter_permanent_slots[];;
  Filter out all non-permanent slots from provided _slots_ dict.
  +
  Parameters:::
  Returns:::
    a  https://docs.python.org/3/library/stdtypes.html#dict[`+dict+`] object that contains only slots that are known to be permanent.
+
get_clone_member(_exclude_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_) → link:#patroni.dcs.Member[Member] | link:#patroni.dcs.Leader[Leader] |  https://docs.python.org/3/library/constants.html#None[None] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L961-L972[View on GitHub]link:#patroni.dcs.Cluster.get_clone_member[];;
  Get member or leader object to use as clone source.
  +
  Parameters:::
    *exclude_name* – name of a member name to exclude.
  Returns:::
    a randomly selected candidate member from available running members that are configured to as viable sources for cloning (has tag `+clonefrom+` in configuration). If no member is appropriate the current leader is used.
+
get_member(_member_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _fallback_to_leader:  https://docs.python.org/3/library/functions.html#bool[bool] = True_) → link:#patroni.dcs.Member[Member] | link:#patroni.dcs.Leader[Leader] |  https://docs.python.org/3/library/constants.html#None[None] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L950-L959[View on GitHub]link:#patroni.dcs.Cluster.get_member[];;
  Get link:#patroni.dcs.Member[`+Member+`] object by name or the link:#patroni.dcs.Leader[`+Leader+`].
  +
  Parameters:::
  Returns:::
    the link:#patroni.dcs.Member[`+Member+`] if found or link:#patroni.dcs.Leader[`+Leader+`] object.
+
get_my_slot_name_on_primary(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _replicatefrom:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_) →  https://docs.python.org/3/library/stdtypes.html#str[str] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1263-L1279[View on GitHub]link:#patroni.dcs.Cluster.get_my_slot_name_on_primary[];;
  Canonical slot name for physical replication.
  +
  Note
P <– I <– L
  In case of cascading replication we have to check not our physical slot, but slot of the replica that connects us to the primary.
  +
  Parameters:::
  Returns:::
    The slot name that is in use for physical replication on this no`de.
+
get_replication_slots(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _role:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _nofailover:  https://docs.python.org/3/library/functions.html#bool[bool]_, _major_version:  https://docs.python.org/3/library/functions.html#int[int]_, _*_, _is_standby_cluster:  https://docs.python.org/3/library/functions.html#bool[bool] = False_, _show_error:  https://docs.python.org/3/library/functions.html#bool[bool] = False_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1033-L1063[View on GitHub]link:#patroni.dcs.Cluster.get_replication_slots[];;
  Lookup configured slot names in the DCS, report issues found and merge with permanent slots.
  +
  Will log an error if:
  +
  \\__\\__
  \\__\\__
  +
  Parameters:::
  Returns:::
    final dictionary of slot names, after merging with permanent slots and performing sanity checks.
+
has_member(_member_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L941-L948[View on GitHub]link:#patroni.dcs.Cluster.has_member[];;
  Check if the given member name is present in the cluster.
  +
  Parameters:::
    *member_name* – name to look up in the `+members+`.
  Returns:::
    `+True+` if the member name is found.
+
has_permanent_slots(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _*_, _is_standby_cluster:  https://docs.python.org/3/library/functions.html#bool[bool] = False_, _nofailover:  https://docs.python.org/3/library/functions.html#bool[bool] = False_, _major_version:  https://docs.python.org/3/library/functions.html#int[int] = 110000_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1187-L1206[View on GitHub]link:#patroni.dcs.Cluster.has_permanent_slots[];;
  Check if the given member node has permanent replication slots configured.
  +
  Parameters:::
  Returns:::
    `+True+` if there are permanent replication slots configured, otherwise `+False+`.
+
is_empty() https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L897-L904[View on GitHub]link:#patroni.dcs.Cluster.is_empty[];;
  Validate definition of all attributes of this link:#patroni.dcs.Cluster[`+Cluster+`] instance.
  +
  Returns:::
    `+True+` if all attributes of the current link:#patroni.dcs.Cluster[`+Cluster+`] are unpopulated.
+
_static _is_logical_slot(_value:  https://docs.python.org/3/library/typing.html#typing.Any[Any] |  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L984-L994[View on GitHub]link:#patroni.dcs.Cluster.is_logical_slot[];;
  Check whether provided configuration is for permanent logical replication slot.
  +
  Parameters:::
    *value* – configuration of the permanent replication slot.
  Returns:::
    `+True+` if _value_ is a logical replication slot, otherwise `+False+`.
+
_static _is_physical_slot(_value:  https://docs.python.org/3/library/typing.html#typing.Any[Any] |  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L974-L982[View on GitHub]link:#patroni.dcs.Cluster.is_physical_slot[];;
  Check whether provided configuration is for permanent physical replication slot.
  +
  Parameters:::
    *value* – configuration of the permanent replication slot.
  Returns:::
    `+True+` if _value_ is a physical replication slot, otherwise `+False+`.
+
is_unlocked() →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L934-L939[View on GitHub]link:#patroni.dcs.Cluster.is_unlocked[];;
  Check if the cluster does not have the leader.
  +
  Returns:::
    `+True+` if a leader name is not defined.
+
_property _last_lsn_:  https://docs.python.org/3/library/functions.html#int[int]_link:#patroni.dcs.Cluster.last_lsn[];;
  Last known leader LSN.
+
_property _leader_name_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Cluster.leader_name[];;
  The name of the leader if defined otherwise `+None+`.
+
_property _min_version_:  https://docs.python.org/3/library/typing.html#typing.Tuple[Tuple][ https://docs.python.org/3/library/functions.html#int[int], ...] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Cluster.min_version[];;
  Lowest Patroni software version found in known members of the cluster.
+
should_enforce_hot_standby_feedback(_my_name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _nofailover:  https://docs.python.org/3/library/functions.html#bool[bool]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L1243-L1261[View on GitHub]link:#patroni.dcs.Cluster.should_enforce_hot_standby_feedback[];;
  Determine whether `+hot_standby_feedback+` should be enabled for the given member.
  +
  The `+hot_standby_feedback+` must be enabled if the current replica has `+logical+` slots, or it is working as a cascading replica for the other node that has `+logical+` slots.
  +
  Parameters:::
  Returns:::
    `+True+` if this node or any member replicating from this node has permanent logical slots, otherwise `+False+`.
+
_property _slots_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/functions.html#int[int]] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Cluster.slots[];;
  `+{"slot_name":+``+ +``+int}+`.
  +
  Type:::
    State of permanent replication slots on the primary in the format
+
_property _timeline_:  https://docs.python.org/3/library/functions.html#int[int]_link:#patroni.dcs.Cluster.timeline[];;
  Get the cluster history index from the `+history+`.
  +
  Returns:::
    If the recorded history is empty assume timeline is `+1+`, if it is not defined or the stored history is not formatted as expected `+0+` is returned and an error will be logged. Otherwise, the last number stored incremented by 1 is returned.
  Example:::
    No history provided: >>> Cluster(0, 0, 0, Status.empty(), 0, 0, 0, 0, None, \{}).timeline 0
    +
    Empty history assume timeline is `+1+`: >>> Cluster(0, 0, 0, Status.empty(), 0, 0, 0, TimelineHistory.from_node(1, ‘[]’), None, \{}).timeline 1
    +
    Invalid history format, a string of `+a+`, returns `+0+`: >>> Cluster(0, 0, 0, Status.empty(), 0, 0, 0, TimelineHistory.from_node(1, ‘[[“a”]]’), None, \{}).timeline 0
    +
    History as a list of strings: >>> history = TimelineHistory.from_node(1, ‘[[“3”, “2”, “1”]]’) >>> Cluster(0, 0, 0, Status.empty(), 0, 0, 0, history, None, \{}).timeline 4
+
_property _use_slots_:  https://docs.python.org/3/library/functions.html#bool[bool]_link:#patroni.dcs.Cluster.use_slots[];;
  `+True+` if cluster is configured to use replication slots.
class _patroni.dcs.ClusterConfig(_version: int | str, data: Dict[ str, Any], modify_version: int | str) View on GitHub

Bases: NamedTuple + Immutable object (namedtuple) which represents cluster configuration. +

Variables:

+

_asdict() View on GitHub

Return a new dict which maps field names to their values. +

field_defaults = \{}_

+

fields = ('version', 'data', 'modify_version')_

+

classmethod \\__make(_iterable) View on GitHub

Make a new ClusterConfig object from a sequence or iterable +

replace(**kwds_) View on GitHub

Return a new ClusterConfig object replacing specified fields with new values +

data_: Dict[ str, Any]_

Alias for field number 1 +

static _from_node(_version: int | str, value: str, modify_version: int | str | None = None) → ClusterConfig View on GitHub

Factory method to parse value as configuration information. +

Parameters
Returns

constructed ClusterConfig instance.

Example
>>> ClusterConfig.from_node(1, '{') is None
False
+
_property _ignore_slots_matchers_:  https://docs.python.org/3/library/typing.html#typing.List[List][ https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]]_link:#patroni.dcs.ClusterConfig.ignore_slots_matchers[];;
  The value for `+ignore_slots+` from link:#patroni.dcs.ClusterConfig.data[`+data+`] if defined or an empty list.
+
_property _max_timelines_history_:  https://docs.python.org/3/library/functions.html#int[int]_link:#patroni.dcs.ClusterConfig.max_timelines_history[];;
  The value for `+max_timelines_history+` from link:#patroni.dcs.ClusterConfig.data[`+data+`] if defined or `+0+`.
+
modify_version_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_link:#patroni.dcs.ClusterConfig.modify_version[];;
  Alias for field number 2
+
_property _permanent_slots_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_link:#patroni.dcs.ClusterConfig.permanent_slots[];;
  Dictionary of permanent slots information looked up from link:#patroni.dcs.ClusterConfig.data[`+data+`].
+
version_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_link:#patroni.dcs.ClusterConfig.version[];;
  Alias for field number 0
class _patroni.dcs.Failover(_version: int | str, leader: str | None, candidate: str | None, scheduled_at: datetime | None) View on GitHub

Bases: NamedTuple + Immutable object (namedtuple) representing configuration information required for failover/switchover capability. +

Variables:
Example:
>>> 'Failover' in str(Failover.from_node(1, '{"leader": "cluster_leader"}'))
True
+
>>> 'Failover' in str(Failover.from_node(1, {"leader": "cluster_leader"}))
True
+
>>> 'Failover' in str(Failover.from_node(1, '{"leader": "cluster_leader", "member": "cluster_candidate"}'))
True
+
>>> Failover.from_node(1, 'null') is None
False
+
>>> n = '''{"leader": "cluster_leader", "member": "cluster_candidate",
...         "scheduled_at": "2016-01-14T10:09:57.1394Z"}'''
+
>>> 'tzinfo=' in str(Failover.from_node(1, n))
True
+
>>> Failover.from_node(1, None) is None
False
+
>>> Failover.from_node(1, '{}') is None
False
+
>>> 'abc' in Failover.from_node(1, 'abc:def')
True
+
_asdict() https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L465-L467[View on GitHub]link:#patroni.dcs.Failover._asdict[];;
  Return a new dict which maps field names to their values.
+
_field_defaults_ = \{}_link:#patroni.dcs.Failover._field_defaults[];;
+
_fields_ = ('version', 'leader', 'candidate', 'scheduled_at')_link:#patroni.dcs.Failover._fields[];;
+
_classmethod \\__make(_iterable_) https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L442-L447[View on GitHub]link:#patroni.dcs.Failover._make[];;
  Make a new Failover object from a sequence or iterable
+
_replace(_**kwds_) https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L452-L456[View on GitHub]link:#patroni.dcs.Failover._replace[];;
  Return a new Failover object replacing specified fields with new values
+
candidate_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Failover.candidate[];;
  Alias for field number 2
+
_static _from_node(_version:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_, _value:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/stdtypes.html#str[str]]_) → link:#patroni.dcs.Failover[Failover] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L504-L534[View on GitHub]link:#patroni.dcs.Failover.from_node[];;
  Factory method to parse _value_ as failover configuration.
  +
  Parameters:::
  Returns:::
    constructed link:#patroni.dcs.Failover[`+Failover+`] information object
+
leader_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Failover.leader[];;
  Alias for field number 1
+
scheduled_at_:  https://docs.python.org/3/library/datetime.html#datetime.datetime[datetime] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Failover.scheduled_at[];;
  Alias for field number 3
+
version_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_link:#patroni.dcs.Failover.version[];;
  Alias for field number 0
class _patroni.dcs.Leader(_version: int | str, session: int | float | str | None, member: Member) View on GitHub

Bases: NamedTuple + Immutable object (namedtuple) which represents leader key. + Consists of the following fields: +

Variables:

+

_asdict() View on GitHub

Return a new dict which maps field names to their values. +

field_defaults = \{}_

+

fields = ('version', 'session', 'member')_

+

classmethod \\__make(_iterable) View on GitHub

Make a new Leader object from a sequence or iterable +

replace(**kwds_) View on GitHub

Return a new Leader object replacing specified fields with new values +

property _checkpoint_after_promote: bool | None_

Determine whether a checkpoint has occurred for this leader after promotion. +

Returns

True if the role is master or primary and checkpoint_after_promote is not set, False if not a master or primary or if the checkpoint hasn’t occurred. If the version of Patroni is older than 1.5.6, return None.

Example
>>> Leader(1, '', Member.from_node(1, '', '', '{"version":"z"}')).checkpoint_after_promote
+
conn_kwargs(_auth:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/stdtypes.html#str[str]] |  https://docs.python.org/3/library/constants.html#None[None] = None_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/stdtypes.html#str[str]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L417-L424[View on GitHub]link:#patroni.dcs.Leader.conn_kwargs[];;
  Connection keyword arguments.
  +
  Parameters:::
    *auth* – an optional dictionary containing authentication information.
  Returns:::
    the result of the called link:#patroni.dcs.Member.conn_kwargs[`+Member.conn_kwargs()+`] method.
+
_property _conn_url_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Leader.conn_url[];;
  Connection URL value of the link:#patroni.dcs.Member[`+Member+`] instance.
+
_property _data_:  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]]_link:#patroni.dcs.Leader.data[];;
  Data value of the link:#patroni.dcs.Member[`+Member+`] instance.
+
member_: link:#patroni.dcs.Member[Member]_link:#patroni.dcs.Leader.member[];;
  Alias for field number 2
+
_property _name_:  https://docs.python.org/3/library/stdtypes.html#str[str]_link:#patroni.dcs.Leader.name[];;
  The leader “member” name.
+
session_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/functions.html#float[float] |  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Leader.session[];;
  Alias for field number 1
+
_property _timeline_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Leader.timeline[];;
  Timeline value of `+data+`.
+
version_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_link:#patroni.dcs.Leader.version[];;
  Alias for field number 0
class _patroni.dcs.Member(_version: int | str, name: str, session: int | float | str | None, data: Dict[ str, Any]) View on GitHub

Bases: Tags, Member + Immutable object (namedtuple) which represents single member of PostgreSQL cluster. + Note

We are using an old-style attribute declaration here because otherwise it is not possible to override `+\\__new\\__+` method in the link:#patroni.dcs.RemoteMember[`+RemoteMember+`] class.
+
Note
These two keys in data are always written to the DCS, but care is taken to maintain consistency and resilience from data that is read:
`+conn_url+`: connection string containing host, user and password which could be used to access this member. `+api_url+`: REST API url of patroni instance
+
Consists of the following fields:
+
Variables:;;
+
_abc_impl_ = <_abc._abc_data object>_link:#patroni.dcs.Member._abc_impl[];;
+
_property _api_url_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Member.api_url[];;
  The `+api_url+` value from `+data+` if defined.
+
_property _clonefrom_:  https://docs.python.org/3/library/functions.html#bool[bool]_link:#patroni.dcs.Member.clonefrom[];;
  `+True+` if both `+clonefrom+` tag is `+True+` and a connection URL is defined.
+
conn_kwargs(_auth:  https://docs.python.org/3/library/typing.html#typing.Any[Any] |  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]] |  https://docs.python.org/3/library/constants.html#None[None] = None_) →  https://docs.python.org/3/library/typing.html#typing.Dict[Dict][ https://docs.python.org/3/library/stdtypes.html#str[str],  https://docs.python.org/3/library/typing.html#typing.Any[Any]] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L271-L310[View on GitHub]link:#patroni.dcs.Member.conn_kwargs[];;
  Give keyword arguments used for PostgreSQL connection settings.
  +
  Parameters:::
    *auth* – Authentication properties - can be defined as anything supported by the `+psycopg2+` or `+psycopg+` modules. Converts a key of `+username+` to `+user+` if supplied.
  Returns:::
    A dictionary containing a merge of default parameter keys `+host+`, `+port+` and `+dbname+`, with the contents of `+data+` `+conn_kwargs+` key. If those are not defined will parse and reform connection parameters from link:#patroni.dcs.Member.conn_url[`+conn_url+`]. One of these two attributes needs to have data defined to construct the output dictionary. Finally, _auth_ parameters are merged with the dictionary before returned.
+
_property _conn_url_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.Member.conn_url[];;
  The `+conn_url+` value from `+data+` if defined or constructed from `+conn_kwargs+`.
+
_static _from_node(_version:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_, _name:  https://docs.python.org/3/library/stdtypes.html#str[str]_, _session:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/functions.html#float[float] |  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_, _value:  https://docs.python.org/3/library/stdtypes.html#str[str]_) → link:#patroni.dcs.Member[Member] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L224-L254[View on GitHub]link:#patroni.dcs.Member.from_node[];;
  Factory method for instantiating link:#patroni.dcs.Member[`+Member+`] from a JSON serialised string or object.
  +
  Parameters:::
  Returns:::
    an link:#patroni.dcs.Member[`+Member+`] instance built with the given arguments.
  Example:::
>>> Member.from_node(-1, '', '', '{"conn_url": "postgres://foo@bar/postgres"}') is not None
True

+

>>> Member.from_node(-1, '', '', '{')
Member(version=-1, name='', session='', data={})

+

property _is_running: bool_

True if the member state is running. +

property _lsn: int | None_

Current LSN (receive/flush/replay). +

property _patroni_version: Tuple[ int, …​] | None_

The version string value from data converted to tuple. +

Example
>>> Member.from_node(1, '', '', '{"version":"1.2.3"}').patroni_version
(1, 2, 3)

+

property _state: str_

The state value of data. +

property _tags: Dict[ str, Any]_

The tags value from data if defined, otherwise an empty dictionary.

class _patroni.dcs.RemoteMember(_name: str, data: Dict[ str, Any]) View on GitHub

Bases: Member + Represents a remote member (typically a primary) for a standby cluster. +

Variables:

ALLOWED_KEYS – Controls access to relevant key names that could be in stored data. +

ALLOWED_KEYS_: Tuple[ str, …​] = ('primary_slot_name', 'create_replica_methods', 'restore_command', 'archive_cleanup_command', 'recovery_min_apply_delay', 'no_replication_slot')_

+

abc_impl = <_abc._abc_data object>_
exception _patroni.dcs.ReturnFalseException https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L1324-L1325[View on GitHub]

Bases: Exception + Exception to be caught by the catch_return_false_exception() decorator.

class _patroni.dcs.Status(_last_lsn: int, slots: Dict[ str, int] | None) View on GitHub

Bases: NamedTuple + Immutable object (namedtuple) which represents /status key. + Consists of the following fields: +

Variables:

+

_asdict() View on GitHub

Return a new dict which maps field names to their values. +

field_defaults = \{}_

+

fields = ('last_lsn', 'slots')_

+

classmethod \\__make(_iterable) View on GitHub

Make a new Status object from a sequence or iterable +

replace(**kwds_) View on GitHub

Return a new Status object replacing specified fields with new values +

static _empty() → Status https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\__init\\_.py#L799-L805[View on GitHub]

Construct an empty Status instance. +

Returns

empty Status object. +

static _from_node(_value: str | Dict[ str, Any] | None) → Status View on GitHub

Factory method to parse value as Status object. +

Parameters

value – JSON serialized string

Returns

constructed Status object. +

last_lsn_: int_

Alias for field number 0 +

slots_: Dict[ str, int] | None_

Alias for field number 1

class _patroni.dcs.SyncState(_version: int | str | None, leader: str | None, sync_standby: str | None) View on GitHub

Bases: NamedTuple + Immutable object (namedtuple) which represents last observed synchronous replication state. +

Variables:

+

_asdict() View on GitHub

Return a new dict which maps field names to their values. +

field_defaults = \{}_

+

fields = ('version', 'leader', 'sync_standby')_

+

classmethod \\__make(_iterable) View on GitHub

Make a new SyncState object from a sequence or iterable +

replace(**kwds_) View on GitHub

Return a new SyncState object replacing specified fields with new values +

static \__str_to_list(_value: str) → List[ str] View on GitHub

Splits a string by comma and returns list of strings. +

Parameters

value – a comma separated string.

Returns

list of non-empty strings after splitting an input value by comma. +

static _empty(_version: int | str | None = None) → SyncState View on GitHub

Construct an empty SyncState instance. +

Parameters

version – optional version number.

Returns

empty synchronisation state object. +

static _from_node(_version: int | str | None, value: str | Dict[ str, Any] | None) → SyncState View on GitHub

Factory method to parse value as synchronisation state information. +

Parameters
Returns

constructed SyncState object.

Example
>>> SyncState.from_node(1, None).leader is None
True
+
>>> SyncState.from_node(1, '{}').leader is None
True
+
>>> SyncState.from_node(1, '{').leader is None
True
+
>>> SyncState.from_node(1, '[]').leader is None
True
+
>>> SyncState.from_node(1, '{"leader": "leader"}').leader == "leader"
True
+
>>> SyncState.from_node(1, {"leader": "leader"}).leader == "leader"
True
+
_property _is_empty_:  https://docs.python.org/3/library/functions.html#bool[bool]_link:#patroni.dcs.SyncState.is_empty[];;
  `+True+` if `+/sync+` key is not valid (doesn’t have a leader).
+
leader_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.SyncState.leader[];;
  Alias for field number 1
+
leader_matches(_name:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L733-L738[View on GitHub]link:#patroni.dcs.SyncState.leader_matches[];;
  Compare the given _name_ to stored leader value.
  +
  Returns:::
    `+True+` if _name_ is matching the link:#patroni.dcs.SyncState.leader[`+leader+`] value.
+
matches(_name:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_, _check_leader:  https://docs.python.org/3/library/functions.html#bool[bool] = False_) →  https://docs.python.org/3/library/functions.html#bool[bool] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L691-L731[View on GitHub]link:#patroni.dcs.SyncState.matches[];;
  Checks if node is presented in the /sync state.
  +
  Since PostgreSQL does case-insensitive checks for synchronous_standby_name we do it also.
  +
  Parameters:::
  Returns:::
    `+True+` if the `+/sync+` key not link:#patroni.dcs.SyncState.is_empty[`+is_empty()+`] and the given _name_ is among those presented in the sync state.
  Example:::
>>> s = SyncState(1, 'foo', 'bar,zoo')
+
>>> s.matches('foo')
False
+
>>> s.matches('fOo', True)
True
+
>>> s.matches('Bar')
True
+
>>> s.matches('zoO')
True
+
>>> s.matches('baz')
False
+
>>> s.matches(None)
False
+
>>> SyncState.empty(1).matches('foo')
False
+
_property _members_:  https://docs.python.org/3/library/typing.html#typing.List[List][ https://docs.python.org/3/library/stdtypes.html#str[str]]_link:#patroni.dcs.SyncState.members[];;
  link:#patroni.dcs.SyncState.sync_standby[`+sync_standby+`] as list or an empty list if undefined or object considered `+empty+`.
+
sync_standby_:  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.SyncState.sync_standby[];;
  Alias for field number 2
+
version_:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str] |  https://docs.python.org/3/library/constants.html#None[None]_link:#patroni.dcs.SyncState.version[];;
  Alias for field number 0
class _patroni.dcs.TimelineHistory(_version: int | str, value: Any, lines: List[ Tuple[ int, int, str] | Tuple[ int, int, str, str] | Tuple[ int, int, str, str, str]]) View on GitHub

Bases: NamedTuple + Object representing timeline history file. + Note

The content held in _lines_ deserialized from _value_ are lines parsed from PostgreSQL timeline history files, consisting of the timeline number, the LSN where the timeline split and any other string held in the file. The files are parsed by `+parse_history()+`.
+
Variables:;;
+
_asdict() https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L465-L467[View on GitHub]link:#patroni.dcs.TimelineHistory._asdict[];;
  Return a new dict which maps field names to their values.
+
_field_defaults_ = \{}_link:#patroni.dcs.TimelineHistory._field_defaults[];;
+
_fields_ = ('version', 'value', 'lines')_link:#patroni.dcs.TimelineHistory._fields[];;
+
_classmethod \\__make(_iterable_) https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L442-L447[View on GitHub]link:#patroni.dcs.TimelineHistory._make[];;
  Make a new TimelineHistory object from a sequence or iterable
+
_replace(_**kwds_) https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/y#L452-L456[View on GitHub]link:#patroni.dcs.TimelineHistory._replace[];;
  Return a new TimelineHistory object replacing specified fields with new values
+
_static _from_node(_version:  https://docs.python.org/3/library/functions.html#int[int] |  https://docs.python.org/3/library/stdtypes.html#str[str]_, _value:  https://docs.python.org/3/library/stdtypes.html#str[str]_) → link:#patroni.dcs.TimelineHistory[TimelineHistory] https://github.com/zalando/patroni/blob/3d527f5728fa8c6fadc55284cf854eead6a30a9b/patroni/dcs/\\__init\\__.py#L761-L785[View on GitHub]link:#patroni.dcs.TimelineHistory.from_node[];;
  Parse the given JSON serialized string as a list of timeline history lines.
  +
  Parameters:::
  Returns:::
    composed timeline history object using parsed lines.
  Example:::
    If the passed _value_ argument is not parsed an empty list of lines is returned:
    +
>>> h = TimelineHistory.from_node(1, 2)

+

>>> h.lines
[]

+

lines_: List[ Tuple[ int, int, str] | Tuple[ int, int, str, str] | Tuple[ int, int, str, str, str]]_

Alias for field number 2 +

value_: Any_

Alias for field number 1 +

version_: int | str_

Alias for field number 0

patroni.dcs.catch_return_false_exception(func: Callable[[…​], Any]) → Any View on GitHub

Decorator function for catching functions raising ReturnFalseException. +

Parameters:

func – function to be wrapped.

Returns:

wrapped function.

patroni.dcs.dcs_modules() → List[ str] View on GitHub

Get names of DCS modules, depending on execution environment. + Note

If being packaged with PyInstaller, modules aren’t discoverable dynamically by scanning source directory because  https://docs.python.org/3/library/importlib.html#importlib.machinery.FrozenImporter[`+importlib.machinery.FrozenImporter+`] doesn’t implement `+iter_modules()+`. But it is still possible to find all potential DCS modules by iterating through `+toc+`, which contains list of all “frozen” resources.
+
Returns:;;
  list of known module names with absolute python module path namespace, e.g. `+patroni.dcs.etcd+`.
patroni.dcs.find_dcs_class_in_module(module: module) → Type[AbstractDCS] | None View on GitHub

Try to find the implementation of AbstractDCS interface in module matching the module name. +

Parameters:

module – Imported DCS module.

Returns:

class with a name matching the name of module that implements AbstractDCS or None if not found.

patroni.dcs.get_dcs(config: Config | Dict[ str, Any]) → AbstractDCS View on GitHub

Attempt to load a Distributed Configuration Store from known available implementations. + Note

Using the list of available DCS classes returned by link:#patroni.dcs.iter_dcs_classes[`+iter_dcs_classes()+`] attempt to dynamically instantiate the class that implements a DCS using the abstract class link:#patroni.dcs.AbstractDCS[`+AbstractDCS+`].
Basic top-level configuration parameters retrieved from _config_ are propagated to the DCS specific config before being passed to the module DCS class.
If no module is found to satisfy configuration then report and log an error. This will cause Patroni to exit.
+
:raises `+PatroniFatalException+`: if a load of all available DCS modules have been tried and none succeeded.
+
Parameters:;;
  *config* – object or dictionary with Patroni configuration. This is normally a representation of the main Patroni
Returns:;;
  The first successfully loaded DCS module which is an implementation of link:#patroni.dcs.AbstractDCS[`+AbstractDCS+`].
patroni.dcs.iter_dcs_classes(config: Config | Dict[ str, Any] | None = None) → Iterator[ Tuple[ str, Type[AbstractDCS]]] View on GitHub

Attempt to import DCS modules that are present in the given configuration. + Note

If a module successfully imports we can assume that all its requirements are installed.
+
Parameters:;;
  *config* – configuration information with possible DCS names as keys. If given, only attempt to import DCS modules defined in the configuration. Else, if `+None+`, attempt to import any supported DCS module.
Yields:;;
  a tuple containing the module `+name+` and the imported DCS class object.
patroni.dcs.parse_connection_string(value: str) → Tuple[ str, str | None] View on GitHub

Split and rejoin a URL string into a connection URL and an API URL. + Note

Original Governor stores connection strings for each cluster members in a following format:
\\__\\__
postgres://\{username}:\{password}@\{connect_address}/postgres
\\__\\__
Since each of our patroni instances provides their own REST API endpoint, it’s good to store this information in DCS along with PostgreSQL connection string. In order to not introduce new keys and be compatible with original Governor we decided to extend original connection string in a following way:
\\__\\__
postgres://\{username}:\{password}@\{connect_address}/postgres?application_name=\{api_url}
\\__\\__
This way original Governor could use such connection string as it is, because of feature of `+libpq+` library.
+
Parameters:;;
  *value* – The URL string to split.
Returns:;;
  the connection string stored in DCS split into two parts, `+conn_url+` and `+api_url+`.
patroni.dcs.slot_name_from_member_name(member_name: str) → str View on GitHub

Translate member name to valid PostgreSQL slot name. + Note

PostgreSQL’s replication slot names must be valid PostgreSQL names. This function maps the wider space of member names to valid PostgreSQL names. Names have their case lowered, dashes and periods common in hostnames are replaced with underscores, other characters are encoded as their unicode codepoint. Name is truncated to 64 characters. Multiple different member names may map to a single slot name.
+
Parameters:;;
  *member_name* – The string to convert to a slot name.
Returns:;;
  The string converted using the rules described above.

© Copyright 2015 Compose, Zalando SE. Revision 3d527f57.

Built with Sphinx using a theme provided by Read the Docs.

Read the Docs v: master