patroni.dcs package

Submodules

Module contents

Abstract classes for Distributed Configuration Store.

class patroni.dcs.AbstractDCS(config: Dict[str, Any], mpp: AbstractMPP)

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:

  • _postgresql_cluster_loader():

    method which processes the structure of data stored in the DCS used to build the Cluster object with all relevant associated data.

  • _mpp_cluster_loader():

    Similar to above but specifically representing MPP group and workers information.

  • _load_cluster():

    main method for calling specific loader method to build the Cluster object representing the state and topology of the cluster.

Functional methods that are critical in their timing and must be written with ACID transaction properties in mind:

  • attempt_to_acquire_leader():

    method used in the leader race to attempt to acquire the leader lock by creating the leader key in the DCS, if it does not exist.

  • _update_leader():

    method to update leader key in DCS. Relies on Compare-And-Set to ensure the Primary lock key is updated. If this fails to update within the retry_timeout window the Primary will be demoted.

Functional method that relies on Compare-And-Create to ensure only one member creates the relevant key:

  • initialize():

    method used in the race for cluster initialization which creates the initialize key in the DCS.

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:

  • delete_sync_state():

    likewise, a method to remove synchronous state sync key from the DCS.

  • delete_cluster():

    method which will remove cluster information from the DCS. Used only from patronictl.

  • _delete_leader():

    method relies on CAS, used by a member that is the current leader, to remove the leader key in the DCS.

  • cancel_initialization():

    method to remove the initialize key for the cluster from the DCS.

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_postgresql_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], mpp: AbstractMPP) None

Prepare DCS paths, MPP object, initial values for state information and processing dependencies.

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

  • mpp – an object implementing AbstractMPP interface.

_abc_impl = <_abc._abc_data object>
_build_retain_slots(cluster: Cluster, slots: Dict[str, int] | None) List[str] | None

Handle retention policy of physical replication slots for cluster members.

When the member key is missing we want to keep its replication slot for a while, so that WAL segments will not be already absent when it comes back online. It is being solved by storing the list of replication slots representing members in the retain_slots field of the /status key.

This method handles retention policy by keeping the list of such replication slots in memory and removing names when they were observed longer than member_slots_ttl ago.

Parameters:
  • clusterCluster object with information about the current cluster state.

  • slots – slot names with LSN values that exist on the leader node and consists of slots for cluster members and permanent replication slots.

Returns:

the list of replication slots to be written to /status key or None.

abstractmethod _delete_leader(leader: Leader) bool

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_mpp_cluster() Cluster

Load MPP cluster from DCS.

Returns:

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

abstractmethod _load_cluster(path: str, loader: Callable[[Any], Cluster | Dict[int, Cluster]]) Cluster | Dict[int, Cluster]

Main abstract method that implements the loading of Cluster instance.

Note

Internally this method should call the loader method that will build Cluster object which represents current state and topology of the cluster in DCS. This method supposed to be called only by the 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.

abstractmethod _mpp_cluster_loader(path: Any) Dict[int, Cluster]

Load and build all PostgreSQL clusters from a single MPP cluster.

Parameters:

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

Returns:

all MPP groups as dict, with group IDs as keys and Cluster objects as values.

abstractmethod _postgresql_cluster_loader(path: Any) Cluster

Load and build the Cluster object from DCS, which represents a single PostgreSQL cluster.

Parameters:

path – the path in DCS where to load Cluster from.

Returns:

Cluster instance.

_set_loop_wait(loop_wait: int) None

Set new loop_wait value.

Parameters:

loop_wait – value to set.

abstractmethod _update_leader(leader: Leader) bool

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.

abstractmethod _write_failsafe(value: str) bool

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.

abstractmethod _write_leader_optime(last_lsn: str) bool

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.

abstractmethod _write_status(value: str) bool

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.

acquire_leader_lock() bool

Attempt to acquire leader lock.

Note

This method wraps attempt_to_acquire_leader(): and is used to reset retention time of physical replication slots that representing members of the cluster when current node is to be promoted to the leader.

Returns:

True if the leader key has been created successfully.

abstractmethod attempt_to_acquire_leader() bool

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.

abstractmethod cancel_initialization() bool

Removes the initialize key for a cluster.

Returns:

True if successfully committed to DCS.

client_path(path: str) str

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.

abstractmethod delete_cluster() bool

Delete cluster from DCS.

Returns:

True if successfully committed to DCS.

delete_leader(leader: Leader | None, last_lsn: int | None = None) bool

Update optime/leader and voluntarily 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.

  • last_lsn – latest checkpoint location in bytes.

Returns:

boolean result of called abstract _delete_leader().

abstractmethod delete_sync_state(version: Any | None = None) bool

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_cluster() Cluster

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 PostgreSQL or MPP implementation of Cluster depending on availability.

Returns:

get_mpp_coordinator() Cluster | None

Load the PostgreSQL cluster for the MPP Coordinator.

Note

This method is only executed on the worker nodes to find the coordinator.

Returns:

Select Cluster instance associated with the MPP Coordinator group ID.

property history_path: str

Get the client path for history.

abstractmethod initialize(create_new: bool = True, sysid: str = '') bool

Race for cluster initialization.

This method should atomically create initialize key and return True, otherwise it should return False.

Parameters:
  • create_newFalse if the key should already exist (in the case we are setting the system_id).

  • sysid – PostgreSQL cluster system identifier, if specified, is written to the key.

Returns:

True if key has been created successfully.

property initialize_path: str

Get the client path for initialize.

is_mpp_coordinator() bool

Cluster instance has a Coordinator group ID.

Returns:

True if the given node is running as the MPP Coordinator.

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

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

Parameters:
  • leader – value to set for leader.

  • candidate – value to set for member.

  • scheduled_at – value converted to ISO date format for scheduled_at.

  • version – for conditional update of the key/object.

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.

property mpp: AbstractMPP

Get the effective underlying MPP, if any has been configured.

reload_config(config: Config | Dict[str, Any]) None

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

Clear cached state of DCS.

abstractmethod set_config_value(value: str, version: Any | None = None) bool

Create or update /config key in DCS.

Parameters:
  • value – new value to set in the config key.

  • version – for conditional update of the key/object.

Returns:

True if successfully committed to DCS.

abstractmethod set_failover_value(value: str, version: Any | None = None) bool

Create or update /failover key.

Parameters:
  • value – value to set.

  • version – for conditional update of the key/object.

Returns:

True if successfully committed to DCS.

abstractmethod set_history_value(value: str) bool

Set value for history in DCS.

Parameters:

value – new value of history key/object.

Returns:

True if successfully committed to DCS.

abstractmethod set_retry_timeout(retry_timeout: int) None

Set the new value for retry_timeout.

abstractmethod set_sync_state_value(value: