All Products
Search
Document Center

ApsaraDB RDS:Use a replication slot to set up change tracking

Last Updated:Mar 30, 2026

ApsaraDB RDS for PostgreSQL supports Change Data Capture (CDC) through logical replication slots — PostgreSQL's native mechanism for streaming row-level changes. Use this guide to configure CDC on an RDS for PostgreSQL instance: set the required parameters, create a replication slot, and read and consume change data end to end.

Prerequisites

Before you begin, ensure that you have:

Limitations

  • CDC is only supported on the primary instance. Read-only instances are not supported.

  • ApsaraDB RDS for PostgreSQL supports Logical Replication Slot Failover, so primary/secondary switchovers do not affect CDC.

Risks before you start

A replication slot does not track its consumers. If a downstream client stops consuming or reports consumption abnormally, Write-Ahead Log (WAL) files accumulate without bound. Address the following risks before enabling CDC:

  • Disk exhaustion and instance lock: WAL files accumulate if consumption stops. Left unaddressed, this exhausts disk space and locks the instance to read-only mode.

  • XID wraparound: If a downstream client does not report consumption progress in real time, the instance retains multiple row versions. This can cause transaction ID (XID) wraparound, also locking the instance to read-only mode. Sample error log:

    HINT: Close open transactions soon to avoid wraparound problems. You might also need to commit or roll back old prepared transactions, or drop stale replication slots.
    WARNING: oldest xmin is far in the past.
  • Instance restart on parameter change: Enabling CDC requires setting wal_level to logical. This change triggers an instance restart. Make this change during off-peak hours.

To mitigate these risks:

Enable the CDC feature

The following steps use these example values. Replace them with your own.

Placeholder Example value Description
<instance-endpoint> pgm-*****.pgsql.singapore.rds.aliyuncs.com Endpoint of your RDS instance
testdb Test database name
db_admin Privileged account for administration
cdc_user Standard account for consuming CDC data
cdc_replication_slot Replication slot name

Step 1: Create a test database

  1. Go to the Instances page. In the top navigation bar, select the region where your RDS instance resides. Click the instance ID.

  2. In the left-side navigation pane, click Databases.

  3. Click Create Database.

    Note

    This example creates a database named testdb. For instructions, see Create a database.

    创建测试数据库

Step 2: Create accounts and configure permissions

  1. In the left-side navigation pane, click Accounts.

  2. Click Create Account to create two accounts: 创建用户

    • A privileged account named db_admin for administration

    • A standard account named cdc_user for capturing change data

    Note

    The account names in this example are for reference only. For instructions, see Create an account.

  3. Connect to the instance as db_admin:

    Note

    To find your instance endpoint, see View and change endpoints and port numbers.

    psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb
  4. Grant the replication role to cdc_user:

    ALTER USER cdc_user WITH REPLICATION;

    Verify the assignment:

    SELECT rolreplication FROM pg_roles WHERE rolname='cdc_user';

    Expected output:

    rolreplication
    ----------------
     t
    (1 row)
  5. Grant SELECT permissions on all tables to cdc_user:

    GRANT SELECT ON ALL TABLES IN SCHEMA PUBLIC to cdc_user;

Step 3: Set wal_level to logical

The wal_level parameter controls how much information is written to WAL logs. The default value is replica. CDC requires the logical value, which adds the information needed for logical decoding.

Value Description
minimal Records only the data required to recover from a crash or immediate shutdown. Does not support WAL-based restore using base backups or WAL logs.
replica Supports WAL archiving and replication, including read-only queries on a standby server.
logical Adds the information needed for logical decoding, on top of what replica provides. Required for CDC.

To verify the current value:

SELECT name, setting, short_desc, source
FROM pg_settings
WHERE name = 'wal_level';

Expected output:

name      | setting |                          short_desc                          |       source
----------+---------+---------------------------------------------------------------+--------------------
 wal_level | replica | Sets the level of information written to the WAL.            | configuration file
(1 row)

To change wal_level to logical:

  1. Go to the Instances page and click your instance ID.

  2. In the left-side navigation pane, click Parameters.

  3. Set wal_level to logical and submit the change.

Important

The instance restarts after you submit the change. Make this change during off-peak hours to minimize impact. For instructions, see Modify the parameters of an ApsaraDB RDS for PostgreSQL instance.

Step 4: Create a logical replication slot

Wait for the instance to restart and return to the Running state before proceeding.

  1. Connect to the instance as db_admin:

    psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb
  2. Create a logical replication slot named cdc_replication_slot using the test_decoding output plugin:

    Note

    test_decoding is an output plugin provided by open source PostgreSQL. cdc_replication_slot is an example name — use any name that fits your requirements.

    SELECT pg_create_logical_replication_slot('cdc_replication_slot', 'test_decoding');

    Expected output:

    pg_create_logical_replication_slot
    ------------------------------------
     (cdc_replication_slot,1/14003428)
    (1 row)
  3. Verify the replication slot was created:

    SELECT * FROM pg_replication_slots;

    Expected output:

    slot_name            |    plugin     | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase
    ---------------------+---------------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+-----------
     cdc_replication_slot | test_decoding | logical   |  18822 | testdb   | f         | f      |            |      |        22356 | 1/140033F0  | 1/14003428          | reserved   |               | f
    (1 row)

Step 5: Create test data

Run the following statements to create a test table and insert sample data:

CREATE TABLE public.tb_test(
    id int NOT NULL PRIMARY KEY
);

ALTER TABLE public.tb_test ADD name varchar(1) NULL;

INSERT INTO public.tb_test SELECT 1, 'A';

Step 6: Read change data from the replication slot

  1. Connect to the instance as cdc_user:

    psql -h <instance-endpoint> -p 5432 -U cdc_user -d testdb
  2. Read change data from the replication slot without consuming it:

    SELECT * FROM pg_logical_slot_peek_changes('cdc_replication_slot', null, null);

    Expected output:

    lsn        |  xid  |                                  data
    -----------+-------+------------------------------------------------------------------------
     1/14003D90 | 22376 | BEGIN 22376
     1/1401DDE8 | 22376 | COMMIT 22376
     1/1401DDE8 | 22377 | BEGIN 22377
     1/1401E100 | 22377 | COMMIT 22377
     1/1401E2A8 | 22382 | BEGIN 22382
     1/1401E2A8 | 22382 | table public.tb_test: INSERT: id[integer]:1 name[character varying]:'A'
     1/1401E3C0 | 22382 | COMMIT 22382
    (7 rows)

Step 7: Consume change data using pg_recvlogical

pg_recvlogical is the native logical decoding tool included with PostgreSQL. It reads from a replication slot and advances the consumption position so that consumed WAL data can be cleared.

  1. Run \q to close the current database connection.

  2. Run the following command to start consuming change data:

    Note

    Run pg_recvlogical as the postgres user (su - postgres). If you see -bash: pg_recvlogical: command not found, see the FAQ.

    pg_recvlogical -h <instance-endpoint> -U <privileged-account> -d <database> \
      --create-slot --if-not-exists --slot=cdc_replication_slot \
      --plugin=test_decoding --start -f -

    Example:

    pg_recvlogical -h pgm-*****.pgsql.singapore.rds.aliyuncs.com -U db_admin -d testdb \
      --create-slot --if-not-exists --slot=cdc_replication_slot \
      --plugin=test_decoding --start -f -

    Expected output:

    BEGIN 22376
    COMMIT 22376
    BEGIN 22377
    COMMIT 22377
    BEGIN 22382
    table public.tb_test: INSERT: id[integer]:1 name[character varying]:'A'
    COMMIT 22382

Disable the CDC feature

Replication slots do not track their consumers. If consumption stops, WAL logs accumulate and can exhaust disk space, locking the instance to read-only mode. Delete inactive replication slots to let AliPG clear WAL logs automatically.

Delete inactive replication slots using any of the following methods:

To delete a replication slot using SQL:

  1. Connect to the instance as db_admin:

    psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb
  2. List inactive replication slots:

    SELECT slot_name, slot_type, database, active, safe_wal_size
    FROM pg_replication_slots
    WHERE active = 'f';

    Expected output:

    slot_name            | slot_type | database | active | safe_wal_size
    ---------------------+-----------+----------+--------+---------------
     cdc_replication_slot | logical   | testdb   | f      |
    (1 row)
  3. Drop the replication slot:

    SELECT pg_drop_replication_slot('cdc_replication_slot');

FAQ

What do I do if `pg_recvlogical: command not found` is displayed?

pg_recvlogical is a native logical decoding tool for PostgreSQL. This tool uses the default test_decoding extension, which is stored in the contrib/test_decoding directory of the PostgreSQL source code package. The tool must be run as the postgres user (su - postgres). If the command is not found, compile and install PostgreSQL from source code — the tool is in the /bin directory of the installation path. See Installation from source code.

WAL files still occupy disk space after I delete replication slots. What do I do?

Set wal_keep_segments to its default value of 128 to reduce the number of retained WAL files. See Modify the parameters of an ApsaraDB RDS for PostgreSQL instance.

What's next