更新时间:2024-07-04 GMT+08:00

逻辑解码概述

功能描述

GaussDB对数据复制能力的支持情况为:

  • 支持通过数据迁移工具定期向异构数据库(如Oracle等)进行数据同步,不具备实时数据复制能力。不足以支撑与异构数据库间并网运行实时数据同步的诉求。
  • GaussDB双集群容灾方案间的数据同步通过《工具参考》中“服务端工具 >SyncDataToStby”章节实现。备集群不支持异形部署,即不支持CN、DN数量和实例部署形态与原集群不一致。备集群恢复期间不支持读写操作,且复制时延相对较高。

基于上述两点,GaussDB提供了逻辑解码功能,通过反解xlog的方式生成逻辑日志。目标数据库解析逻辑日志以实时进行数据复制。具体如图1所示。逻辑复制降低了对目标数据库的形态限制,支持异构数据库、同构异形数据库对数据的同步,支持目标库进行数据同步期间的数据可读写,数据同步时延低。

图1 逻辑复制

逻辑复制由两部分组成:逻辑解码和数据复制。逻辑解码会输出以事务为单位组织的逻辑日志。业务或数据库中间件将会对逻辑日志进行解析并最终实现数据复制。GaussDB当前只提供逻辑解码功能,因此本章节只涉及逻辑解码的说明。

逻辑解码为逻辑复制提供事务解码的基础能力,GaussDB使用SQL函数接口进行逻辑解码。此方法调用方便,不需使用工具,对接外部工具接口也比较清晰,不需要额外适配。

由于逻辑日志是以事务为单位的,在事务提交后才能输出,且逻辑解码是由用户驱动的;因此为了防止事务开始时的xlog被系统回收,或所需的事务信息被VACUUM回收,GaussDB新增了逻辑复制槽,用于阻塞xlog的回收。

一个逻辑复制槽表示一个更改流,这些更改可以在其它集群上以它们在原集群上产生的顺序被重播。逻辑复制槽,由每个逻辑日志的获取者维护一个。如果处于流式解码中的逻辑复制槽所在库不存在业务,则该复制槽会依照其他库的日志位置来推进。活跃状态的LSN序逻辑复制槽在处理到活跃事务快照日志时可以根据当前日志的LSN推进复制槽;活跃状态的CSN序逻辑复制槽在处理到虚拟事务日志时可以根据当前日志的CSN推进复制槽。

前提条件

  • 逻辑日志目前从DN中抽取,如果进行逻辑复制,需要保证DN上的GUC参数ssl设置为on。

    为避免安全风险,请保证启用SSL连接。

  • 设置GUC参数wal_level为logical。
  • 设置GUC参数max_replication_slots>=每个DN所需的(物理流复制槽数+备份槽数+逻辑复制槽数)。

    物理流复制槽提供了一种自动化的方法来确保主DN在所有备DN收到xlog之前,xlog不会被移除。也就是说物理流复制槽用于支撑集群HA。集群所需要的物理流复制槽数为:一组DN中,备与主DN之间的比例。例如,假设集群的DN高可用方案为1主3备,则所需物理流复制槽数为3。

    关于逻辑复制槽数,请按如下规则考虑。
    • 一个逻辑复制槽只能解码一个Database的修改,如果需要解码多个Database,则需要创建多个逻辑复制槽。
    • 如果需要多路逻辑复制同步给多个目标数据库,在源端数据库需要创建多个逻辑复制槽,每个逻辑复制槽对应一条逻辑复制链路。
    • 同一实例上,最多支持同时开启20个逻辑复制槽进行解码。
  • 用户需要通过DN端口连接数据库,才可以直接使用SQL函数接口进行逻辑解码操作。如果使用CN端口连接数据库,则需要通过EXECUTE DIRECT ON (datanode_name) 'statement'语句来执行SQL函数。
  • 仅限初始用户和拥有REPLICATION权限的用户进行操作。三权分立关闭时数据库管理员可进行逻辑复制操作,三权分立开启时不允许数据库管理员进行逻辑复制操作。

注意事项

  • 不支持DDL语句解码,在执行特定的DDL语句(如普通表truncate或分区表exchange)时,可能造成解码数据丢失。
  • 不支持数据页复制的解码。
  • 当执行DDL语句(如alter table)后,该DDL语句前尚未解码的物理日志可能会丢失。
  • 使用逻辑解码功能时,禁止进行集群在线扩容。
  • 单条元组大小不超过1GB,考虑解码结果可能大于插入数据,因此建议单条元组大小不超过500MB。
  • 不支持压缩表的DML语句解码。
  • GaussDB支持解码的数据类型为:INTEGER、BIGINT、SMALLINT、TINYINT、SERIAL、SMALLSERIAL、BIGSERIAL、FLOAT、DOUBLE PRECISION、BOOLEAN、BIT(n)、BIT VARYING(n)、DATE、TIME[WITHOUT TIME ZONE]、TIMESTAMP[WITHOUT TIME ZONE]、CHAR(n)、VARCHAR(n)、TEXT、CLOB(解码成TEXT格式)。
  • 如果需要ssl连接需要保证前置条件guc参数ssl设置为on。
  • 逻辑复制槽名称必须小于64个字符,且只包含小写字母、数字或者下划线中的一种或几种。
  • 当逻辑复制槽所在数据库被删除后,这些复制槽变为不可用状态,需要用户手动删除。
  • 不支持interval partition表复制。
  • 对多库的解码需要分别在库内创建流复制槽并开始解码,每个库的解码都需要单独扫一遍日志。
  • 不支持强切,强切后需要重新全量导出数据。
  • 在事务中执行DDL语句后,该DDL语句与之后的语句不会被解码。
  • 备机解码时,switchover和failover时可能出现解码数据变多,需用户手动过滤。Quorum协议下,switchover和failover选择升主的备机,需要与当前主机日志同步。
  • 不允许主备,多个备机同时使用同一个复制槽解码,否则会产生数据不一致的情况。
  • 只支持主机创建删除复制槽。
  • 数据库故障重启或逻辑复制进程重启后,解码数据可能存在重复,用户需自己过滤。
  • 计算机内核故障后,解码可能存在乱码,需手动或自动过滤。
  • 请确保在创建逻辑复制槽过程中长事务未启动,启动长事务会阻塞逻辑复制槽的创建。如果创建复制槽时因为长事务阻塞,可通过执行SQL函数pg_terminate_backend(创建该复制槽线程id)来手动停止创建。
  • 为解析某个astore表的UPDATE和DELETE语句,需为此表配置REPLICA IDENTITY属性,在此表无主键时需要配置为FULL,否则UPDATE和DELETE语句的解码结果将不会标识操作的修改行。配置方式请参考《开发者指南》中“SQL参考 > SQL语法 > ALTER TABLE”章节中“REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }”字段。
  • 禁止在使用逻辑复制槽时在其他节点对该复制槽进行操作,删除复制槽的操作需在该复制槽停止解码后执行。
  • 基于目标库可能需要源库的系统状态信息考虑,逻辑解码仅自动过滤模式'pg_catalog'和'pg_toast'下OID小于16384的系统表的逻辑日志。若目标库不需要复制其他相关系统表的内容,逻辑日志回放过程中需要对相关系统表进行过滤。
  • 在开启逻辑复制的场景下,如需创建包含系统列的主键索引,必须将该表的REPLICA IDENTITY属性设置为FULL或是使用USING INDEX指定不包含系统列的、唯一的、非局部的、不可延迟的、仅包括标记为NOT NULL的列的索引。
  • 对于缩容或升级前已存在的复制表场景,需要对复制表手动配置logical_repl_node属性或RESET为默认值,配置方式请参考《开发者指南》中“SQL参考 > SQL语法 > ALTER TABLE”章节中“storage_parameter”参数的使用说明,以及“logical_repl_node”属性相关说明。
  • 若一个事务的子事务过多导致落盘文件过多,退出解码时需执行SQL函数pg_terminate_backend(逻辑解码的walsender线程id)来手动停止解码,而且退出时延增加约为1分钟/30万个子事务。因此在开启逻辑解码时,若一个事务的子事务数量达到5万时,会打印一条WARNING日志。
  • 当逻辑复制槽处于非活跃状态,且设置GUC参数enable_xlog_prune=on、enable_logicalrepl_xlog_prune=on、max_size_for_xlog_retention为非零值,且备份槽或逻辑复制槽导致保留日志段数已超过GUC参数wal_keep_segments同时其他复制槽并未导致更多的保留日志段数时,如果max_size_for_xlog_retention大于0且当前逻辑复制槽导致保留日志的段数(每段日志大小为16MB)超过max_size_for_xlog_retention,或者max_size_for_xlog_retention小于0且磁盘使用率达到(-max_size_for_xlog_retention)/100,当前逻辑复制槽会强制失效,其restart_lsn将被设置为FFFFFFFF/FFFFFFFF。该状态的逻辑复制槽不参与阻塞日志回收或系统表历史版本的回收,但仍占用复制槽的限制数量,需要手动删除。
  • 备机解码启动后,向主机发送复制槽推进指令后会占用主机上对应的逻辑复制槽(即标识为活跃状态)。在此之前主机上对应逻辑复制槽为非活跃状态,此状态下如果满足逻辑复制槽强制失效条件则会被标记为失效(即restart_lsn将被设置为FFFFFFFF/FFFFFFFF),备机将无法推进主机复制槽,且备机回放完成复制槽失效日志后当前复制槽的备机解码断开后将无法重连。
  • 不活跃的逻辑复制槽将阻塞WAL日志回收和系统表元组历史版本清理,导致磁盘日志堆积和系统表扫描性能下降,因此不再使用的逻辑复制槽请及时清理。需要特别注意,在升级提交之前观察期内使用DN扩展IP连接DN创建的逻辑复制槽,在升级回滚之前务必手动清理,否则随着DN扩展IP特性回滚无法直连DN清理。
  • 分布式强一致逻辑解码(连接CN解码)仅支持GTM-Lite分布式部署及流式解码,不支持CN连接备DN进行解码、SQL逻辑解码函数、在线扩容、全局索引。
  • 针对分布式强一致逻辑解码(连接CN解码)功能,CN高可用由业务负责切换。
  • CN上的CSN序逻辑复制槽仅起到占位作用,不随着逻辑解码的进行而推进,同时也不会阻塞日志回收,因此此类复制槽xmin、catalog_xmin、restart_lsn、confirmed_flush和confirmed_csn字段均不显示。
  • 通过协议连接CN创建逻辑复制槽仅支持CSN序复制槽,通过协议连接DN创建逻辑复制槽仅支持LSN序复制槽。
  • 针对分布式解码,对于故障报错或者手动停止解码客户端等场景,需等待15s再次重试解码,如有复制槽占用则需通过执行SQL函数pg_terminate_backend(占用该复制槽线程id)来手动解除复制槽占用。
  • 在CN上创建复制槽失败报错后,需要在CN上进行复制槽删除操作,然后在CN上重新创建复制槽。
  • 在CN上删除逻辑复制槽时,若为LSN序逻辑复制槽,则仅删除当前节点复制槽,其他节点同名逻辑复制槽不受影响;否则只要其他节点有残留同名CSN序逻辑复制槽,执行删除时不会因为某些节点不存在复制槽而报错,同时所有节点的同名复制槽会被成功删除;如果任何节点均不存在该复制槽,则报错。
  • 在CN上创建CSN序逻辑复制槽时,某些节点如残留同名LSN序逻辑复制槽,需在这些节点执行删除残留复制槽的操作。否则会在除当前CN节点外,其他不存在同名复制槽的CN和主DN节点上创建CSN序逻辑复制槽。
  • 如果当前CN节点残留LSN序逻辑复制槽,同时其他某些节点上残留同名CSN序逻辑复制槽,则在当前CN节点上执行删除复制槽操作仅会删除本地LSN序逻辑复制槽,待删除完成再次执行删除操作方可删除其他节点的同名复制槽。
  • 解码使用JSON格式输出时不支持数据列包含特殊字符(如'\0'空字符),解码输出列内容将出现被截断现象。
  • 当同一事务产生大量需要落盘的子事务时,同时打开的文件句柄可能会超限,需将GUC参数max_files_per_process配置成大于子事务数量上限的两倍。
  • sql_decoding将UPDATE语句解码为DELETE+INSERT操作。

性能

在Benchmarksql-5.0的100warehouse场景下,采用pg_logical_slot_get_changes时:
  • 单次解码数据量4K行(对应约5MB~10MB日志),解码性能0.3MB/s~0.5 MB/s。
  • 单次解码数据量32K行(对应约40MB~80MB日志),解码性能3MB/s~5MB/s。
  • 单次解码数据量256K行(对应约320MB~640MB日志),解码性能3MB/s~5MB/s。
  • 单次解码数据量再增大,解码性能无明显提升。

如果采用pg_logical_slot_peek_changes + pg_replication_slot_advance方式,解码性能相比采用pg_logical_slot_get_changes时要下降30%~50%。