0
点赞
收藏
分享

微信扫一扫

RabbitMQ进阶——死信队列

一、发布订阅介绍

发布和订阅使用了pg的逻辑复制的功能,通过发布端创建publication与表绑定,订阅端创建subscription同时会在发布端创建逻辑复制槽实现逻辑复制功能

逻辑复制基于 发布(Publication) 与 订阅(Subscription)模型:

一个 发布者(Publisher) 上可以有多个发布,一个 订阅者(Subscriber) 上可以有多个 订阅 。

一个发布可被多个订阅者订阅,一个订阅只能订阅一个发布者,但可订阅同发布者上的多个不同发布。

逻辑复制的典型用途是:

迁移,跨PostgreSQL大版本,跨操作系统平台进行复制。

CDC,收集数据库(或数据库的一个子集)中的增量变更,在订阅者上为增量变更触发触发器执行定制逻辑。

分拆,将多个数据库集成为一个,或者将一个数据库拆分为多个,进行精细的分拆集成与访问控制。

复制标识:

一个被纳入发布中的表,必须带有复制标识(Replica Identity),只有这样才可以在订阅者一侧定位到需要更新的行,完成UPDATE与DELETE操作的复制。

默认情况下,主键 (Primary Key)是表的复制标识,非空列上的唯一索引 (UNIQUE NOT NULL)也可以用作复制标识。

如果没有任何复制标识,可以显式将复制标识设置为FULL,也就是把整个行当作复制标识

使用FULL模式的复制标识效率很低(因为每一行修改都需要在订阅者上执行全表扫描,很容易把订阅者拖垮),所以这种配置只能是保底方案。

使用FULL模式的复制标识还有一个限制,订阅端的表上的复制身份所包含的列,要么与发布者一致,要么比发布者更少

复制标识的影响:

  • INSERT操作总是可以无视复制标识直接进行(因为插入一条新记录,在订阅者上并不需要定位任何现有记录;而删除和更新则需要通过复制标识 定位到需要操作的记录)。
  • 如果一个没有 复制标识 的表被加入到带有UPDATE和DELETE的发布中,后续的UPDATE和DELETE会导致发布者上报错

显式配置复制标识:

alter table test3 REPLICA IDENTITY full;

create unique index idx_test4 on test4(id);

alter table test4 alter column id set not null;

alter table test4 REPLICA IDENTITY using index idx_test4;

select relname,relreplident from pg_class where relname in('test3','test4');

二、发布和订阅创建

发布端配置:

wal_level=logical

max_replication_slots大于订阅端的数量

max_wal_senders大于max_replication_slots

订阅端配置:

max_logical_replication_workers 逻辑复制进程数,应大于订阅节点的数量,并且给表同步预留一些进程数量

发布端操作:

1、创建复制用户并赋予复制权限

create user repuser password 'repuser' replication;

2、在postgres库中创建表

create table test1(id int primary key,name varchar(10) );

insert into test1 values(1,'a');

3、赋予复制用户select表权限

grant select on table t1 to repuser;

4、创建表test1的发布

create publication pub1 for table test1;

订阅端操作:

1、建发布端同名表

create table test1(id int primary key,name varchar(10) );

2、创建订阅

CREATE SUBSCRIPTION sub1 CONNECTION 'host=192.168.40.112 dbname=postgres port=5432 user=repuser password=repuser' PUBLICATION pub1;

3、查看表test1的数据是否被同步

在发布端执行test1表的insert、delete、update、truncate操作,看订阅端是否能同步

三、新加表同步

发布端:

1、新建表

create table test3 (id int,name varchar(10));

2、设置复制标识

alter table test3 REPLICA IDENTITY full;

3、将表加入发布

ALTER PUBLICATION pub1 ADD TABLE test3;

订阅端执行刷新

ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION ;

在发布端执行test3表的insert、delete、update、truncate操作,看订阅端是否能同步

四、发布订阅的相关视图(要在对应的库下查看)

发布端:

select * from pg_replication_slots; --查看所有复制槽

select * from pg_stat_replication; --查看复制槽的同步状态

select * from pg_publication; --查看所有发布

select * from pg_publication_tables; --查看所有发布对应的表

select usename,a.pubname,c.*,pubinsert,pubupdate,pubdelete,pubtruncate from pg_publication a,pg_user b,pg_publication_tables c where a.pubowner=b.usesysid and c.pubname=a.pubname;

订阅端:

select * from pg_subscription; --查看所有订阅

select srrelid::regclass from pg_subscription_rel; --查看订阅的所有表

select usename,datname,subname,srrelid::regclass,srsublsn,subconninfo from pg_subscription a,pg_user b,pg_subscription_rel c ,pg_database d where a.oid=c.srsubid and a.subowner=b.usesysid and a.subdbid=d.oid;

举报

相关推荐

0 条评论