MogDB3.0.0新特性——發布訂閱
概述
特性簡介
發布訂閱基于邏輯復制實現,其中有一個或者更多訂閱者訂閱一個發布者節點上的一個或者更多發布。訂閱者從它們所訂閱的發布拉取數據。實現集群間的數據實時同步。
客戶價值
發布訂閱的典型使用場景是:
- 在一個數據庫或者一個數據庫的子集中發生更改時,把增量的改變發送給訂閱者。
- 在更改到達訂閱者時引發觸發器。
- 把多個數據庫聯合到單一數據庫中(例如用于分析目的)。
特性描述
發布者上的更改會被實時發送給訂閱者。訂閱者以與發布者相同的順序應用那些數據,這樣在一個訂閱中能夠保證發布的事務一致性。這種數據復制的方法有時候也被稱為事務性復制。
訂閱者數據庫的行為與任何其他MogDB實例相同,并且可以被用作其他數據庫的發布者,只需要定義它自己的發布。當訂閱者被應用當作只讀時,單一的訂閱中不會有沖突。在另一方面,如果應用或者對相同表集合的訂閱者執行了其他的寫動作,沖突可能會發生。
參考官方文檔
流程
- 發布端配置相關參數,創建發布(wal_level = logical)
- 訂閱端建表,創建訂閱(需要指定發布端的IP,PORT,用戶名,密碼,發布名稱)
- 訂閱端發送鏈接請求,建立鏈接(建立類似主備的鏈接)
- 訂閱端向發布端發送命令,創建復制槽(復制槽的作用是記錄wal日志解析位置)
- 創建訂閱的事務提交,launcher線程被喚醒,發現有新的訂閱產生,啟動apply線程
- apply線程通過copy命令復制基礎數據;基礎數據復制完成后,開啟流復制同步增量數據,同步格式為二進制格式。
- 對于增量數據:訂閱端將二進制格式的數據組裝成tuple直接調用存儲層heap接口,對表進行IUD操作
原理
發布訂閱實際上是對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;
回調消息處理流程
- ‘B’
- 讀取事務信息,事務信息包括結束LSN位置、事務提交時間、事務id
- 記錄最新LSN位置
- 標記發送端當前在事務中
- 報告活躍狀態為RUNNING
- ‘C’
- 讀取事務提交信息,包括提交LSN、結束LSN、事務提交時間
- 更新復制源LSN為事務結束LSN,更新復制源時間戳為提交時間
- CommitTransactionCommand
- ‘I’
- 解析消息體,讀取rel_oid,newtup信息
- open relation并切初始化executor state、tuple slot
- 執行INSERT(
tableam_tuple_insert)
- ‘U’
- 解析消息體,讀取rel_oid,oldtup,newtup信息
- open relation并初始化executor state、tuple slot
- 是否能在relation中找到oldtup?如果不能找到,無需進一步處理
- 執行UPDATE(
tableam_tuple_update)
- ‘D’
-
解析消息體,讀取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

pub端
設置參數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
查看發布設置,檢驗發布是否成功


sub端
創建于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
查看訂閱屬性


兩端數據同步

Q&A
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。




