Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hazards of logical decoding in PostgreSQL

Hazards of logical decoding in PostgreSQL

Avatar for Polina Bungina

Polina Bungina

October 24, 2025
Tweet

More Decks by Polina Bungina

Other Decks in Technology

Transcript

  1. Agenda 1. Intro a. CDC, approaches for PostgreSQL 2. Logical

    decoding - concepts, hazards and examples a. Decoding process b. Logical replication slot c. Replication protocol 2
  2. • Set of design patterns used to track when and

    what changes occur in data then notify other systems and services that must respond to those changes. • Maintain consistency across all systems that rely on data Intro CDC - Change Data Capture 3
  3. Process of extracting all persistent changes to a database tables

    into a coherent, easy to understand format which can be interpreted without detailed knowledge of the database’s internal state. Intro Logical decoding 5
  4. • The technology is complex and can be dangerous •

    Users need to understand the implementation details Intro IMHO 6
  5. 8 Logical replication slot • Slot – state of a

    consumer • LSN (log sequence number) and xmin positions define all the resources required • Resource is not removed if needed by at least one consumer • WAL • System catalog rows • Crash-safe - state is persisted to disk • independently of the connection using it
  6. • do not produce writes for my publication ➜ single

    WAL for the whole cluster, not per-database/publication • do not produce write activity in the db ➜ scheduled vacuum/reindex/… ? ➜ autovacuum ➜ WAL segment switches (archive_timeout) on any database activity Segment file size is always the same (16MB by default) Logical replication slot – examples But wait, I 13
  7. • Failing/not performant consumer => slot is moved slower than

    WAL is generated => WAL size grows • Make use of publications (filtering): • FOR TABLE / FOR TABLES IN SCHEMA • with (publish = 'insert, update, delete, truncate') ➜ unrelated events are not sent to the consumer Logical replication slot – examples Consumer performance 14
  8. • [PG17+] • sync_replication_slots GUC (per standby) • pg_create_logical_replication_slot(name, plugin,

    .., failover) CREATE_REPLICATION_SLOT slot_name ( FAILOVER[, ...] ) ] • synchronized_standby_slots GUC • slot on standby might be not ready/invalidated • < PG17 • Patroni logical slots failover (pg_replication_slot_advance()) • pg_failover_slots extension • File system replication Logical replication slot Failover 15
  9. • Single WAL for the whole cluster, not per-database/table •

    Decoded transactions are sent on commit • [PG14+] streaming of in-progress transactions • Requires client-side implementation Decoding process 17
  10. 15:45 ~/pgdata/pgroot/data$ du -sh pg_replslot/* 70GB pg_replslot/my_slot 15:53 ~/pgdata/pgroot/data$ du

    -sh pg_replslot/* 152GB pg_replslot/my_slot 16:03 ~/pgdata/pgroot/data$ du -sh pg_replslot/* 185GB pg_replslot/my_slot 16:09 ~/pgdata/pgroot/data$ du -sh pg_replslot/* 8.0K pg_replslot/my_slot 25 Decoding process – example 12:19 - start pg_repack 13:20 - copy to temp table finished 13:48 - pg_repack cancelled 16:08 - delete replication slot
  11. ➜ Slot is not advanced unless there is a write

    produced for the respective publication ➜ Problem of endless shutdown • a clean shutdown == all changes are received by consumers • Imporved in pgjdbc v42.7.0 Replication protocol – example 32
  12. • pgjdbc is used by Debezium • Improved in pgjdbc

    v42.7.0, is disabled in Debezium 3.2.0 • heartbeat.action.query ¯\_(ツ)_/¯ 33 Replication protocol – example
  13. Conclusion • Use cautiously! Beware of the hazards • Monitor:

    • Slot is active and advancing • Free disk space • Delete unused slots • Use the proper protocol implementation • Know your workload, evaluate other approaches 34
  14. Alternative: pgq + No maintenance overhead + Minimal bloat +

    Equal to logical decoding (e.g., outbox table) - Not modern, not fancy - No good documentation - Might stop working one day 38