使用普通的数据迁移工具,虽能达成GBase 8c数据库与像Oracle这类异构数据库的数据同步,但往往难以做到实时复制数据,也就无法满足异构数据库并网运行时实时数据同步的要求。为解决这一问题,GBase 8c推出了逻辑解码功能,它的核心原理是通过对xlog进行反解,生成逻辑日志,让目标数据库解析这些日志,从而实现实时的数据复制。

逻辑复制功能优势明显,它对目标数据库的形态限制较小,无论是异构数据库,还是同构异形数据库之间的数据同步场景,都能完美适配。而且,在数据同步期间,目标库还能正常进行数据的读写操作,数据同步的延迟也比较低。接下来,本文将通过具体操作示例,详细介绍GBase 8c逻辑复制槽功能的实践应用。

一、配置GUC参数

在使用复制槽之前,需要对GBase 8c的GUC参数进行配置,主要涉及以下几个参数:

  • wal_level = logical:将wal_level设置为logical,开启逻辑日志功能,为后续生成逻辑日志做准备。
  • enable_slot_log = on:用于指定是否开启逻辑复制槽主备同步特性,默认值是off。开启这个特性,有助于实现主备库之间复制槽信息的同步以及数据变更的获取。
  • host replication all 0.0.0.0/0 sha256:设置允许从任何IP地址进行复制连接,并使用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 

二、创建逻辑复制槽

使用下面的SQL语句创建逻辑复制槽:

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

这条语句创建了一个名为test_slot的逻辑复制槽,并指定使用wal2json插件。wal2json插件的作用是将逻辑日志转换为JSON格式,方便后续的解析和处理。

三、获取复制槽列表

想要查看当前数据库中的复制槽列表,可以使用以下两条SQL语句:

select pg_get_replication_slots(); select * from pg_replication_slots; 

这两条语句都能获取复制槽的相关信息,不过select * from pg_replication_slots;返回的信息会更加详细,能帮助我们全面了解复制槽的状态等情况。

四、删除复制槽

当某个复制槽不再需要时,可以使用以下SQL语句进行删除:

select pg_drop_replication_slot('test_slot'); 

执行这条语句后,名为test_slot的复制槽就会被删除。在实际操作中,要谨慎使用删除操作,避免误删有用的复制槽。

五、解码并不推进流复制槽

在不推进流复制槽的情况下进行解码,意味着下次解码时还能获取到本次解出的数据。可以使用以下SQL语句实现:

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'); 

其中,pg_logical_slot_peek_changes函数用于查看复制槽中的变更数据。通过设置不同的参数,如pretty-print设置为1,可以使输出的数据格式更加美观,便于查看;include-timestamp设置为on,则会在输出数据中包含时间戳信息。

六、解码并推进流复制槽

如果希望在解码的同时推进流复制槽,可以使用以下SQL语句:

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'); 

pg_logical_slot_get_changes函数与pg_logical_slot_peek_changes函数类似,但pg_logical_slot_get_changes会推进复制槽,即下次再获取数据时,获取的是本次之后的新数据。

七、复制槽监控

为了实时了解复制槽的状态,GBase 8c提供了相关的监控语句:

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')); 

第一条语句用于查询复制槽的详细信息,包括复制槽名称、所属数据库、使用的插件、是否处于活动状态等。其中,pg_size_pretty(pg_xlog_location_diff(...))函数用于计算并显示复制槽延迟的日志量大小。第二条语句则是单独展示两个日志位置之间的差异大小。通过这些监控语句,管理员可以及时发现复制槽可能存在的问题,比如延迟过大等,并采取相应的措施进行优化。

(一)enable_slot_log效果验证

enable_slot_log这个参数对逻辑复制槽主备同步特性影响较大,下面通过假设场景来验证它的效果。假设在一个高可用组中,有A和B两个节点,初始时A为主库,B为从库。

  • 当enable_slot_log = off时:在A上创建复制槽,B中无法查到复制槽信息,也不能查询数据变更。当主备切换,B成为主库,A变为从库后,B依然查不到复制槽信息,无法进行逻辑解码;而A虽然可以查到复制槽信息及进行逻辑解码,但如果A发生故障无法启动,那么复制流就会中断。
  • 当enable_slot_log = on时:A创建复制槽后,B中能查到复制槽信息,也可以进行逻辑解码获取数据变更,不过B库无法推进复制槽。主备切换后,B为主库,A为从库,此时B和A都可以查到复制槽信息并进行逻辑解码,但A无法推进复制槽。

八、设置记录级别

在逻辑复制场景下,还可以设置表的记录级别,控制UPDATE和DELETE操作中旧元组的记录方式,这可以通过以下SQL语句实现:

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'; 

记录级别有几种不同的选项:

  • DEFAULT:只记录主键列的旧值,如果表没有主键,则不记录旧值。
  • USING INDEX:记录命名索引覆盖的列的旧值,不过这些列必须满足唯一、不局部、不可延迟且标记为NOT NULL的条件。
  • FULL:记录该行中所有列的旧值。
  • NOTHING:不记录有关旧行的任何信息。

在实际应用中,对于有主键的表,该选项可以设置为DEFAULTFULL;对于无主键的表,为了确保解码时旧元组能正常解析,需要设置为FULL,否则旧元组在解码时会解析为空。一般情况下,不建议设置为NOTHING,因为这样旧元组始终会解析为空。需要注意的是,即使指定了DEFAULTUSING INDEX,对于ustore表,只有旧值涉及toast时,该配置选项才会生效。而且针对ustore表,NOTHING选项无效,实际效果等同于FULL

通过以上对GBase 8c逻辑复制槽功能的详细实践介绍,希望能帮助大家更好地理解和运用这一功能,如有问题欢迎留言哦。