发布订阅基于逻辑复制实现,其中有一个或者更多订阅者订阅一个发布者节点上的一个或者更多发布。订阅者从它们所订阅的发布拉取数据。实现集群间的数据实时同步。
发布订阅的典型使用场景是:
发布者上的更改会被实时发送给订阅者。订阅者以与发布者相同的顺序应用那些数据,这样在一个订阅中能够保证发布的事务一致性。这种数据复制的方法有时候也被称为事务性复制。
订阅者数据库的行为与任何其他MogDB实例相同,并且可以被用作其他数据库的发布者,只需要定义它自己的发布。当订阅者被应用当作只读时,单一的订阅中不会有冲突。在另一方面,如果应用或者对相同表集合的订阅者执行了其他的写动作,冲突可能会发生。
参考官方文档
发布订阅实际上是对OutputPluginCallbacks 众多回调函数的实现。其默认实现是pgoutput.cpp 。
/*
* Output plugin callbacks
*/
typedef struct OutputPluginCallbacks {
LogicalDecodeStartupCB startup_cb;
LogicalDecodeBeginCB begin_cb;
LogicalDecodeChangeCB change_cb;
LogicalDecodeCommitCB commit_cb;
LogicalDecodeAbortCB abort_cb;
LogicalDecodePrepareCB prepare_cb;
LogicalDecodeShutdownCB shutdown_cb;
LogicalDecodeFilterByOriginCB filter_by_origin_cb;
} OutputPluginCallbacks;
回调消息处理流程
tableam_tuple_insert)tableam_tuple_update)解析消息体,读取rel_oid,newtup信息
open relation并初始化executor state、tuple slot
是否能在relation中找到oldtup?如果不能找到,无需进一步处理
执行DELETE(tableam_tuple_delete)
frank@LAPTOP-4OF1323N:/$ docker run --name mogdb --privileged=true -d -e GS_PASSWORD=Enmo@123 -v /mogdb:/var/lib/mogdb -p 15432:5432 -p 15433:5433 swr.cn-north-4.myhuaweicloud.com/mogdb/mogdb:3.0.0
a925573d1d38a472b7749e22aa3bc99974a82cae6f91914fe37067701871da65
frank@LAPTOP-4OF1323N:/$ docker run --name mogdb3 --privileged=true -d -e GS_PASSWORD=Enmo@123 -v /mogdb3:/var/lib/mogdb -p 35432:5432 -p 35433:5433 swr.cn-north-4.myhuaweicloud.com/mogdb/mogdb:3.0.0
0e75166b099ac2fed0a466c7e26f2b1620b02831c09389d5348768ff1184b74d

设置参数postgres.conf
wal_level = logical
max_replication_slots = 8 ##大于订阅数+物理复制槽数量+少量剩余用作临时快照复制
max_wal_senders = 10 #大于max_replication_slots+物理复制的备机数量
设置白名单pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication omm trust
#host replication omm 127.0.0.1/32 trust
#host replication omm ::1/128 trust
host all all 0.0.0.0/0 md5
host replication all 0.0.0.0/0 md5
创建角色/用户,这里要有SYSADMIN/OPRADMIN,REPLICATION权限,
MogDB=#CREATE ROLE pub_sub_user WITH SYSADMIN REPLICATION LOGIN PASSWORD 'pub_sub@123';
NOTICE: The encrypted password contains MD5 ciphertext, which is not secure.
CREATE ROLE
MogDB=#
创建要发布的测试表
MogDB=#create table pub_sub(i serial, name varchar);
NOTICE: CREATE TABLE will create implicit sequence "pub_sub_i_seq" for serial column "pub_sub.i"
CREATE TABLE
赋权
MogDB=#CREATE PUBLICATION user_pub FOR TABLE pub_sub;
CREATE PUBLICATION
MogDB=#GRANT SELECT ON TABLE pub_sub TO pub_sub_user;
GRANT
查看发布设置,检验发布是否成功


创建于pub端相同结构的测试表
MogDB=#create table pub_sub(i serial, name varchar);
NOTICE: CREATE TABLE will create implicit sequence "pub_sub_i_seq" for serial column "pub_sub.i"
CREATE TABLE
创建订阅
MogDB=#CREATE SUBSCRIPTION user_sub CONNECTION 'dbname=postgres host=172.17.0.1 port=15433 user=pub_sub_user password=pub_sub@123' PUBLICATION user_pub;
NOTICE: created replication slot "user_sub" on publisher
CREATE SUBSCRIPTION
查看订阅属性



Q1:
MogDB=#CREATE SUBSCRIPTION user_sub CONNECTION 'dbname=postgres host=172.17.0.1 port=15433 user=pub_sub_user password=pub_sub@123' PUBLICATION user_pub;
ERROR: No key file subscription.key.cipher
HINT: Please create subscription.key.cipher file with gs_guc and gs_ssh, such as :gs_ssh -c "gs_guc generate -S XXX -D $GAUSSHOME/bin -o subscription"
A1:sub端
omm@4c1187b588b6:~$ gs_guc generate -S pub_sub@123 -D $GAUSSHOME/bin -o subscription
The gs_guc run with the following arguments: [gs_guc -S ******** -D /usr/local/mogdb/bin -o subscription generate ].
gs_guc generate -S ***
omm@4c1187b588b6:~$
Q2:
MogDB=#CREATE SUBSCRIPTION user_login_sub CONNECTION 'dbname=postgres host=172.17.0.1 port=15432 user=pub_sub_user password=pub_sub@123' PUBLICATION user_pub;
WARNING: apply worker could not connect to the remote server
ERROR: could not connect to the publisher
A2:
1 端口未映射到宿主机(docker部署需要注意)。
2 查看信息错误信息
select lwtid from dbe_perf.thread_wait_status w , pg_stat_activity b
where w.sessionid = b.sessionid and query_start > sysdate - 1/86000 AND b.application_name = 'gsql';
strace -s 8192 -o rep.trc -p <lwtid>



用于连接发布端且具有系统管理员权限(SYSADMIN)或者运维管理员权限(OPRADMIN)的用户名和密码。password需要加密,创建订阅前需要在订阅端执行gs_guc generate -S xxxxxx -D $GAUSSHOME/bin -o subscription。