逻辑解码选项
逻辑解码选项可以用来为本次逻辑解码提供限制或额外功能,如“解码结果是否包含事务号”、“解码时是否忽略空事务”等。对于具体配置方法,SQL函数解码请参考《开发指南》中“SQL参考 > 函数和操作符 > 系统管理函数 > 逻辑复制函数”章节中函数pg_logical_slot_peek_changes的可选入参''options_name'和'options_value',JDBC流式解码请参考《开发指南》中“应用程序开发教程 > 基于JDBC开发 > 示例:逻辑复制代码示例”章节示例代码中函数withSlotOption的使用方法。
通用选项(串行解码和并行解码均可配置,但可能无效,请参考相关选项详细说明)
- include-xids:
取值范围:boolean型,默认值为true。
- false:设为false时,解码出的data列不包含xid信息。
- true:设为true时,解码出的data列包含xid信息。
- skip-empty-xacts:
取值范围:boolean型,默认值为false。
- false:设为false时,解码时不忽略空事务信息。
- true:设为true时,解码时会忽略空事务信息。
- include-timestamp:
取值范围:boolean型,针对并行解码场景默认值为false,针对SQL函数解码和串行解码场景默认值为true。
- false:设为false时,解码信息不包含commit时间戳。
- true:设为true时,解码信息包含commit时间戳。
- only-local:
取值范围:boolean型,默认值为true。
- false:设为false时,解码非本地日志和本地日志。
- true:设为true时,仅解码本地日志。
- white-table-list:
取值范围:包含白名单中表名的字符串,不同的表以','为分隔符进行隔离;使用'*'来模糊匹配所有情况;schema名和表名间以'.'分隔,不允许存在任意空白符。例如:
select * from pg_logical_slot_peek_changes('slot1', NULL, 4096, 'white-table-list', 'public.t1,public.t2,*.t3,my_schema.*');
- max-txn-in-memory:
内存管控参数,单位为MB,单个事务占用内存大于该值即进行落盘。
串行解码-取值范围:0~100的整型,默认值为0,即不开启此种管控。
并行解码-取值范围:0~max_process_memory总量的25%,默认值为max_process_memory/4/1024,其中1024为kB到MB的单位转换,0表示不开启此条内存管控项。
- max-reorderbuffer-in-memory
内存管控参数,单位为GB,拼接-发送线程中正在拼接的事务总内存(包含缓存)大于该值则对当前解码事务进行落盘。
串行解码-取值范围:0~100的整型,默认值为0,即不开启此种管控。
并行解码-取值范围:0~max_process_memory总量的50%,默认值为max_process_memory/2/1048576,其中1048576为kB到GB的单位转换,0表示不开启此条内存管控项。
- include-user:
事务的BEGIN逻辑日志是否输出事务的用户名。事务的用户名特指授权用户——执行事务对应会话的登录用户,它在事务的整个执行过程中不会发生变化。
取值范围:boolean型,默认值为false。
- false:设为false时,事务的BEGIN逻辑日志不输出事务的用户名。
- true:设为true时,事务的BEGIN逻辑日志输出事务的用户名。
- exclude-userids:
黑名单用户的OID参数,该参数只支持直连DN解码任务配置,分布式CN强一致解码不支持该参数。
取值范围:字符串类型,指定黑名单用户的OID,多个OID通过','分隔,不校验用户OID是否存在。
- exclude-users:
取值范围:字符串类型,指定黑名单用户名,通过','分隔,不校验用户名是否存在。
- dynamic-resolution:
是否动态解析黑名单用户名。如果解码某条XLOG,且XLOG写入时,用户未创建,则认为用户不存在。
取值范围:boolean型,默认值为true。
- false:设为false时,当解码观测到黑名单exclude-users中用户不存在时将会报错并退出逻辑解码;当用户存在,黑名单功能正常过滤用户的操作。
- true:设为true时,当解码观测到黑名单exclude-users中用户不存在时不报错,并正常解码;当用户存在,黑名单功能正常过滤用户的操作。
- standby-connection:
仅流式解码设置,是否仅限制备机解码,因为CN没有备机,所以该参数在仅连接DN时支持。
取值范围:boolean型,默认值为false。
- true:设为true时,仅允许连接备机解码,连接主机解码时会报错退出。
- false:设为false时,不做限制,允许连接主机或备机解码。
如果主机资源使用率较大且业务对增量数据同步的实时性不敏感,建议进行备机解码;如果业务对增量数据同步的实时性要求高并且主机业务压力较小,建议使用主机解码。
- sender-timeout:
仅流式解码设置,内核与客户端的心跳超时阈值。如果该时间段内没有收到客户端任何消息,逻辑解码将主动停止,并断开和客户端的连接。单位为毫秒(ms)。
取值范围:0~2147483647的int型,默认值取决于GUC参数logical_sender_timeout的配置值。设置为0,表示逻辑解码不会主动断开与客户端的连接,如果设置过小,例如1ms,则可能存在解码任务中断风险。
- change-log-max-len:
逻辑日志缓存长度上限参数,单位为字节。仅连接DN的并行解码有效,分布式强一致解码、串行解码及SQL函数解码无效。如果单条解码结果长度超过上限,则会销毁重新分配大小为1024字节的内存并缓存。过长会增加内存占用,过短会频繁触发内存申请和释放的操作,不建议设置成小于1024的值。
取值范围:1~65535,默认值为4096。
- max-decode-to-sender-cache-num:
并行解码日志的缓存条数阈值。仅连接DN的并行解码有效,分布式强一致解码、串行解码及SQL函数解码无效。缓存中的日志条数未超过这个阈值时,使用完毕的解码日志将置入缓存,否则直接释放。
取值范围:1~65535,默认值为4096。
- enable-heartbeat:
取值范围:boolean型,默认值为false。
- true:设为true时,输出心跳日志。
- false:设为false时,不输出心跳日志。
若开启心跳日志选项,此处说明并行解码场景心跳日志如何解析:二进制格式首先是字符'h'表示消息是心跳日志,之后是心跳日志内容,分别是8字节uint64,直连DN解码场景代表LSN,表示发送心跳逻辑日志时读取的WAL日志结束位置,而在分布式强一致解码场景为CSN,表示发送心跳逻辑日志时已发送的解码日志事务CSN;8字节uint64,直连DN解码场景代表LSN,表示发送心跳逻辑日志时刻已经落盘的WAL日志的位置,而在分布式强一致解码场景为CSN,表示集群下一个提交事务将获得的CSN;8字节int64代表时间戳(从1970年1月1日开始),表示最新解码到的事务日志或检查点日志的产生时间戳。关于消息结束符:如果是二进制格式则为字符'F',如果格式为text或者json且为批量发送则结束符为0,否则没有结束符。消息内容采用大端字节序进行数据传输。具体格式见下图(考虑到前向兼容性,相关部分仍保留着LSN的命名方式,实际含义依具体场景而定):
- parallel-decode-num:
仅流式解码设置有效,并行解码的Decoder线程数量;系统函数调用场景下此选项无效,仅校验取值范围。
取值范围:1~20的int型,取1表示按照原有的串行逻辑进行解码,取其余值即为开启并行解码,默认值为1。
当parallel-decode-num不配置(即为默认值1)或显式配置为1时,下述“并行解码”中的选项不可配置。
- output-order:
仅流式解码设置有效,代表是否使用CSN顺序输出解码结果;系统函数调用场景下此选项无效,仅校验取值范围。
取值范围:0或1的int型,默认值为0。
- 0:设为0时,解码结果按照事务的COMMIT LSN排序,当且仅当解码复制槽的confirmed_csn列值为0(即不显示)时可使用该方式,否则报错。
- 1:设为1时,解码结果按照事务的CSN排序,当且仅当解码复制槽的confirmed_csn列值为非零时可使用该方式,否则报错。
- 当output-order不配置(即为默认值0,按照COMMIT LSN排序)或显式配置为0时,下述“分布式强一致解码”中的选项不可配置。
- 在流式解码场景,DN收到来自CN的逻辑解码连接时,output-order选项失效,默认采用CSN序解码。
-
仅流式解码设置有效,代表是否允许自主推进逻辑复制槽。
取值范围:boolean型,默认值为false。
- true:设为true时,在已发送日志都被确认推进且没有待发送事务时,推进逻辑复制槽到当前解码位置。
- false:设为false时,完全交由复制业务调用日志确认接口推进逻辑复制槽。
- skip-generated-columns:
逻辑解码控制参数,用于跳过存储生成列的输出。对UPDATE和DELETE的旧元组无效,相应元组始终会输出存储生成列。分布式版本暂不支持存储生成列,此配置选项暂无实际影响。
取值范围:boolean型,默认值为false/off。
- true/on:值为true/on时,不输出存储生成列的解码结果。
- false/off:设为false/off时,输出存储生成列的解码结果。
虚拟生成列不受此参数控制,DML的解码结果始终不会输出虚拟生成列。
- enable-ddl-decoding:
取值范围:boolean型,默认值为false。
- true:值为true时,开启DDL语句的逻辑解码。
- false:值为false时,不开启DDL语句的逻辑解码。
- enable-ddl-json-format:
取值范围:boolean型,默认值为false。
- true:值为true时,传送JSON格式的DDL反解析结果。
- false:设为false时,传送decode-style指定格式的DDL反解析结果。
- timezone-is-utc:
逻辑解码控制参数,用于控制时间类型(携带时区)数据的输出。如ORA、MYSQL兼容下的timestamptz类型,M兼容的timestamp类型都表示带时区的时间类型,默认会输出当前数据库时区的时间,设置为true时,在解码时会强制输出为0时区的时间。该参数仅对流式解码有效,函数解码使用该参数会忽略不生效。
取值范围:boolean型,默认值为false。
- true:值为true时,解码时间类型数据输出0时区的时间。
- false:值为false时,解码时间类型数据输出当前数据库时区的时间。
- decode-sequence:
逻辑解码控制参数,用来指定是否输出sequence值的变更日志的解码结果。
取值范围:boolean型,默认值为false。
- true:暂不支持设置。
- false:设为false时,不输出sequence值的变更日志的解码结果。
解码选项decode-sequence当前仅允许设置为false,设置为true会在启动解码时报错退出。
分布式强一致解码
- logical-receiver-num:
仅流式解码设置有效,分布式解码启动的logical_receiver数量,系统函数调用场景下此选项无效,仅校验取值范围。
取值范围:1~20的int型,默认值为1。当该值被设置为比当前集群分片数更大时,将被修改为分片数。
- slice-id:
仅连接DN解码时设置,指定当前DN所在的分片号,用于复制表解码。
取值范围:0~8192的int型,默认值为-1,即不指定分片号,但在解码到复制表时会报错。
该配置选项在尝试连接DN使用CSN序逻辑复制槽(confirmed_csn为非0值的复制槽)进行解码时使用,用来表示自己的分片号(即第几个分片,第一个分片则输入0),如果不设置该参数(即使用默认值-1)在解码到复制表时将会报错。此参数用于使用连接CN的分布式解码时,CN从DN收集解码结果时使用,CN只会收集指定DN分片的复制表解码结果。不建议在此场景下手动连接DN解码。
串行解码
- force-binary:
- 针对系统函数pg_logical_slot_get_binary_changes和pg_logical_slot_peek_binary_changes:
- 针对系统函数pg_logical_slot_get_changes、pg_logical_slot_peek_changes和pg_logical_get_area_changes:
- 针对流式解码(仅连接DN时支持):
并行解码
- decode-style:
当enable-ddl-json-format参数值为true时,DDL的格式由enable-ddl-json-format控制,decode-style仅指定DML语句的解码格式;当enable-ddl-json-format参数值为false时,decode-style指定DML和DDL语句的解码格式。
取值范围:char型的字符'j'、't'或'b',分别代表json格式、text格式及二进制格式。
默认值:
- 没有指定decode-style:
针对复制槽插件类型为mppdb_decoding、sql_decoding,decode-style默认值为'b'即二进制格式解码。针对复制槽插件类型为parallel_binary_decoding、parallel_json_decoding、parallel_text_decoding,decode-style默认值分别为'b'、'j'、't',解码格式分别为二进制格式、json格式、text格式。
对于json格式和text格式解码,开启批量发送选项时的解码结果中,每条解码语句的前4字节组成的uint32代表该条语句总字节数(不包含该uint32类型占用的4字节,0代表本批次解码结束),8字节uint64代表相应lsn(begin对应first_lsn,commit对应end_lsn,其他场景对应该条语句的lsn)。
例如:以mppdb_decoding插件为例,当decode-style为b类型时,以二进制格式解码,结果如下:current_lsn: 0/CFE5C80 BEGIN CSN: 2357 first_lsn: 0/CFE5C80 current_lsn: 0/CFE5D40 INSERT INTO public.test1 new_tuple: {a[typid = 23]: "1", b[typid = 23]: "2"} current_lsn: 0/CFE5E68 COMMIT xid: 78108
当decode-style为j类型时,以json格式解码,结果如下:BEGIN CSN: 2358 first_lsn: 0/CFE6220 {"table_name":"public.test1","op_type":"INSERT","columns_name":["a","b"],"columns_type":["integer","integer"],"columns_val":["3","3"],"old_keys_name":[],"old_keys_type":[],"old_keys_val":[]} COMMIT XID: 78109
当decode-style为t类型时,以text格式解码,结果如下:BEGIN CSN: 2359 first_lsn: 0/CFE64D0 table public test1 INSERT: a[integer]:3 b[integer]:4 COMMIT XID: 78110
- 没有指定decode-style:
二进制格式编码规则如下所示:
- 前4字节代表接下来到语句级别分隔符字母P(不含)或者该批次结束符F(不含)的解码结果的总字节数,该值如果为0代表本批次解码结束。
- 接下来8字节uint64代表相应lsn(begin对应first_lsn,commit对应end_lsn,其他场景对应该条语句的lsn)。
- 接下来1字节的字母有5种B/C/I/U/D,分别代表begin/commit/insert/update/delete。
- 第3步字母为B时:
- 接下来的8字节uint64代表CSN。
- 接下来的8字节uint64代表first_lsn。
- 【该部分为可选项】接下来的1字节字母如果为T,则代表后面4字节uint32表示该事务commit时间戳长度,再后面等同于该长度的字符为时间戳字符串。
- 【该部分为可选项】接下来的1字节字母如果为N,则代表后面4字节uint32表示该事务用户名的长度,再后面等同于该长度的字符为事务的用户名字。
- 因为之后仍可能有解码语句,接下来会有1字节字母P或F作为语句间的分隔符,P代表本批次仍有解码的语句,F代表本批次解码完成。
- 第3步字母为C时:
- 【该部分为可选项】接下来1字节字母如果为X,则代表后面的8字节uint64表示xid。
- 【该部分为可选项】接下来的1字节字母如果为T,则代表后面4字节uint32表示时间戳长度,再后面等同于该长度的字符为时间戳字符串。
- 因为批量发送日志时,一个COMMIT日志解码之后可能仍有其他事务的解码结果,接下来的1字节字母如果为P则表示该批次仍需解码,如果为F则表示该批次解码结束。
- 第3步字母为I/U/D时:
- 接下来的2字节uint16代表schema名的长度。
- 按照上述长度读取schema名。
- 接下来的2字节uint16代表table名的长度。
- 按照上述长度读取table名。
- 【该部分为可选项】接下来1字节字母如果为N代表为新元组,如果为O代表为旧元组,这里先发送新元组。
- 接下来的2字节uint16代表该元组需要解码的列数,记为attrnum。
- 以下流程重复attrnum次。
- 接下来2字节uint16代表列名的长度。
- 按照上述长度读取列名。
- 接下来4字节uint32代表当前列类型的OID。
- 接下来4字节uint32代表当前列值(以字符串格式存储)的长度,如果为0xFFFFFFFF则表示NULL,如果为0则表示长度为0的字符串。
- 按照上述长度读取列值。
- 因为之后仍可能有解码语句,接下来的1字节字母如果为P则表示该批次仍需解码,如果为F则表示该批次解码结束。
- sending-batch:
取值范围:0或1的int型,默认值为0。
- 0:设为0时,表示逐条发送解码结果。
- 1:设为1时,表示解码结果累积到达1MB则批量发送解码结果。
开启批量发送的场景中,当解码格式为'j'或't'时,在原来的每条解码语句之前会附加一个uint32类型,表示本条解码结果长度(长度不包含当前的uint32类型),以及一个uint64类型,表示当前解码结果对应的lsn。
在CSN序解码(即output-order设置为1)场景下,批量发送仅限于单个事务内(即如果一个事务有多条较小的语句会采用批量发送),即不会使用批量发送功能在同一批次里发送多个事务,且BEGIN和COMMIT语句不会批量发送。