GBase新闻

专注于数据库软件产品和服务,致力于成为用户最信赖的数据库产品供应商

“G”术时刻 | GBase数据库逻辑复制槽功能应用实践

发布时间:2025-04-10

通过普通数据迁移工具可以实现GBase数据库与如Oracle等异构数据库的数据同步,但大多不具备实时数据复制的能力,无法支撑与异构数据库间并网运行实时数据同步的诉求。为应对这种场景,GBase 数据库提供逻辑解码功能,核心思想是通过反解xlog的方式生成逻辑日志,目标数据库解析逻辑日志以实时进行数据复制。

逻辑复制功能可以降低对目标数据库的形态限制,完美支撑异构数据库、同构异形数据库的数据同步场景,支持目标库进行数据同步期间的数据可读写,数据同步时延低。

那么如何实践应用呢?本文将通过简单的数据为例,进行操作说明:

(1)使用复制槽之前,需要配置以下GUC参数:

wal_level = logical

enable_slot_log = on

host replication all 0.0.0.0/0 sha256

gbase用户身份执行命令:

gs_guc reload -Z coordinator -N all -I all -c “wal_level = logical”

gs_guc reload -Z coordinator -N all -I all -c “enable_slot_log = on”

gs_guc reload -Z coordinator -N all -I all -h “host replication all 0.0.0.0/0 sha256”

重启数据库生效,例如执行:

gha_ctl restart -l http://192.168.142.56:2379

(2)创建逻辑复制槽

select pg_create_logical_replication_slot('test_slot', 'wal2json');

(3)获取复制槽列表

select pg_get_replication_slots();select * from pg_replication_slots;

(4)删除复制槽

select pg_drop_replication_slot('test_slot');

(5)解码并不推进流复制槽(下次解码可以再次获取本次解出的数据)

select pg_logical_slot_peek_changes('slot_name', 'LSN', upto_nchanges, 'options_name', 'options_value');

select pg_logical_slot_peek_changes('test_slot',null,null);

select data from pg_logical_slot_peek_changes('test_slot', null, null, 'pretty-print', '1');

select * from pg_logical_slot_peek_changes('test_slot', null, null, 'include-timestamp', 'on');

(6)解码并推进流复制槽

pg_logical_slot_get_changes('slot_name', 'LSN', upto_nchanges, 'options_name', 'options_value')

select pg_logical_slot_get_changes('test_slot', null, null);

select data from pg_logical_slot_get_changes('test_slot', null, null, 'pretty-print', '1');

(7)复制槽监控

select  slot_name,  database as datname,  plugin,  slot_type,  datoid,  database,  active,  xmin,  catalog_xmin,   restart_lsn,  pg_size_pretty(pg_xlog_location_diff(  case    when pg_is_in_recovery() then pg_last_xlog_receive_location()  else pg_current_xlog_location()  end ,  restart_lsn)) as delay_lsn_bytes,  dummy_standby,  confirmed_flush

from pg_replication_slots; 

select pg_size_pretty(pg_xlog_location_diff('7F9/F7241AA0','76D/3FE8E558'));

其中enable_slot_log的作用:指定是否开启逻辑复制槽主备同步特性,默认值为off。

如何验证enable_slot_log效果?假设在一个高可用组中,初始情况下,A为主,B为从。

  • 假如enable_slot_log = off

A创建复制槽,在B中无法查到复制槽信息,也无法查询数据变更。

主备切换后,B为主库,A为从库。B仍无法查到复制槽信息,也无法逻辑解码。A可以查到复制槽信息及逻辑解码。在B上修改数据,A中也可以逻辑解码,获取到数据变更。因此,如果发生了故障切换,A无法正常启动的情况下,无法再继续逻辑解码,复制流将中断。

  • 假如enable_slot_log = on

A创建复制槽,在B中可以查到复制槽信息,同时也能够逻辑解码,获取到数据变更,但是B库无法推进复制槽。如下图所示:

主备切换后,B为主库,A为从库。B可以查到复制槽信息,也可以逻辑解码。A可以查到复制槽信息及逻辑解码。在B上修改数据,A中也可以逻辑解码,获取到数据变更,但A无法推进复制槽。

(8)设置记录级别

alter table t1 replica identity full;

select a.relname, b.nspname, a.relreplident

from pg_catalog.pg_class a join pg_catalog.pg_namespace b on a.relnamespace = b.oid

where a.relname = 't1' and b.nspname = 'public' and a.relkind = 'r';

在逻辑复制场景下,指定该表的UPDATE和DELETE操作中旧元组的记录级别。

  • DEFAULT记录主键的列的旧值,没有主键则不记录。

  • USING INDEX记录命名索引覆盖的列的旧值,这些值必须是唯一的、不局部的、不可延迟的,并且仅包括标记为NOT NULL的列。

  • FULL记录该行中所有列的旧值。

  • NOTHING不记录有关旧行的信息。

在逻辑复制场景,解析该表的UPDATE和DELETE操作语句时,解析出的旧元组由以此方法记录的信息组成。对于有主键表该选项可设置为DEFAULT或FULL。对于无主键表该选项需设置为FULL,否则解码时旧元组将解析为空。一般场景不建议设置为NOTHING,旧元组会始终解析为空。

即使指定DEFAULT或USING INDEX,当前ustore表列的旧值中也可能包含该行所有列的旧值,只有旧值涉及toast该配置选项才会生效。另外针对ustore表,选项NOTHING无效,实际效果等同于FULL。