Coder Social home page Coder Social logo

pg_failover_slots's Introduction

pg_failover_slots

PG Failover Slots is for anyone with Logical Replication Slots on Postgres databases that are also part of a Physical Streaming Replication architecture.

Since logical replication slots are only maintained on the primary node, downstream subscribers don't receive any new changes from a newly promoted primary until the slot is created, which is unsafe because the information that includes which data a subscriber has confirmed receiving and which log data still needs to be retained for the subscriber will have been lost, resulting in an unknown gap in data changes. PG Failover Slots makes logical replication slots usable across a physical failover using the following features:

  • Copies any missing replication slots from the primary to the standby
  • Removes any slots from the standby that aren't found on the primary
  • Periodically synchronizes the position of slots on the standby based on the primary
  • Ensures that selected standbys receive data before any of the logical slot walsenders can send data to consumers

PostgreSQL 11 or higher is required.

How to check the standby is ready

The slots are not synchronized to the standby immediately, because of consistency reasons. The standby can be too behind logical slots, or too ahead of logical slots on primary when the pg_failover_slots module is activated, so the module does verification and only synchronizes slots when it's actually safe.

This, however brings a need to verify that the slots are synchronized and that the standby is actually ready to be a failover target with consistent logical decoding for all slots. This only needs to be done initially, once the slots are synchronized the first time, they will always be consistent as long as the module is active in the cluster.

The check for whether slots are fully synchronized with primary is relatively simple. The slots just need to be present in pg_replication_slots view on standby and have active state false. An active state true means the slots is currently being initialized.

For example consider the following psql session:

# SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical';
    slot_name    | active
-----------------+--------
regression_slot1 | f
regression_slot2 | f
regression_slot3 | t

This means that slots regression_slot1 and regression_slot2 are synchronized from primary to standby and regression_slot3 is still being synchronized. If failover happens at this stage, the regression_slot3 will be lost.

Now let's wait a little and query again:

# SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical';
    slot_name    | active
-----------------+--------
regression_slot1 | f
regression_slot2 | f
regression_slot3 | f

Now all the the three slots are synchronized and the standby can be used for failover without losing logical decoding state for any of them.

Prerequisite settings

The module throws hard errors if the following settings are not adjusted:

  • hot_standby_feedback should be on
  • primary_slot_name should be non-empty

These are necessary to connect to the primary so it can send the xmin and catalog_xmin separately over hot_standby_feedback.

Configuration options

The module itself must be added to shared_preload_libraries on both the primary instance as well as any standby that is used for high availability (failover or switchover) purposes.

The behavior of pg_failover_slots is configurable using these configuration options (set in postgresql.conf).

pg_failover_slots.synchronize_slot_names

This standby option allows setting which logical slots should be synchronized to this physical standby. It's a comma-separated list of slot filters.

A slot filter is defined as key:value pair (separated by colon) where key can be one of:

  • name - specifies to match exact slot name
  • name_like - specifies to match slot name against SQL LIKE expression
  • plugin - specifies to match slot plugin name against the value

The key can be omitted and will default to name in that case.

For example, 'my_slot_name,plugin:test_decoding' will synchronize the slot named "my_slot_name" and any slots that use the test_decoding plugin.

If this is set to an empty string, no slots will be synchronized to this physical standby.

The default value is 'name_like:%', which means all logical replication slots will be synchronized.

pg_failover_slots.drop_extra_slots

This standby option controls what happens to extra slots on the standby that are not found on the primary using the pg_failover_slots.synchronize_slot_names filter. If it's set to true (which is the default), they will be dropped, otherwise they will be kept.

pg_failover_slots.primary_dsn

A standby option for specifying the connection string to use to connect to the primary when fetching slot information.

If empty (default), then use same connection string as primary_conninfo.

Note that primary_conninfo cannot be used if there is a password field in the connection string because it gets obfuscated by PostgreSQL and pg_failover_slots can't actually see the password. In this case, pg_failover_slots.primary_dsn must be configured.

pg_failover_slots.standby_slot_names

This option is typically used in failover configurations to ensure that the failover-candidate streaming physical replica(s) have received and flushed all changes before they ever become visible to any subscribers. That guarantees that a commit cannot vanish on failover to a standby for the consumer of a logical slot.

Replication slots whose names are listed in the comma-separated pg_failover_slots.standby_slot_names list are treated specially by the walsender on the primary.

Logical replication walsenders will ensure that all local changes are sent and flushed to the replication slots in pg_failover_slots.standby_slot_names before the walsender sends those changes for the logical replication slots. Effectively, it provides a synchronous replication barrier between the named list of slots and all the consumers of logically decoded streams from walsender.

Any replication slot may be listed in pg_failover_slots.standby_slot_names; both logical and physical slots work, but it's generally used for physical slots.

Without this safeguard, two anomalies are possible where a commit can be received by a subscriber and then vanish from the provider on failover because the failover candidate hadn't received it yet:

  • For 1+ subscribers, the subscriber may have applied the change but the new provider may execute new transactions that conflict with the received change, as it never happened as far as the provider is concerned;

and/or

  • For 2+ subscribers, at the time of failover, not all subscribers have applied the change. The subscribers now have inconsistent and irreconcilable states because the subscribers that didn't receive the commit have no way to get it now.

Setting pg_failover_slots.standby_slot_names will (by design) cause subscribers to lag behind the provider if the provider's failover-candidate replica(s) are not keeping up. Monitoring is thus essential.

pg_failover_slots.standby_slots_min_confirmed

Controls how many of the pg_failover_slots.standby_slot_names have to confirm before we send data through the logical replication slots. Setting -1 (the default) means to wait for all entries in pg_failover_slots.standby_slot_names.

Release notes

v1.0.1

Version 1.0.1 fixes several compatibility bugs.

  • Fix support for PG13 and older

    The missing interfaces caused either disconnects or outright crashes on PG13 and older.

  • Test compatibility improvements

    Tests now work on PG11, and are more resilient to testing on slower machines.

  • PG16 compatibility improvements

  • Various minor cleanups

pg_failover_slots's People

Contributors

ashucoek avatar ibarwick avatar mnencia avatar onderkalaci avatar petere avatar pjmodos avatar theadamwright avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pg_failover_slots's Issues

WARNING: dropping replication slot <physical-slot> (by pg _failover_slots worker)

After we set up physical slots for primary_slot_name (for pg_failover_slots to work on our standby DBs), pg_failover_slot worker keeps dropping the standbys' physical slots that are supposed to be sync-ed by EFM from primary to standbys. We saw it working without dropping physical slots (which actually exist on primary) earlier, but not sure what changed its behavior. The current behavior seems inconsistent with the documentation.

pg_failover_slots.drop_extra_slots
This standby option controls what happens to extra slots on the standby that are not found on the primary using the pg_failover_slots.synchronize_slot_names filter. If it's set to true (which is the default), they will be dropped, otherwise they will be kept.

How do I fix this?

Proper synchronization of logical replication slots between Primary and Standby.

Greetings,

Is it possible to provide a semi-universal example of the pg-failover-slots configuration.

I try to do configuration according to existing documentation - replication slot(s) do not appear on the standby node during the clone from the primary or if I create replication slot later after operational failover cluster created (prime and standby nodes registered). Obviously, after Prime failure and Standby promotion as a new Prime, the replication slot is absent on the new Prime node.

As an example, failover cluster {Prime : pg14, Standby : pg14}, using EDB repmgr; [client : pg14]. Prime has logical replication publication test_pub for all tables of testdb. Client has logical replication subscription test_sub to the Prime.

How to configure postgresql.conf on Prime and Standby, so test_sub replication slot will be existed on the Standby, and synchronized between Prime and Standby.

Here is a configuration, that I tried and which is not working:
Installed on Prime and Standby edb-pg14-pg-failover-slots1
[postgresql.conf]:
shared_preload_libraries = 'repmgr, pg_failover_slots'
pg_failover_slots.synchronize_slot_names='name_like:%' # would like to synchronize all available replication slots
pg_failover_slots.standby_slot_names='name_like:%'

I also tried:
pg_failover_slots.standby_slots_min_confirmed = -1
Did not help.

Your help would be greatly appreciated!

pg_failover_slots extension with CNPG

Hello,
I'm trying to use this extension with CNPG and i have no problem with basic configuration, however, i have a few questions.
This is my context and configuration:

  • I have a primary and one replica

  • I'm using a CDC tool (debezium) that's why i need this extension to ensure that i will not lose data after failover / switchover

  • About configuration:
    hot_standby_feedback: on
    pg_failover_slots.synchronize_slot_names: debezium
    I dont use primary_slot_name because i noticed that with CNPG, this value is never empty (can you confirm it ?)

  • Questions:

  1. I would like to use pg_failover_slots.standby_slot_names parameter to ensure that i will not lose data, so if I've understood correctly, I need to set the value of my replica physical's replication_slot ! (for example the slot used for streaming_replication ?)
    ex: pg_failover_slots.standby_slot_names = cnpg-test-2 (in case of cnpg-test-1 is primary db)

  2. So in case of failover/switchover , cnpg-test-1 become replica and what about pg_failover_slots.standby_slot_names value ? Should i manually upgrade the value to pg_failover_slots.standby_slot_names = cnpg-test-1 ?

  3. Is there a way to retrieve this physical's replication_slot name (replica pod) into the manifest declaration ?

thanks

receivePtr is not a valid restart_lsn

wait_for_primary_slot_catchup does this, but that's incorrect:

		if (new_slot->restart_lsn > receivePtr)
			new_slot->restart_lsn = receivePtr;

restart_lsn is expected to be a valid decoding position, in particular it needs to meet this assert in XLogDecodeNextRecord:

Assert(XRecOffIsValid(RecPtr))

The flush position can easily be a multiple of WAL page, for example, violating the assert.

Replication slot lost after switchover?

Situation: a PostgreSQL 13 master/standby setup on-premises using repmgr.
We recently added a logical standby, by the use of AWS Data Migration Server (DMS) to replicate to a cloud instance.
To avoid the replication to fail after a switchover, I installed pg_failover_slots on both the master and standby. And after adding some pg_hba.conf rules, the logical replication_slot also gets visible on the standby node.

primary:

SELECT * FROM pg_replication_slots WHERE slot_type = 'logical';
-[ RECORD 1 ]-------+---------------------------------------------------------------
slot_name           | a2ngextskh5dxnxw_00139051_195c95de_355f_4ea8_8739_4185610c15b4
plugin              | test_decoding
slot_type           | logical
datoid              | 139051
database            | persoon
temporary           | f
active              | t
active_pid          | 59662
xmin                | ¤
catalog_xmin        | 175553299
restart_lsn         | 537/392661A8
confirmed_flush_lsn | 537/392661A8
wal_status          | reserved
safe_wal_size       | ¤

standby:

 SELECT * FROM pg_replication_slots WHERE slot_type = 'logical';
-[ RECORD 1 ]-------+---------------------------------------------------------------
slot_name           | a2ngextskh5dxnxw_00139051_195c95de_355f_4ea8_8739_4185610c15b4
plugin              | test_decoding
slot_type           | logical
datoid              | 139051
database            | persoon
temporary           | f
active              | t
active_pid          | 87075
xmin                | ¤
catalog_xmin        | 175553797
restart_lsn         | 537/3A000028
confirmed_flush_lsn | ¤
wal_status          | reserved
safe_wal_size       | ¤

For some reason I have to stop the replication task in AWS first, else the primary instance will not shutdown (but that is not related to pg_failover_slots) during a switchover. I see the "active" state turn to false on the primary after stopping the replication task, but no change on the standby. After a switchover, the replication slot gets lost on both instances. And the replication task turns in error state after restart.

Any clue why this is not working?

ERROR: cannot synchronize replication slot positions because primary_slot_name is not set

Why does it require that we have a physical replication slot for the streaming replication's primary_slot_name?

Our csvlog looks like the following:

2023-04-28 11:53:22.156 PDT,,,725006,,644c161c.b100e,5,,2023-04-28 11:53:16 PDT,,0,LOG,00000,"database system is ready to accept read-only connections",,,,,,,,,"","postmaster",,0
2023-04-28 11:53:22.159 PDT,,,725568,,644c1622.b1240,1,,2023-04-28 11:53:22 PDT,,0,LOG,00000,"starting pg_failover_slots replica worker",,,,,,,,,"pg_failover_slots worker","pg_failover_slots worker",,0
2023-04-28 11:53:22.159 PDT,,,725568,,644c1622.b1240,2,,2023-04-28 11:53:22 PDT,2/0,0,ERROR,XX000,"cannot synchronize replication slot positions because primary_slot_name is not set",,,,,,,,,"pg_failover_slots worker","pg_failover_slots worker",,0
2023-04-28 11:53:22.162 PDT,,,725006,,644c161c.b100e,6,,2023-04-28 11:53:16 PDT,,0,LOG,00000,"background worker ""pg_failover_slots worker"" (PID 725568) exited with exit code 1",,,,,,,,,"","postmaster",,0

[Feature] Add support for cascading replication

Currently failover slots are only synchronised from the primary to the standby(s), not the other way around. Postgres 16 has added support for cascading replication, where the active slot is actually on the standby (and might be initially created there). It would be nice to add failover slots support for this scenario.

Is there any work done already in this direction?

Missing control file when installed via apt postgresql repo

From a fresh postgresql, installing pg_failover_slots does not install a control file, leading CREATE EXTENSION pg_failover_slots; to fail.

To reproduce:

$ docker run -it -u=0 --entrypoint /bin/bash postgres:15
# apt update
# apt install postgresql-15-pg-failover-slots
# find / -name pg_failover_slots # verify library installed - finds the library
/usr/lib/postgresql/15/lib/bitcode/pg_failover_slots
# find / -name pg_failover_slots.control # verify control file installed - finds no control file

clarify supported PostgreSQL versions

The supported versions of PostgreSQL should be clarified, probably in the documentation. At the moment, <=PG12 does not build. That might okay as a cutoff, as long as it's intentional.

More informations about failover logical replication_slot

Hello to all !
Would it be possible to have more information on how you managed these possible problems:

  • Requested WAL segment pg_wal/XXX has already been removed

  • It can be unsafe to use the logical slot after promote if replicas physical slot didn’t reach the catalog_xmin of the
    logical slot on the old primary

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.