背景
我们需要在Postgres开启CDC功能,但是standby server上不能够开始logical replication,需要等到PG 16。目前在PG 14上,我们只能够在主库上开启logical replication,这样才可以实现CDC。
准备工作
需要两台数据库。我直接用Postgres App开启了两个instance,Primary端口是5414,Slave是5424。
主数据库创建表和数据
CREATE TABLE table_with_pk (a SERIAL, b VARCHAR(30), c TIMESTAMP NOT NULL, PRIMARY KEY(a, c));
BEGIN;
INSERT INTO table_with_pk (b, c) VALUES('Backup and Restore', now());
INSERT INTO table_with_pk (b, c) VALUES('Tuning', now());
INSERT INTO table_with_pk (b, c) VALUES('Replication', now());
UPDATE table_with_pk SET b = 'Update' WHERE 1 = 1;
DELETE FROM table_with_pk WHERE a < 3;
COMMIT;
从库创建空表
CREATE TABLE table_with_pk (a SERIAL, b VARCHAR(30), c TIMESTAMP NOT NULL, PRIMARY KEY(a, c));
主库开启插件并创建Node
CREATE EXTENSION pglogical;
SELECT pglogical.create_node(
node_name := 'provider',
dsn := 'host=127.0.0.1 port=5414 dbname=pzhong'
);
SELECT pglogical.replication_set_add_table('default', 'public.table_with_pk');
从库上开启插件并订阅
CREATE EXTENSION pglogical;
SELECT pglogical.create_node(
node_name := 'subscriber',
dsn := 'host=127.0.0.1 port=5424 dbname=pzhong'
);
SELECT pglogical.create_subscription(
subscription_name := 'subscription',
provider_dsn := 'host=127.0.0.1 port=5414 dbname=pzhong'
);
从库上查看replication状态
select pglogical.show_subscription_status();
主库上查看replication status
SELECT * FROM pg_replication_slots;
清理从库
select pglogical.alter_subscription_disable('subscription');
select pglogical.drop_subscription('subscription');
DROP EXTENSION pglogical;
清理主库
DROP EXTENSION pglogical;
从库无法创建subscription - Could not open relation with OID
需要断开连接,再重新连一次数据库。
从库无法replication
首先查看replication 状态是否是down了。如果down了,那可能是那里有问题了。比如我这里是从库上面表已经有数据了,产生了冲突。我重新drop了表,再重新创建表,再enable subscription就好了。
select pglogical.alter_subscription_enable('subscription');
主库修改表结构
修改之后会导致replication down,需要从库也apply相同的DDL,再enable subscription。
主库在订阅暂停后插入的新数据
因为replication slot会导致WAL保留slave未消费的日志,所以不用担心数据丢失,但是要担心主库磁盘爆满。我们在从库上disable subscription之后,主库上会保留后续的DML操作,直到我们再次enable subscription。
主库有大量数据写入
这些数据会写入wal log,直到slave消费掉这些日志之后,过一会儿才会重新下降到默认的wal_size(1GB)。