[FREE] pglogical slots don't survive a failover
[FREE] pglogical slots don't survive a failover
I looked at a failover that went cleanly. Then I rebuilt it in a lab to see what the new primary was missing.
๐ Welcome to The Sev-1 Database.
Real PostgreSQL incidents, engine internals, and the production runbooks I lab-test before they go live. That's what I write about here.
Free subscribers get lab-tested scenarios like this one and the database engineering challenges.
Premium members ($5/month) get the full SQL diagnostic packs, step-by-step playbooks, and the queries I actually run during a Sev-1.
๐ New platform: thesev1database.com. PostgreSQL errors, runbooks and engine lessons.
Useful? Subscribe, or send it to one engineer who runs logical replication in production:
I once looked at a failover that went cleanly. The standby was promoted, the application reconnected, and writes resumed.
What bothered me came later. A logical subscriber had stopped receiving changes, and the new primary had no replication slot for it.
Nothing had been broken. The failover had done exactly what a failover does. I wanted to know what a new primary actually has, and what it does not.
So I rebuilt it in a lab.
My lab
PostgreSQL 17.11, pglogical 2.4.8, pg_failover_slots 1.2.1, all local.
One provider with a physical standby, plus one pglogical subscriber.
I synced 1,000 rows to my subscriber, paused apply to model a lagging subscriber, then wrote rows 1001-1100 on my provider.
For failover, I stopped my provider hard and promoted my standby.
Case 1: plain physical standby
My new primary had 0 replication slots.
My subscriber logged connection refused against the old node. Nothing recreated a slot.
After I wrote new rows on my new primary, my subscriber was missing 200 rows (1001-1200).
Recreating my subscription without a data sync left that gap in place. Only a table resync brought me back to full row count, with matching checksums.
Why: logical slots live only on a node that created them. Physical streaming replicates data, not slots.
Case 2: same failover with pg_failover_slots
I installed the extension on both nodes and named my physical slot in standby_slot_names. After promotion, my logical slot was already on my new primary, with restart and confirmed-flush positions synced. I only had to repoint my subscriber. 0 rows missing, checksums equal.
Control: native logical replication on PostgreSQL 17
With failover=true, sync_replication_slots=on and synchronized_standby_slots set, my slot showed up on my standby (failover = t, synced = t) and I lost nothing. This does not cover pglogical 2.4.8. It creates its slot with failover = f, so built-in slot sync skips it.
What went wrong on my way there
PostgreSQL 17.11 rejected my output plugin with
library "pglogical_output" may not be used as an output plugin. A newoutput_plugin_librariessetting has to list it. I would check this before any minor upgrade.pg_failover_slots synced nothing at first. Default
worker_nap_timeis 60 seconds, longer than my test window.My sync got stuck with
waiting for remote slot ... catalog xmin. An idle or disabled slot on a provider cannot be synced, so a slot has to be actively advancing.
What I would check before an outage
Is my slot on my standby right now? I would look at
pg_replication_slotsthere.Do
failoverandsyncedsay what I think they say for every slot?Is my slot active and advancing on my provider, or idle?
After any manual rebuild, I would plan a table resync and compare row counts and checksums.
Limits of my lab: I modelled lag by pausing apply. I did not test WAL on a dead primary that never reached an asynchronous standby. That is a separate loss.
๐ The Sev-1 Database is now a platform
The newsletter is where I write about incidents. thesev1database.com is where the fixes live. Mid-incident, you open one page instead of digging through your inbox.
Free to browse, with no card and no signup:
Errors (102): the cause, the fix and the captured output on every error page.
Runbooks (105): the symptom and the scenario on every page โ 10 are free end to end.
Lessons (37): the outline and the sources โ 5 are free end to end.
Glossary (107 terms) and GUC reference (36): everything.
Pro unlocks:
Runbooks: the exact SQL in order, with the verify step (on the other 95).
Lessons: the full lesson, the queries and the lab transcript.
Errors: a deeper lab verification that confirms the fix held (on 87 of 102).
Passes are one-time (7-Day Pass is $12), nothing auto-renews, and every pass has a 14-day money-back guarantee.
For this post: the free pages below cover the failover and slot basics. The lesson is Pro.
Runbook: Measure and fence a Patroni failover (free)
Glossary: Failover slot (free)
Glossary: Slot synchronization (free)
Lesson: Replication slots (Pro)
Open the replication slots lesson
A question for you
Before a failover, do you check that your logical slots exist on the standby, or do you find out after? Tell me in the comments.
Haider
๐ Upgrade to Premium ($5/month). Premium subscribers get the full SQL diagnostic packs, step-by-step playbooks, and the queries I actually run during a Sev-1.
Enjoyed reading? Restack, share with your audience.
The Sev-1 Database is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.
ยฉ 2026 Haider Z
548 Market Street PMB 72296, San Francisco, CA 94104