Skip to content

CONCEPT Cited by 1 source

lsn.flush.mode (Debezium)

Definition

lsn.flush.mode is a Debezium Postgres connector configuration property introduced in Debezium 3.4.0.Final (2025-12-16) that controls who is allowed to advance the Postgres logical replication slot's confirmed_flush_lsn — Debezium itself, the pgjdbc keep-alive thread, both, or neither. Zalando contributed it as DBZ-9641 / PR #6881.

The property is a three-value enum that replaces and deprecates the older boolean flush.lsn.source:

Value Debezium flushes pgjdbc keep-alive flushes Use case
manual No No LSN flushing managed externally by the application
connector (default) Yes, after each event No Default — matches Debezium's pre-3.4 post-disable behaviour
connector_and_driver Yes Yes, when connector has no pending LSN Prevents WAL accumulation on low-activity databases where unmonitored WAL activity (CHECKPOINT, VACUUM, pg_switch_wal()) dominates

Why it exists

Before 3.4, Debezium hard-coded the pgjdbc keep-alive flush feature off (withAutomaticFlush(false)) after discovering it conflicted with Debezium's own LSN-management logic and generated user-reported issues — a global disable that foreclosed on Zalando's proven-safe deployment. Zalando had shipped the pgjdbc keep-alive flush upstream in pgjdbc 42.7.0 in 2023 and ran it for nearly two years processing billions of events with zero detected data loss. After Debezium disabled it, "we couldn't upgrade Debezium without losing the fix that kept our production systems stable."

lsn.flush.mode inverts the default discipline: keep pgjdbc flushing off by default, let operators who know their deployment can tolerate it opt in to connector_and_driver.

The connector_and_driver mode in detail

When enabled:

  • Debezium flushes the LSN after processing each logical- replication change event (standard behaviour).
  • When the connector has no pending LSN to flush, the pgjdbc driver's keep-alive thread can flush the server-reported keep-alive LSN — which reflects all WAL activity including unmonitored activity such as CHECKPOINT, VACUUM, or pg_switch_wal() that doesn't produce logical-replication change events.

This specifically targets the runaway WAL growth failure mode: when monitored tables are low-activity but other unmonitored activity on the same server is high, the pgjdbc keep-alive thread advances the slot so WAL can be reclaimed.

The hidden contract: only safe with slot-authoritative position

connector_and_driver creates the structural condition that connector_and_driver mode's pgjdbc keep-alive thread can advance the slot past Debezium's currently-stored offset. On connector restart, the offset store may be behind the replication slot — a state the default Debezium startup logic interprets as data loss.

This is why the second Zalando contribution ( offset.mismatch.strategy) is required to safely use lsn.flush.mode=connector_and_driver against persistent offset stores. The two properties must be set together for production use; the post's explicit prescription is lsn.flush.mode=connector_and_driver paired with offset.mismatch.strategy=trust_greater_lsn for persistent offset stores, or with trust_slot when only the slot is trusted.

Backward compatibility

The deprecated flush.lsn.source boolean auto-maps to the new enum: - trueconnector - falsemanual

Canonical instance of boolean → enum deprecation mapping — preserves existing deployments through the deprecation window without breaking changes.

Seen in

Last updated · 428 distilled / 1,221 read