代码改变世界

【Vastbase G100】发布订阅功能详解与配置案例

2026-03-11 16:57  狂澜与玉昆0950  阅读(128)  评论(0)    收藏  举报
1. 概述
发布订阅基于逻辑复制实现的数据同步功能,允许一个或多个订阅者订阅发布者节点上的一个或多个发布,订阅者从它们所订阅的发布拉取数据,实现跨节点的数据实时同步。
核心特性:
  •   发布者上的更改会被实时发送给订阅者。订阅者以与发布者相同的顺序应用那些数据,这样在一个订阅中能够保证发布的事务一致性。
  •   订阅者数据库的行为与任何其他vastbase实例相同,也可以定义自己的发布,成为其他数据库的发布者,支持基于该模式实现级联发布订阅。
  •   订阅者可以被应用程序视为只读数据库,此时单个订阅内不会产生冲突;如果应用程序或其他订阅者在同一组表上执行写操作,则可能发生冲突。
2. 工作原理
逻辑复制原理:
  •   发布端通过逻辑解码反解xlog生成逻辑日志,目标数据库解析逻辑日志以实时进行数据复制。

image

发布订阅流程:

image

3. 注意事项
  •  发布端和订阅端的Vastbase G100数据库版本需保持一致。
  •  调用者必须拥有该表的所有权。FOR ALL TABLES 子句要求调用者是具有 SYSADMIN 权限用户。
  •  对象必须被明确地加入到发布,除非发布是用ALL TABLES创建的。
  •  发布可自定义同步的操作类型(INSERT/UPDATE/DELETE 任意组合),默认所有操作类型都会被复制。
  •  添加到发布 UPDATE 或 DELETE 操作的发布的表必须已经定义了 REPLICA IDENTITY,否则将在这些表上禁止这些操作。
    •  如果有主键,复制标识就是主键。
    •  如果表没有合适的键,可以设置成复制标识“full”(整行作为标识,执行alter table tablename replica identity full;),即整个行都成为键,但这样效率很低。
    •  如果发布者端设置了非“full”的复制标识(主键 / 唯一索引),订阅者端也必须设置一个复制标识,且订阅端标识列需为发布端标识列的相同列或子集。
  •  现有的发布不能启用或禁用 DDL 复制。
  •  发布端和订阅端的 schema 必须一致。
4. 风险项
  • 暂无
5. 配置案例
5.1 环境准备

image

 

5.2 发布者端配置
5.2.1 检验数据库参数
发布端需将 wal_level 参数设置为logical(支持逻辑复制),同时修改 synchronous_standby_names 参数,只保留数据库架构中的机器,避免第三方同步工具采用逻辑复制时被认为是备机,同步异常时阻塞主数据库。修改这两个参数后需重启数据库生效。
-- 查看参数当前值
vsql -c "show wal_level; show synchronous_standby_names;"
-- 修改参数 wal_level
vb_guc set -I all -N all -c "wal_level='logical'"
-- 修改参数 synchronous_standby_names
-- 主备/一主一备一仲裁:
vb_guc set -I all -N all -c "synchronous_standby_names='ANY 2(dn_6001,dn_6002)''
-- 一主两备集群:
vb_guc set -I all -N all -c "synchronous_standby_names='ANY 3(dn_6001,dn_6002,dn_6003)''
数据库重启生效(根据实际部署环境执行重启命令)
-- 单机
数据库关闭:root用户执行:stystemctl stop vastbase
数据库启动:root用户执行:stystemctl start vastbase
-- 主备
数据库关闭:
备节点root用户执行:stystemctl stop vastbase
主节点root用户执行:stystemctl stop vastbase
数据库启动:
主节点root用户执行:stystemctl start vastbase
备节点root用户执行:stystemctl start vastbase
-- HAS 1.x
关闭各节点Has服务,按异步备-同步备-主节点顺序依次关闭:
systemctl stop has
启动各节点Has服务,按主节点-同步备-异步备顺序依次关闭:
systemctl start has
-- HAS 3.x
集群关闭:cm_ctl stop
集群启动:cm_ctl start
-- 验证参数是否修改成功
vsql -c "show wal_level; show synchronous_standby_names;"

image

image 

5.2.2 创建测试表
在发布者数据库上创建带主键的测试表(employee员工表、department部门表),并插入初始数据,主键将作为默认复制标识:
-- 登录发布者数据库
vsql -d postgres -p 5432 -r
-- postgres 是数据库,根据实际情况替换
-- 创建测试表
CREATE TABLE employee (
id INTEGER PRIMARY KEY,
name VARCHAR(50),
department VARCHAR(50),
salary NUMERIC,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE department (
dept_id INTEGER PRIMARY KEY,
dept_name VARCHAR(50) NOT NULL,
location VARCHAR(100)
);
-- 插入初始数据
INSERT INTO department VALUES (1, '研发部', 'A座5层'), (2, '市场部', 'B座3层');
INSERT INTO employee VALUES (1001, '张三', '研发部', 15000, now()), (1002, '李四', '市场部', 12000, now());

image

5.2.3 创建发布
创建名为my_publication的发布,显式关联employee和department两张表,默认同步 INSERT/UPDATE/DELETE 所有操作和 DDL 操作:
-- 创建发布,发布两个表
CREATE PUBLICATION my_publication FOR TABLE employee, department with (ddl='table');
-- 查看已创建的发布
SELECT * FROM pg_publication;

image

5.2.4 配置连接权限
创建具备 SYSADMIN 权限的复制用户,并在pg_hba.conf中配置订阅端的复制连接权限,允许订阅端通过该用户连接发布端:
-- 创建复制用户
CREATE USER repl_user WITH PASSWORD 'replication@123' sysadmin;
-- 在pg_hba.conf中添加复制连接权限(需在操作系统层面操作)
gs_guc reload -I all -N all -h "host replication repl_user 192.168.124.171/32 sha256"

image

image

5.3 订阅者端配置
5.3.1 创建相同表结构
在订阅者数据库上创建相同的表结构(逻辑复制不会同步DDL操作,需要先将发布端表结构迁移到订阅端):
方式一:手动创建表结构
-- 登录订阅者数据库
vsql -d postgres -p 5432 -r
-- 创建相同的表结构
CREATE TABLE employee (
id INTEGER PRIMARY KEY,
name VARCHAR(50),
department VARCHAR(50),
salary NUMERIC,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE department (
dept_id INTEGER PRIMARY KEY,
dept_name VARCHAR(50) NOT NULL,
location VARCHAR(100)
);
注意:列名需要匹配,但列顺序可以不同,数据类型也不必完全相同,只要能进行文本形式的转换即可。目标表还可以包含发布表中不存在的额外列,这些列将使用默认值填充。
方式二:用逻辑导出导入功能创建表结构:
# 在订阅者端执行,从发布者导入表结构
vb_dump postgres -h 192.168.124.170 -p 5432 -U repl_user -s -t employee -t department > ddl.sql
# 删除或注释 ddl.sql 文件中发布的创建语句(避免订阅端创建重复发布)
# 导入表结构到订阅者
vsql -d postgres -p 5432 -f ddl.sql

image

image

image

5.3.2 密码加密
-- 创建订阅前,需要在订阅端执行密码加密(在操作系统命令行执行)
gs_guc generate -S replication@123 -D $GAUSSHOME/bin -o subscription
5.3.3 创建订阅
在订阅者端创建名为my_subscription的订阅,关联发布端的my_publication:
-- 创建订阅
CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=192.168.124.170 port=5433 user=repl_user dbname=postgres password=replication@123'
PUBLICATION my_publication
WITH (
enabled = true,
slot_name = 'my_subscription_slot',
synchronous_commit = 'off',
binary = false
);
参数说明:
- **subscription_name**:订阅名称,在数据库中唯一
- **CONNECTION**:连接发布端的字符串,包含IP地址、端口、数据库、用户名和密码
- **port**:必须使用主端口+1(即5433),否则会与线程池冲突
- **user/password**:需具有SYSADMIN或OPRADMIN权限
- **PUBLICATION**:要订阅的发布名称,一个订阅可对应多个发布
- **WITH选项**:
- **enabled**:指定订阅是否主动复制,默认为true
- **slot_name**:复制插槽名称,默认使用订阅名称
- **synchronous_commit**:覆盖synchronous_commit设置,逻辑复制通常设为off
- **binary**:是否以二进制格式发送数据,默认为false

image 

5.3.4 查看订阅状态
-- 查看订阅信息
SELECT * FROM pg_subscription;
-- 查看复制进度
SELECT * FROM pg_stat_subscription; 

image

5.4 验证复制功能
订阅创建成功后,分别测试历史数据同步、INSERT/UPDATE/DELETE 操作同步、DDL更新同步,验证数据是否能从发布端实时同步至订阅端。
5.4.1 历史数据库的同步
-- 订阅者执行
SELECT * FROM department;
SELECT * FROM employee;

image

预期结果:订阅端的查询结果与发布端初始数据完全一致。
5.4.2 测试数据插入
在发布者端插入新数据:
-- 发布者执行
INSERT INTO department VALUES (3, '财务部', 'A座8层');
INSERT INTO employee VALUES (1003, '王五', '财务部', 18000, now());
在订阅者端查询,验证数据是否同步:
-- 订阅者执行(稍等片刻)
SELECT * FROM department;
SELECT * FROM employee;

image

预期结果:订阅端能查询到发布端新增的数据。
5.4.3 测试数据更新
在发布者端更新数据:
-- 发布者执行
UPDATE employee SET salary = 20000 WHERE id = 1003;
在订阅者端验证更新是否生效。
-- 订阅者执行(稍等片刻)
SELECT * FROM employee;

image 

预期结果:订阅端中数据已更新。
5.4.4 测试数据删除
在发布者端删除数据:
-- 发布者执行
DELETE FROM employee WHERE id = 1001;
在订阅者端验证删除是否同步。
-- 订阅者执行(稍等片刻)
SELECT * FROM employee;

image

预期结果:订阅端中数据已被删除。
5.4.5 测试DDL变化
在发布者端修改表结构,使其增加一列:
-- 发布者执行
ALTER TABLE employee add column address varchar(100); 
在订阅者端验证DDL变更是否同步。
-- 订阅者执行
-- 查询表结构
\d+ employee

image

预期结果:订阅端中DDL已更新。
6. 发布订阅管理和运维
6.1 发布管理
支持修改发布的关联表、删除发布等操作,命令如下:
-- 修改发布的信息:用指定的表替换当前发布的表。
ALTER PUBLICATION my_publication SET TABLE product, department;
-- 修改发布的信息:为发布中添加一个或多个表。
ALTER PUBLICATION my_publication ADD TABLE product;
-- 修改发布的信息:从发布中删除一个或多个表。
ALTER PUBLICATION my_publication DROP TABLE employee;
-- 删除发布(需先确保订阅端已删除对应订阅,避免残留复制槽)
DROP PUBLICATION my_publication;
6.2 订阅管理
支持修改订阅连接信息、激活 / 停用订阅、刷新订阅、删除订阅等操作,命令如下:
-- 修改订阅的发布端连接信息
ALTER SUBSCRIPTION my_subscription CONNECTION 'host=192.168.1.11 port=5433 user=repl_user dbname=postgres password=replication@123';
-- 激活订阅(若创建时设置enabled = false,需手动激活)
ALTER SUBSCRIPTION my_subscription SET (enabled = true);
-- 刷新订阅(发布端新增/移除同步表后,订阅端执行刷新以同步表关联关系和初始数据)
ALTER SUBSCRIPTION my_subscription REFRESH PUBLICATION;
-- 删除订阅(同时自动删除发布端的对应复制槽)
DROP SUBSCRIPTION my_subscription;

image

6.3 发布订阅运维
Vastbase G100提供多个视图用于监控发布端和订阅端的复制状态:
视图名称         执行节点    核心作用
pg_replication_slots    发布者    查看复制槽状态(是否活跃、未读取日志量等)
pg_stat_replication     发布者    查看发布端数据发送进度、网络连接状态
pg_publication        发布者    查看发布的基本信息(操作类型等)
pg_subscription      订阅者    查看订阅的基本信息(连接信息、关联发布等)
pg_stat_subscription   订阅者    查看订阅端应用进度、复制延迟、同步状态
-- 查询发布名称和对应表
SELECT
pub.pubname,
n.nspname AS schema_name,
c.relname AS table_name
FROM pg_publication_rel pr
JOIN pg_publication pub on pr.prpubid = pub.oid
JOIN pg_class c ON pr.prrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid;

-- 查询订阅名称和对应表
SELECT
sub.subname,
n.nspname AS schema_name,
c.relname AS table_name,
(case sr.srsubstate when 'i' then '初始化' when 'd' then '基础数据正在复制' when 'f' then '基础数据复制完成' when 's' then '已与增量复制进度同步' when 'r' then '准备好增量复制' end) as "订阅状态"
FROM pg_subscription_rel sr
JOIN pg_subscription sub on sr.srsubid = sub.oid
JOIN pg_class c ON sr.srrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid;
7. FAQ

image