Cookbook recipe

Logical Replication: Publication Missing Column Changes

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Scenario A developer adds a GENERATED ALWAYS AS (price * quantity) STORED column to the order_items table on the publisher. The subscriber schema is updated manually to add the column. Two days later, the analytics team…

Investigation Path

Scenario

A developer adds a GENERATED ALWAYS AS (price * quantity) STORED column to the order_items table on the publisher. The subscriber schema is updated manually to add the column. Two days later, the analytics team reports that the total_price values on the subscriber don’t match the publisher — they’re recomputing locally from stale data. No replication errors were logged.

How to Identify

Conditions:

  • Subscriber data differs from publisher with no error messages
  • GENERATED ALWAYS AS (STORED) columns on subscriber recomputing from old base values
  • ALTER TABLE ADD COLUMN applied to publisher but not refreshed on subscription
  • pg_publication_tables shows column-level filtering in use

Analysis Steps

-- On PUBLISHER: check what columns are being published
SELECT pubname, schemaname, tablename, attnames
FROM   pg_publication_tables
WHERE  pubname = 'my_publication';
-- attnames = NULL means all columns; or lists specific columns

-- Check if GENERATED columns exist
SELECT attname, attgenerated
FROM   pg_attribute
WHERE  attrelid = 'order_items'::regclass
  AND  attnum > 0
  AND  NOT attisdropped;
-- attgenerated = 's' means STORED generated column

-- On SUBSCRIBER: check schema matches publisher
SELECT attname, atttypid::regtype
FROM   pg_attribute
WHERE  attrelid = 'order_items'::regclass
  AND  attnum > 0
  AND  NOT attisdropped;

Pitfalls

  • GENERATED ALWAYS AS (expr) STORED columns are not replicated — they are regenerated locally on the subscriber using the subscriber’s copy of the expression. If the base columns have stale values, the generated column will be wrong.
  • Logical replication does not replicate DDL — every ALTER TABLE must be manually applied to the subscriber in the correct order (subscriber first, then publisher for ADD COLUMN; publisher first, then subscriber for DROP COLUMN).
  • Schema drift between publisher and subscriber is silent — no error, data is just wrong.
  • REFRESH PUBLICATION must be run on the subscriber after any schema change affects which tables are published.

Resolution Approach

Apply DDL changes to the subscriber before the publisher when adding columns (prevents gap). After schema changes, run ALTER SUBSCRIPTION ... REFRESH PUBLICATION. For generated columns, ensure base column values are correctly replicated first.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Mitigation Actions
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes