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:
-
An ApsaraDB RDS for PostgreSQL instance. See Create an ApsaraDB RDS for PostgreSQL instance
-
An IP address whitelist configured to allow connections from your client. See Configure an IP address whitelist
-
psql installed on your client. See PostgreSQL documentation: Installation from source code
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_leveltological. This change triggers an instance restart. Make this change during off-peak hours.
To mitigate these risks:
-
Configure downstream clients to report consumption progress in real time.
-
Monitor WAL log size and storage usage regularly. See View enhanced monitoring and Manage alerts.
-
Delete inactive replication slots promptly to allow AliPG to clear WAL logs automatically. See Disable the CDC feature.
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
-
Go to the Instances page. In the top navigation bar, select the region where your RDS instance resides. Click the instance ID.
-
In the left-side navigation pane, click Databases.
-
Click Create Database.
NoteThis example creates a database named testdb. For instructions, see Create a database.

Step 2: Create accounts and configure permissions
-
In the left-side navigation pane, click Accounts.
-
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
NoteThe account names in this example are for reference only. For instructions, see Create an account.
-
-
Connect to the instance as db_admin:
NoteTo find your instance endpoint, see View and change endpoints and port numbers.
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb -
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) -
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:
-
Go to the Instances page and click your instance ID.
-
In the left-side navigation pane, click Parameters.
-
Set wal_level to logical and submit the change.
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.
-
Connect to the instance as db_admin:
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb -
Create a logical replication slot named
cdc_replication_slotusing thetest_decodingoutput plugin:Notetest_decodingis an output plugin provided by open source PostgreSQL.cdc_replication_slotis 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) -
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
-
Connect to the instance as cdc_user:
psql -h <instance-endpoint> -p 5432 -U cdc_user -d testdb -
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.
-
Run
\qto close the current database connection. -
Run the following command to start consuming change data:
NoteRun
pg_recvlogicalas thepostgresuser (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:
-
ApsaraDB RDS console: See Use the WAL log management feature.
-
API operations: See DeleteSlot.
-
SQL statements: Follow the steps below.
To delete a replication slot using SQL:
-
Connect to the instance as db_admin:
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb -
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) -
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
-
Logical Replication Slot Failover — keep CDC working across primary/secondary switchovers
-
View enhanced monitoring — track WAL log size and storage usage
-
Manage alerts — set up alerts for disk usage and instance lock events