Replication
===========
.. raw:: html
Physical replication is one of the strengths of PostgreSQL and one of
the reasons why some of the largest organizations in the world have
chosen it for the management of their data in business continuity
contexts. Primarily used to achieve high availability, physical
replication also allows scale-out of read-only workloads and offloading
of some work from the primary.
.. Note::
This section is about replication within the same `Cluster` resource managed in the same Kubernetes cluster. For information about how to replicate with another Postgres `Cluster` resource, even across different Kubernetes clusters, please refer to the :ref:`Replica Clusters ` section.
Application-level replication
-----------------------------
Having contributed throughout the years to the replication feature in
PostgreSQL, we have decided to build high availability in CloudNativePG
on top of the native physical replication technology, and integrate it
directly in the Kubernetes API.
In Kubernetes terms, this is referred to as **application-level
replication**, in contrast with *storage-level replication*.
A very mature technology
------------------------
PostgreSQL has a very robust and mature native framework for replicating
data from the primary instance to one or more replicas, built around the
concept of transactional changes continuously stored in the WAL (Write
Ahead Log).
Started as the evolution of crash recovery and point in time recovery
technologies, physical replication was first introduced in PostgreSQL
8.2 (2006) through WAL shipping from the primary to a warm standby in
continuous recovery.
PostgreSQL 9.0 (2010) introduced WAL streaming and read-only replicas
through *hot standby*. In 2011, PostgreSQL 9.1 brought synchronous
replication at the transaction level, supporting :ref:`PgBouncerPoolMode ` =0
clusters. Cascading replication was added in PostgreSQL 9.2 (2012). The
foundations for :ref:`Logical Replication Publications ` were established in PostgreSQL 9.4 (2014),
and version 10 (2017) introduced native support for the
publisher/subscriber pattern to replicate data from an origin to a
destination. The table below summarizes these milestones.
.. csv-table::
:header: Version,Year,Feature
:widths: 10,10,25
:align: left
:class: longtable
8.2,2006,Warm Standby with WAL shipping
9.0,2010,Hot Standby and physical streaming replication
9.1,2011,Synchronous replication (priority-based)
9.2,2012,Cascading replication
9.4,2014,Foundations of logical replication
10,2017,Logical publisher/subscriber and quorum-based synchronous replication
This table highlights key PostgreSQL replication features and their
respective versions.
Streaming replication support
-----------------------------
At the moment, CloudNativePG natively and transparently manages physical
streaming replicas within a cluster in a declarative way, based on the
number of provided ``instances`` in the ``spec`` :
::
replicas = instances - 1 (where instances > 0)
Immediately after the initialization of a cluster, the operator creates
a user called ``streaming_replica`` as follows:
.. code:: sql
CREATE USER streaming_replica WITH REPLICATION;
- - NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOBYPASSRLS
Out of the box, the operator automatically sets up streaming replication
within the cluster over an encrypted channel and enforces TLS client
certificate authentication for the ``streaming_replica`` user - as
highlighted by the following excerpt taken from ``pg_hba.conf`` :
::
## Require client certificate authentication for the streaming_replica user
hostssl postgres streaming_replica all cert map=cnpg_streaming_replica
hostssl replication streaming_replica all cert map=cnpg_streaming_replica
.. Note::
For details on how CloudNativePG manages certificates, please refer to the :ref:`Certificates `
in the documentation.
If configured, the operator manages replication slots for all the
replicas in the HA cluster, ensuring that WAL files required by each
standby are retained on the primary’s storage, even after a failover or
switchover.
.. Note::
For details on how CloudNativePG automatically manages replication slots for the High Availability replicas, please refer to the :ref:`Replication slots for High Availability `
below.
Continuous backup integration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In case continuous backup is configured in the cluster, CloudNativePG
transparently configures replicas to take advantage of
``restore_command`` when in continuous recovery. As a result, PostgreSQL
can use the WAL archive as a fallback option whenever pulling WALs via
streaming replication fails.
Synchronous Replication
-----------------------
CloudNativePG supports both `quorum-based and priority-based synchronous replication for PostgreSQL `_ .
.. Warning::
By default, synchronous replication pauses write operations if the required number of standby nodes for WAL replication during transaction commits is unavailable. This behavior prioritizes data durability and aligns with PostgreSQL DBA best practices. However, if self-healing is a higher priority than strict data durability in your setup, this setting can be adjusted. For details on managing this behavior, refer to the :ref:`Data Durability and Synchronous Replication `
section.
.. Note::
The :ref:`*failover quorum* feature `
can be used alongside synchronous replication to improve data durability
and safety during failover events.
Direct configuration of the ``synchronous_standby_names`` option is not
permitted. However, CloudNativePG automatically populates this option
with the names of local pods, while also allowing customization to
extend synchronous replication beyond the ``Cluster`` resource. This can
be achieved through the :ref:`.spec.postgresql.synchronous ` .
Synchronous replication is disabled by default (the ``synchronous``
stanza is not defined). When defined, two options are mandatory:
- ``method`` : either ``any`` (quorum) or ``first`` (priority)
- ``number`` : the number of synchronous standby servers that
transactions must wait for responses from
Quorum-based Synchronous Replication
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In PostgreSQL, quorum-based synchronous replication ensures that
transaction commits wait until their WAL records are replicated to a
specified number of standbys. To enable this, set the ``method`` to
``any`` .
This replication method is the most common setup for a CloudNativePG
cluster.
Example
^^^^^^^
The example below, based on a typical ``cluster-example`` configuration
with three instances, sets up quorum-based synchronous replication with
at least one instance:
.. code:: yaml
postgresql:
synchronous:
method: any
number: 1
With this configuration, CloudNativePG automatically sets the content of
``synchronous_standby_names`` as follows:
.. code:: console
ANY 1 (cluster-example-2, cluster-example-3, cluster-example-1)
Migrating from Deprecated Synchronous Replication Implementation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This section outlines how to migrate from the deprecated quorum-based
synchronous replication format to the newer, more robust implementation
in CloudNativePG.
Given the following manifest:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: angus
spec:
instances: 3
minSyncReplicas: 1
maxSyncReplicas: 1
storage:
size: 1Gi
You can update it to the new format as follows:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: angus
spec:
instances: 3
storage:
size: 1Gi
postgresql:
synchronous:
method: any
number: 1
dataDurability: required
To prioritize self-healing over strict data durability, set
``dataDurability`` to ``preferred`` instead.
Priority-based Synchronous Replication
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PostgreSQL’s priority-based synchronous replication makes transaction
commits wait until their WAL records are replicated to the requested
number of synchronous standbys chosen based on their priorities.
Standbys listed earlier in the ``synchronous_standby_names`` option are
given higher priority and considered synchronous. If a current
synchronous standby disconnects, it is immediately replaced by the
next-highest-priority standby. To use this method, set ``method`` to
``first`` .
.. Note::
Currently, this method is most useful when extending synchronous replication beyond the current cluster using the `maxStandbyNamesFromCluster` , `standbyNamesPre` , and `standbyNamesPost` options explained below.
Controlling ``synchronous_standby_names`` Content
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
By default, CloudNativePG populates ``synchronous_standby_names`` with
the names of local pods in a ``Cluster`` resource, ensuring synchronous
replication within the PostgreSQL cluster. You can customize the content
of ``synchronous_standby_names`` based on your requirements and
replication method (quorum or priority) using the following optional
parameters in the ``.spec.postgresql.synchronous`` stanza:
- ``maxStandbyNamesFromCluster`` : the maximum number of pod names from
the local ``Cluster`` object that can be automatically included in the
``synchronous_standby_names`` option in PostgreSQL.
- ``standbyNamesPre`` : a list of standby names (specifically
``application_name`` ) to be prepended to the list of local pod names
automatically listed by the operator.
- ``standbyNamesPost`` : a list of standby names (specifically
``application_name`` ) to be appended to the list of local pod names
automatically listed by the operator.
.. Warning::
You are responsible for ensuring the correct names in `standbyNamesPre` and `standbyNamesPost` . CloudNativePG expects that you manage any standby with an `application_name` listed here, ensuring their high availability. Incorrect entries can jeopardize your PostgreSQL database uptime.
Examples
^^^^^^^^
Here are some examples, all based on a ``cluster-example`` with three
instances:
If you set:
.. code:: yaml
postgresql:
synchronous:
method: any
number: 1
maxStandbyNamesFromCluster: 1
standbyNamesPre:
- angus
The content of ``synchronous_standby_names`` will be:
.. code:: console
ANY 1 (angus, cluster-example-2)
If you set:
.. code:: yaml
postgresql:
synchronous:
method: any
number: 1
maxStandbyNamesFromCluster: 0
standbyNamesPre:
- angus
- malcolm
The content of ``synchronous_standby_names`` will be:
.. code:: console
ANY 1 (angus, malcolm)
If you set:
.. code:: yaml
postgresql:
synchronous:
method: first
number: 2
maxStandbyNamesFromCluster: 1
standbyNamesPre:
- angus
standbyNamesPost:
- malcolm
The ``synchronous_standby_names`` option will look like:
.. code:: console
FIRST 2 (angus, cluster-example-2, malcolm)
Data Durability and Synchronous Replication
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``dataDurability`` option in the ``.spec.postgresql.synchronous``
stanza controls the trade-off between data safety and availability for
synchronous replication. It can be set to ``required`` or ``preferred``
, with the default being ``required`` if not specified.
.. Note::
`preferred` can only be used when `standbyNamesPre` and `standbyNamesPost` are unset.
Required Data Durability
^^^^^^^^^^^^^^^^^^^^^^^^
When ``dataDurability`` is set to ``required`` , PostgreSQL only
considers transactions committed once WAL (Write-Ahead Log) records have
been replicated to the specified number of synchronous standbys. This
setting prioritizes data safety over availability, meaning write
operations will pause if the required number of synchronous standbys is
unavailable. This ensures zero data loss (RPO=0) but may reduce database
availability during network disruptions or standby failures.
Synchronous standbys are selected in this priority order:
1. Healthy instances
2. Unhealthy instances
3. Primary
The list is then truncated based on ``maxStandbyNamesFromCluster`` if
this value is set, prioritizing healthy instances and ensuring
``synchronous_standby_names`` is populated.
.. _example-1:
Example
'''''''
Consider the following example:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: foo
spec:
instances: 3
postgresql:
synchronous:
method: any
number: 1
dataDurability: required
1. Initial state. The content of ``synchronous_standby_names`` is:
::
ANY 1 ("foo-2","foo-3","foo-1")
2. ``foo-2`` becomes unavailable. It gets pushed back in priority:
::
ANY 1 ("foo-3","foo-2","foo-1")
3. ``foo-3`` also becomes unavailable. The list contains no healthy
standbys:
::
ANY 1 ("foo-2","foo-3","foo-1")
At this point no write operations will be allowed until at least one of
the standbys is available again.
4. When the standbys are available again, ``synchronous_standby_names``
will be back to the initial state.
Preferred Data Durability
^^^^^^^^^^^^^^^^^^^^^^^^^
When ``dataDurability`` is set to ``preferred`` , the required number of
synchronous instances adjusts based on the number of available standbys.
PostgreSQL will attempt to replicate WAL records to the designated
number of synchronous standbys, but write operations will continue even
if fewer than the requested number of standbys are available.
.. Note::
Make sure you have a clear understanding of what *ready/available* means for a replica and set your expectations accordingly. By default, a replica is considered ready when it has successfully connected to the source at least once. However, CloudNativePG allows you to configure startup and readiness probes for replicas based on maximum lag. For more details, please refer to the :ref:`Postgres Instance Manager ` .
This setting balances data safety with availability, enabling
applications to continue writing during temporary standby
unavailability—hence, it’s also known as *self-healing mode*.
.. Warning::
This mode may result in data loss if all standbys become unavailable.
With ``preferred`` data durability, **only healthy replicas** are
included in ``synchronous_standby_names`` .
.. _example-2:
Example
'''''''
Consider the following example. For demonstration, we’ll use a cluster
named ``bar`` with 5 instances and 2 synchronous standbys:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: bar
spec:
instances: 5
postgresql:
synchronous:
method: any
number: 2
dataDurability: preferred
1. Initial state. The content of ``synchronous_standby_names`` is:
::
ANY 2 ("bar-2","bar-3", "bar-4", "bar-5")
2. ``bar-2`` and ``bar-3`` become unavailable. They are removed from the
list:
::
ANY 2 ("bar-4", "bar-5")
3. ``bar-4`` also becomes unavailable. It gets removed from the list.
Since the number of available standbys is less than the requested
number, the requested amount gets reduced:
::
ANY 1 ("bar-5")
4. ``bar-5`` also becomes unavailable. ``synchronous_standby_names``
becomes empty, disabling synchronous replication completely. Write
operations will continue, but with the risk of potential data loss in
case of a primary failure.
5. When the replicas are back, ``synchronous_standby_names`` will be
back to the initial state.
Synchronous Replication (Deprecated)
------------------------------------
.. Warning::
Prior to CloudNativePG 1.24, only the quorum-based synchronous replication implementation was supported. Although this method is now deprecated, it will not be removed anytime soon. The new method prioritizes data durability over self-healing and offers more robust features, including priority-based synchronous replication and full control over the `synchronous_standby_names` option. It is recommended to gradually migrate to the new configuration method for synchronous replication, as explained in the previous paragraph.
.. Note::
The deprecated method and the new method are mutually exclusive.
CloudNativePG supports the configuration of **quorum-based synchronous
streaming replication** via two configuration options called
``minSyncReplicas`` and ``maxSyncReplicas`` , which are the minimum and
the maximum number of expected synchronous standby replicas available at
any time. For self-healing purposes, the operator always compares these
two values with the number of available replicas to determine the
quorum.
.. Note::
By default, synchronous replication selects among all the available replicas indistinctively. You can limit on which nodes your synchronous replicas can be scheduled, by working on node labels through the `syncReplicaElectionConstraint` option as described in the next section.
Synchronous replication is disabled by default (``minSyncReplicas`` and
``maxSyncReplicas`` are not defined). In case both ``minSyncReplicas``
and ``maxSyncReplicas`` are set, CloudNativePG automatically updates the
``synchronous_standby_names`` option in PostgreSQL to the following
value:
::
ANY q (pod1, pod2, ...)
Where:
- ``q`` is an integer automatically calculated by the operator to be:
``1 ≤ minSyncReplicas ≤ q ≤ maxSyncReplicas ≤ readyReplicas``
- ``pod1, pod2, ...`` is the list of all PostgreSQL pods in the cluster
.. Warning::
To provide self-healing capabilities, the operator can ignore `minSyncReplicas` if such value is higher than the currently available number of replicas. Synchronous replication is automatically disabled when `readyReplicas` is `0` .
As stated in the `PostgreSQL documentation `_ , the *method ``ANY`` specifies a
quorum-based synchronous replication and makes transaction commits wait
until their WAL records are replicated to at least the requested number
of synchronous standbys in the list*.
.. Note::
Even though the operator chooses self-healing over enforcement of synchronous replication settings, our recommendation is to plan for synchronous replication only in clusters with 3+ instances or, more generally, when `maxSyncReplicas < (instances - 1)` .
Select nodes for synchronous replication
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CloudNativePG enables you to select which PostgreSQL instances are
eligible to participate in a quorum-based synchronous replication set
through anti-affinity rules based on the node labels where the PVC
holding the PGDATA and the Postgres pod are.
.. Note::
For more information on the general pod affinity and anti-affinity rules, please check the :ref:`Scheduling ` .
.. Warning::
The `.spec.postgresql.syncReplicaElectionConstraint` option only applies to the legacy implementation of synchronous replication (see :ref:`Synchronous Replication (Deprecated) ` ).
As an example use-case for this feature: in a cluster with a single sync
replica, we would be able to ensure the sync replica will be in a
different availability zone from the primary instance, usually
identified by the ``topology.kubernetes.io/zone`` `label on a node `_ . This
would increase the robustness of the cluster in case of an outage in a
single availability zone, especially in terms of recovery point
objective ( :ref:`PgBouncerPoolMode ` ).
The idea of anti-affinity is to ensure that sync replicas that
participate in the quorum are chosen from pods running on nodes that
have different values for the selected labels (in this case, the
availability zone label) then the node where the primary is currently in
execution. If no node matches such criteria, the replicas are eligible
for synchronous replication.
.. Note::
The self-healing enforcement still applies while defining additional constraints for synchronous replica election (see :ref:`Zero-Data-Loss Clusters Through Synchronous Replication ` ).
The example below shows how this can be done through the
``syncReplicaElectionConstraint`` section within ``.spec.postgresql`` .
``nodeLabelsAntiAffinity`` allows you to specify those node labels that
need to be evaluated to make sure that synchronous replication will be
dynamically configured by the operator between the current primary and
the replicas which are located on nodes having a value of the
availability zone label different from that of the node where the
primary is:
.. code:: yaml
spec:
instances: 3
postgresql:
syncReplicaElectionConstraint:
enabled: true
nodeLabelsAntiAffinity:
- topology.kubernetes.io/zone
As you can imagine, the availability zone is just an example, but you
could customize this behavior based on other labels that describe the
node, such as storage, CPU, or memory.
Replication slots
-----------------
`Replication slots `_
are a native PostgreSQL feature introduced in 9.4 that provides an
automated way to ensure that the primary does not remove WAL segments
until all the attached streaming replication clients have received them,
and that the primary does not remove rows which could cause a recovery
conflict even when the standby is ( temporarily) disconnected.
A replication slot exists solely on the instance that created it, and
PostgreSQL does not replicate it on the standby servers. As a result,
after a failover or a switchover, the new primary does not contain the
replication slot from the old primary. This can create problems for the
streaming replication clients that were connected to the old primary and
have lost their slot.
CloudNativePG provides a turn-key solution to synchronize the content of
physical replication slots from the primary to each standby, addressing
two use cases:
- the replication slots automatically created for the High Availability
of the Postgres cluster ( see :ref:`Replication slots for High Availability `
for details)
- :ref:`User-Defined Replication slots ` created on the primary
Replication slots for High Availability
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CloudNativePG fills this gap by introducing the concept of
cluster-managed replication slots, starting with high availability
clusters. This feature automatically manages physical replication slots
for each hot standby replica in the High Availability cluster, both in
the primary and the standby.
In CloudNativePG, we use the terms:
- **Primary HA slot**: a physical replication slot whose lifecycle is
entirely managed by the current primary of the cluster and whose
purpose is to map to a specific standby in streaming replication. Such
a slot lives on the primary only.
- **Standby HA slot**: a physical replication slot for a standby whose
lifecycle is entirely managed by another standby in the cluster, based
on the content of the ``pg_replication_slots`` view in the primary,
and updated at regular intervals using
``pg_replication_slot_advance()`` .
This feature is enabled by default and can be disabled via
configuration. For details, please refer to the :ref:`ReplicationSlotsConfiguration ` . Here
follows a brief description of the main options:
``.spec.replicationSlots.highAvailability.enabled``
if ``true`` , the feature is enabled (``true`` is the default)
``.spec.replicationSlots.highAvailability.slotPrefix``
the prefix that identifies replication slots managed by the operator for
this feature (default: ``_cnpg_`` )
``.spec.replicationSlots.updateInterval``
how often the standby synchronizes the position of the local copy of the
replication slots with the position on the current primary, expressed in
seconds (default: 30)
Although it is not recommended, if you desire a different behavior, you
can customize the above options.
For example, the following manifest will create a cluster with
replication slots disabled.
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
# Disable replication slots for HA in the cluster
replicationSlots:
highAvailability:
enabled: false
storage:
size: 1Gi
User-Defined Replication slots
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Although CloudNativePG doesn’t support a way to declaratively define
physical replication slots, you can still `create your own slots via SQL `_ .
.. Note::
At the moment, we don't have any plans to manage replication slots in a declarative way, but it might change depending on the feedback we receive from users. The reason is that replication slots exist for a specific purpose and each should be managed by a specific application the oversees the entire lifecycle of the slot on the primary.
CloudNativePG can manage the synchronization of any user managed
physical replication slots between the primary and standbys, similarly
to what it does for the HA replication slots explained above (the only
difference is that you need to create the replication slot).
This feature is enabled by default (meaning that any replication slot is
synchronized), but you can disable it or further customize its behavior
(for example by excluding some slots using regular expressions) through
the ``synchronizeReplicas`` stanza. For example:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
replicationSlots:
synchronizeReplicas:
enabled: true
excludePatterns:
- "^foo"
For details, please refer to the :ref:`ReplicationSlotsConfiguration ` . Here follows a brief
description of the main options:
``.spec.replicationSlots.synchronizeReplicas.enabled``
When true or not specified, every user-defined replication slot on the
primary is synchronized on each standby. If changed to false, the
operator will remove any replication slot previously created by itself
on each standby.
``.spec.replicationSlots.synchronizeReplicas.excludePatterns``
A list of regular expression patterns to match the names of user-defined
replication slots to be excluded from synchronization. This can be
useful to exclude specific slots based on naming conventions.
.. Warning::
Users utilizing this feature should carefully monitor user-defined replication slots to ensure they align with their operational requirements and do not interfere with the failover process.
Synchronization frequency
^^^^^^^^^^^^^^^^^^^^^^^^^
You can also control the frequency with which a standby queries the
``pg_replication_slots`` view on the primary, and updates its local copy
of the replication slots, like in this example:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
# Reduce the frequency of standby HA slots updates to once every 5 minutes
replicationSlots:
updateInterval: 300
storage:
size: 1Gi
Logical Decoding Slot Synchronization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CloudNativePG can synchronize logical decoding (replication) slots
across all nodes in a high-availability cluster, ensuring seamless
continuation of logical replication after a failover or switchover. This
feature is disabled by default, and enabling it requires two steps.
The first step is to enable logical decoding slot synchronization:
.. code:: yaml
# ...
replicationSlots:
highAvailability:
synchronizeLogicalDecoding: true
The second step involves configuring PostgreSQL parameters: the required
configuration depends on your PostgreSQL version, as explained below.
When enabled, the operator automatically manages logical decoding slot
states during failover and switchover, preventing slot invalidation and
avoiding data loss for logical replication clients.
Behavior on PostgreSQL 17 and later
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For PostgreSQL 17 and newer, CloudNativePG transparently manages the
`synchronized_standby_slots `_ .
You must enable both ``sync_replication_slots`` and
``hot_standby_feedback`` in your PostgreSQL configuration:
.. code:: yaml
## ...
postgresql:
parameters:
# ...
hot_standby_feedback: on
sync_replication_slots: on
Additionally, you must create the logical replication ``Subscription``
with the ``failover`` option enabled, for example:
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Subscription
## ...
spec:
## ...
parameters:
failover: true
## ...
When configured, logical WAL sender processes send decoded changes to
plugins only after the specified replication slots confirm receiving and
flushing the relevant WAL, ensuring that:
- logical replication slots do not consume changes until they are safely
received by the replicas of the publisher, and
- logical replication clients can seamlessly reconnect to a promoted
standby without missing data after failover.
For more details on logical replication slot synchronization, see the
PostgreSQL documentation on
`Logical Replication Failover `_ .
Behavior on PostgreSQL 16 and earlier
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For PostgreSQL 16 and older versions, CloudNativePG uses the
`pg_failover_slots `_
to maintain synchronization of logical replication slots across
failovers.
Capping the WAL size retained for replication slots
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When replication slots is enabled, you might end up running out of disk
space due to PostgreSQL trying to retain WAL files requested by a
replication slot. This might happen due to a standby that is
(temporarily?) down, or lagging, or simply an orphan replication slot.
Starting with PostgreSQL 13, you can take advantage of the
`max_slot_wal_keep_size `_
configuration option controlling the maximum size of WAL files that
replication slots are allowed to retain in the ``pg_wal`` directory at
checkpoint time. By default, in PostgreSQL ``max_slot_wal_keep_size`` is
set to ``-1`` , meaning that replication slots may retain an unlimited
amount of WAL files. As a result, our recommendation is to explicitly
set ``max_slot_wal_keep_size`` when replication slots support is
enabled. For example:
.. code:: ini
# ...
postgresql:
parameters:
max_slot_wal_keep_size: "10GB"
# ...
Monitoring replication slots
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Replication slots must be carefully monitored in your infrastructure. By
default, we provide the ``pg_replication_slots`` metric in our
Prometheus exporter with key information such as the name of the slot,
the type, whether it is active, the lag from the primary.
.. Note::
Please refer to the :ref:`Monitoring Backup Progress ` for details on how to monitor a CloudNativePG deployment.