Webhook icon
Schedule icon
If icon
Fail icon
Query icon
SlackIncomingWebhook icon
Pause icon
Log icon

Recover a Stalled PostgreSQL Logical Subscriber Safely

Detect a stalled PostgreSQL logical subscriber, inspect errors, and gate transaction skipping behind approval and a fresh state check.

Categories
DataInfrastructure

A conflicting row can stop a PostgreSQL logical subscriber while the publisher keeps writing. The subscriber's apply-error counter rises, but the confirmed position does not. This blueprint samples both signals, reports a new stall once, and presents the operator with a choice. It runs against a local PostgreSQL 16 subscriber by default after secrets are set.

How it works

  1. replication_alert (Webhook) starts diagnosis immediately; the disabled minute_backstop (Schedule) can be enabled as a sweep.
  2. check_subscription reads pg_subscription, pg_stat_subscription_stats, pg_stat_subscription, and the durable pg_replication_origin_status.remote_lsn. sample remembers the first repeated error while the applied LSN stays fixed, even if the worker crashes and disappears from the live statistics view.
  3. classify changes one ledger row from ok to stalled after stale_seconds, so repeated runs do not repeat the Slack alert.
  4. operator_decision (Pause) asks whether to repair the conflict manually or skip the whole transaction. The operator must copy the transaction finish LSN from the subscriber log and explain the data-loss decision.
  5. prepare_skip checks current subscription identity, enablement, two-phase mode, existing skip setting and unchanged apply position. Only then does set_skip_lsn run a PostgreSQL-quoted ALTER SUBSCRIPTION ... SKIP.

Error handling

  • Invalid subscription names and unsupported PostgreSQL versions fail before the ledger changes. Database calls retry with backoff; flow failures alert with the task and cause.
  • A denied, malformed, stale or expired approval never runs the skip. No automated conflicting-row deletion is offered because the correct repair depends on application semantics.
  • The accepted command is reported as a setting, not proof of recovered replication. PostgreSQL may clear subskiplsn after it has skipped the transaction. Operators must verify the apply LSN and reconcile the skipped transaction's rows.

What this blueprint teaches about Kestra

A webhook and optional schedule share one diagnosis. A database ledger deduplicates alerts across executions, while a Pause and a second read guard a destructive SQL statement after a potentially long human delay.

Prerequisites

  • PostgreSQL 16+ subscriber with a logical subscription. The Kestra database role must read subscription catalogs and own the subscription for an approved skip. PostgreSQL 16 is used in the quick start.
  • An incoming Slack webhook and a Kestra worker that can connect to the subscriber.

Secrets

  • POSTGRES_URL: JDBC URL of the subscriber database, not the publisher.
  • POSTGRES_USERNAME, POSTGRES_PASSWORD: subscriber role credentials.
  • SLACK_WEBHOOK_URL: incoming webhook for alerts and approved actions.

Inputs

  • subscription_name (STRING, demo_sub): subscription to monitor.
  • stale_seconds (INT, 60): minimum time of unchanged position with apply errors.
  • force_review (BOOL, false): request another decision for an existing stall.
  • kestra_url (STRING, http://localhost:8080): link in the alert.

Outputs

  • observation (JSON): raw subscription state, including error counts and confirmed LSN.
  • classification (JSON): old/new level and whether it changed. Outputs on failed runs may be empty.

Quick start

  1. Create publication and subscription as in the PostgreSQL logical replication documentation. Connect POSTGRES_URL to the subscriber.
  2. Set all four secrets, change the webhook key, then run twice with at least stale_seconds between samples.
  3. On a stalled alert, inspect the subscriber log's transaction ... finished at LSN context. Repair the conflicting row if possible. If the whole transaction may be discarded, resume with SKIP_TRANSACTION, the finish LSN and a reason.
  4. After a skip, compare publisher and subscriber rows for that transaction, then run again to confirm apply progress.

Plugins used

See How

New to Kestra?

Use blueprints to kickstart your first workflows.