This article describes how to enable CDC on your PostgreSQL database.

This article guides you through the process of enabling CDC on your PostgreSQL database.

Prerequisites for PostgreSQL

Database configuration

CDC uses logical replication to get change events from the Write-Ahead Log (WAL), so you should ensure this is enabled in advance.

You can check the replication method of your database by running:

SHOW wal_level;

This query should return logical. If it returns any other value, please change the replication method:

  • For self-hosted PostgreSQL:

ALTER SYSTEM SET wal_level = logical;
  • For RDS / Aurora PostgreSQL: set the logical_replication parameter in AWS RDS console to 1.

The database must be restarted for this change to take effect.


In order for Upsolver to read the WAL and the initial state of the database, the CDC data source requires:

  1. A user with replication and select permissions

  2. A PostgreSQL publication for the replicated tables

Creating a CDC user

If you are using an AWS RDS PostgreSQL instance please see the instructions below on how to create a CDC user. If you are using a self-hosted instance, please refer to Debezium's documentation.

Upsolver recommends creating a separate user for the CDC process and granting that user replication and select permissions.

Replication permission can be granted using:

  • For self-hosted PostgreSQL:

  • For RDS / Aurora PostgreSQL:

GRANT rds_replication TO <user>;

SELECT permissions can be granted either by giving permission to the entire schema, or for each table individually:

 GRANT SELECT ON ALL TABLES IN SCHEMA <schema_name> TO <user>; // For all tables
 GRANT SELECT ON <table_name> TO <user>; // For a specific table

Creating a publication

Upsolver requires the publication of replicated tables in order to be able to subscribe to change events. The publication can be either on all tables or on specific tables.

If the database contains tables without primary keys, adding those tables to the publication will cause PostgreSQL to block all updates and deletes for that table. This can be prevented in one of the following ways:

  • Manage the publication tables manually and don't include such tables.

  • Change the REPLICA IDENTITY of that table to FULL or INDEX. More information can be found in the PostgreSQL documentation.

  • Add a primary key to the table.

Creating a publication of all tables is the simplest method and will automatically include all tables created in the future. However, this can lead to issues if tables without primary keys are created without having a REPLICA IDENTITY configured.

A publication of all tables can be created by a superuser using the following command:


Creating a publication on specific tables will not automatically include newly created tables. For instructions on how to create and manage publications for specific tables, see the PostgreSQL documentation.

More information about permissions can be found in the Debezium documentation.

Setting up a Heartbeat Table

The WAL in a PostgreSQL instance is shared among all tables and databases on that instance. When at least one replication slot exists, PostgreSQL will wait until all replication slots confirm that a particular WAL event has been consumed before deleting it. Consequently, a replication slot that doesn't confirm any event for a long time might lead to the WAL growing excessively.

Upsolver can confirm an event only when receiving one. This means that when a data source doesn't contain any frequently changing tables, Upsolver might not get an opportunity to confirm any events, thereby leading to high disk usage (by the WAL).

To prevent excessive growth, heartbeats can be placed in the replication stream so that Upsolver can periodically confirm events. A Heartbeat Table sets up the heartbeats. After Upsolver is set up to use the heartbeat table, heartbeats will be tracked and confirmed by the Upsolver data source.

Follow these steps to create a heartbeat table:

  1. Create a heartbeat table:

CREATE TABLE IF NOT EXISTS <schema_name>.<table_name> 
   (key int primary key, value timestamp)

2. Grant the necessary permissions for Upsolver to use the heartbeat table:

GRANT INSERT, UPDATE, SELECT on table <table_name> to <user>

3. If the publication used in the data source was created for specific tables (not all tables), add the heartbeat table to the publication. See the PostgreSQL documentation.

4. Add the heartbeat table to the data source in the data source creation wizard or in the data source properties.

Known Limitations

  1. PostgreSQL omits unchanged TOASTed values unless they are explicitly part of the table's replica identity. See Handle PostgreSQL TOAST Values page for suggested solutions and workarounds.

  2. Columns with generated values are not included in the PostgreSQL replication log. Generated columns will be replicated during snapshotting but will not be included in streaming changes. Consider reproducing the the generation expression in the target system or in the replication job.

Last updated