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

逻辑解码选项

  • 通用选项:
    • include-xids:

      解码出的data列是否包含xid信息。

      取值范围:0或1,默认值为1。

      • 0:设为0时,解码出的data列不包含xid信息。
      • 1:设为1时,解码出的data列包含xid信息。
    • skip-empty-xacts:

      解码时是否忽略空事务信息。

      取值范围:0或1,默认值为0。

      • 0:设为0时,解码时不忽略空事务信息。
      • 1:设为1时,解码时会忽略空事务信息。
    • include-timestamp:

      解码信息是否包含commit时间戳。

      取值范围:0或1,默认值为0。

      • 0:设为0时,解码信息不包含commit时间戳。
      • 1:设为1时,解码信息包含commit时间戳。
    • only-local:

      是否仅解码本地日志。

      取值范围:0或1,默认值为1。

      • 0:设为0时,解码非本地日志和本地日志。
      • 1:设为1时,仅解码本地日志。
    • force-binary:

      是否以二进制格式输出解码结果。

      取值范围:0,默认值为0。

      • 0:设为0时,以文本格式输出解码结果。
    • white-table-list:

      白名单参数,包含需要进行解码的schema和表名。

      取值范围:包含白名单中表名的字符串,不同的表以','为分隔符进行隔离;使用'*'来模糊匹配所有情况;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,即不开启此种管控。

    • max-reorderbuffer-in-memory

      内存管控参数,单位为GB,拼接-发送线程中正在拼接的事务总内存(包含缓存)大于该值则对当前解码事务进行落盘。

      取值范围:0~100的整型,默认值为0,即不开启此种管控。

    • include-user:

      事务的BEGIN逻辑日志是否输出事务的用户名。事务的用户名特指授权用户——执行事务对应会话的登录用户,它在事务的整个执行过程中不会发生变化。

      取值范围:0或1,默认值为0。

      • 0:设为0时,事物的BEGIN逻辑日志不输出事务的用户名。
      • 1:设为1时,事物的BEGIN逻辑日志输出事务的用户名。
    • exclude-userids:

      黑名单用户的OID参数。

      取值范围:字符串类型,指定黑名单用户的OID,多个OID通过','分隔,不校验用户OID是否存在。

    • exclude-users:

      黑名单用户的名称列表。

      取值范围:字符串类型,指定黑名单用户名,通过','分隔,不校验用户名是否存在。

    • dynamic-resolution:

      是否动态解析黑名单用户名。

      取值范围:0或1,默认值为1。

      • 0:设为0时,当解码观测到黑名单exclude-users中用户不存在时将会报错并退出逻辑解码。
      • 1:设为1时,当解码观测到黑名单exclude-users中用户不存在时继续解码。
    • standby-connection:

      仅流式解码设置,是否仅限制备机解码。

      取值范围:bool型,默认值为false。

      • true:设为true时,仅允许连接备机解码,连接主机解码时会报错退出。
      • false:设为false时,不做限制,允许连接主机或备机解码。
    • sender-timeout:

      仅流式解码设置,内核与客户端的心跳超时阈值。当该时间段内没有收到客户端任何消息,逻辑解码将主动停止,并断开和客户端的连接。单位为毫秒(ms)。

      取值范围:0~2147483647的int型,默认值取决于GUC参数logical_sender_timeout的配置值。

    • change-log-max-len:

      逻辑日志长度上限参数。

      取值范围:1~65535, 默认值为4096。

      超过上限会销毁重新分配内存保存。过长会增加内存占用,过短会频繁触发内存申请和释放的操作。

    • max-decode-to-sender-cache-num:

      发送解码日志的缓存阈值大小。

      取值范围:1~65535,默认值为4096。

      不超过这个阈值时暂时不发送,超过时才发送。减少频繁发送的负担。

    • enable-heartbeat:

      仅流式解码设置,是否输出心跳日志。

      取值范围:bool型,默认值为false。

      • true:设为true时,输出心跳日志。
      • false:设为false时,不输出心跳日志。

      若开启心跳日志选项,此处说明心跳日志如何解析:二进制格式首先是字符'h'表示是消息是心跳日志,之后是心跳日志内容内容,分别是8字节uint64代表LSN,表示发送心跳逻辑日志时读取的WAL日志结束位置;8字节uint64代表LSN,表示发送心跳逻辑日志时刻已经落盘的WAL日志的位置;8字节int64代表时间戳(从1970年1月1日开始),表示最新解码到的事务日志或检查点日志的产生时间戳。关于消息结束符:如果是二进制格式则为字符'F',如果格式为text或者json且为批量发送则结束符为0,否则没有结束符。具体解析见下图:

    • parallel-decode-num:

      仅流式解码设置有效,并行解码的Decoder线程数量;系统函数调用场景下此选项无效,仅校验取值范围。

      取值范围:取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列值为非零值时可使用该方式,否则报错。
    • auto-advance:

      仅流式解码设置有效,是否允许自主推进逻辑复制槽。

      取值范围:boolean型,默认值为false。

      • true:设为true时,在已发送日志都被确认推进且没有待发送事务时,推进逻辑复制槽到当前解码位置。
      • false:设为false时,完全交由复制业务调用日志确认接口推进逻辑复制槽。
    • skip-generated-columns:

      逻辑解码控制参数,用于跳过生成列的输出。对UPDATE和DELETE的旧元组无效,相应元组始终会输出生成列。

      取值范围:boolean型,默认值为false/off。

      • true/on:表示不输出生成列的解码结果。
      • false/off:表示输出生成列的解码结果。
  • 并行解码:
    以下配置选项仅限流式解码设置。
    • decode-style:

      指定解码格式。

      取值范围:char型的字符'j'、't'或'b',分别代表json格式,text格式及二进制格式。默认值为'b'即二进制格式解码。

      对于json格式和text格式解码,开启批量发送选项时的解码结果中,每条解码语句的前4字节组成的uint32代表该条语句总字节数(不包含该uint32类型占用的4字节,0代表本批次解码结束),8字节uint64代表相应lsn(begin对应first_lsn,commit对应end_lsn,其他场景对应该条语句的lsn)。

    二进制格式编码规则如下所示:

    1. 前4字节代表接下来到语句级别分隔符字母P(不含)或者该批次结束符F(不含)的解码结果的总字节数,该值如果为0代表本批次解码结束。
    2. 接下来8字节uint64代表相应lsn(begin对应first_lsn,commit对应end_lsn,其他场景对应该条语句的lsn)。
    3. 接下来1字节的字母有5种B/C/I/U/D,分别代表begin/commit/insert/update/delete。
    4. 第3步字母为B时。
      1. 接下来的8字节uint64代表CSN。
      2. 接下来的8字节uint64代表first_lsn。
      3. 【该部分为可选项】接下来的1字节字母如果为T,则代表后面4字节uint32表示该事务commit时间戳长度,再后面等同于该长度的字符为时间戳字符串。
      4. 【该部分为可选项】接下来的1字节字母如果为N,则代表后面4字节uint32表示该事务用户名的长度,再后面等同于该长度的字符为事务的用户名字。
      5. 因为之后仍可能有解码语句,接下来会有1字节字母P或F作为语句间的分隔符,P代表本批次仍有解码的语句,F代表本批次完成。
    5. 3步字母为C时:
      1. 【该部分为可选项】接下来1字节字母如果为X,则代表后面的8字节uint64表示xid。
      2. 【该部分为可选项】接下来的1字节字母如果为T,则代表后面4字节uint32表示时间戳长度,再后面等同于该长度的字符为时间戳字符串。
      3. 因为批量发送日志时,一个COMMIT日志解码之后可能仍有其他事务的解码结果,接下来的1字节字母如果为P则表示该批次仍需解码,如果为F则表示该批次解码结束。
    6. 3步字母为I/U/D时:
      1. 接下来的2字节uint16代表schema名的长度。
      2. 按照上述长度读取schema名。
      3. 接下来的2字节uint16代表table名的长度。
      4. 按照上述长度读取table名。
      5. 【该部分为可选项】接下来1字符字母如果为N代表为新元组,如果为O代表为旧元组,这里先发送新元组。
        1. 接下来的2字节uint16代表该元组需要解码的列数,记为attrnum。
        2. 以下流程重复attrnum次。
          1. 接下来2字节uint16代表列名的长度。
          2. 按照上述长度读取列名。
          3. 接下来4字节uint32代表当前列类型的Oid。
          4. 接下来4字节uint32代表当前列的值(以字符串格式存储)的长度,如果为0xFFFFFFFF则表示NULL,如果为0则表示长度为0的字符串。
          5. 按照上述长度读取列值。
      6. 因为之后仍可能有解码语句,接下来的1字节字母如果为P则表示该批次仍需解码,如果为F则表示该批次解码结束。
    • sending-batch:

      指定是否批量发送。

      取值范围:0或1的int型,默认值为0。

      • 0:设为0时,表示逐条发送解码结果。
      • 1:设为1时,表示解码结果累积到达1MB则批量发送解码结果。

      开启批量发送的场景中,当解码格式为'j'或't'时,在原来的每条解码语句之前会附加一个uint32类型,表示本条解码结果长度(长度不包含当前的uint32类型),以及一个uint64类型,表示当前解码结果对应的lsn。

      在使用CSN顺序输出解码结果的场景下,批量发送仅限于单个事务内(即如果一个事务有多条较小的语句会采用批量发送),不会使用批量发送功能在同一批次里发送多个事务。

    • parallel-queue-size:

      指定并行逻辑解码线程间进行交互的队列长度。

      取值范围:2~1024的int型,且必须为2的整数幂,默认值为128。

      队列长度和解码过程的内存使用量正相关。

    • logical-reader-bind-cpu:

      reader 线程绑定cpu核号的参数。

      取值范围:-1~65535,不使用该参数则为不绑核。

      默认-1,为不绑核。-1不可手动设置,核号应确保在机器总逻辑核数以内,不然会返回报错。多个线程绑定同一个核会导致该核负担加重,从而导致性能下降。

    • logical-decoder-bind-cpu-index:

      逻辑解码线程绑定cpu核号的参数。

      取值范围: -1~65535,不使用该参数则为不绑核。

      默认 -1,不绑核。-1不可手动设置,核号应确保在机器总逻辑核数以内且小于 [cpu核数 - 并行逻辑解码数],不然会返回报错。

      从给定的核号参数开始,新拉起的线程会依次递增加一。

      多个线程绑定同一个核会导致该核负担加重,从而导致性能下降。

      GaussDB在进行逻辑解码和日志回放时,会占用大量的CPU资源,相关线程如Walwriter、WalSender、WALreceiver、pageredo就处于性能瓶颈,如果能将这些线程运行绑定在固定的CPU上运行,可以减少因操作系统调度线程频繁切换CPU,导致缓存未命中带来的性能开销,从而提高流程处理速度,如用户场景有性能需求,可根据以下的绑核样例进行配置优化。

      • 参数样例:
        1. walwriter_cpu_bind=1
        2. walwriteraux_bind_cpu=2
        3. wal_receiver_bind_cpu=4
        4. wal_rec_writer_bind_cpu=5
        5. wal_sender_bind_cpu_attr='cpuorderbind:7-14'
        6. redo_bind_cpu_attr='cpuorderbind:16-19'
        7. logical-reader-bind-cpu=20
        8. logical-decoder-bind-cpu-index=21
      • 样例中1.2.3.4.5.6通过GUC工具设置,使用指令如

        gs_guc set -Z datanode -N all -I all -c “walwriter_cpu_bind=1”。

        样例中7.8通过JDBC客户端发起解码请求时添加。

      • 样例中如walwriter_cpu_bind=1是限定该线程在1号CPU上运行。

        cpuorderbind:7-14意为拉起的每个线程依次绑定7号到14号CPU,如果范围内的CPU用完,则新拉起的线程不参与绑核。

        logical-decoder-bind-cpu-index意为拉起的线程从21号CPU依次开始绑定,后续拉起的线程分别绑定21、22、23,依次类推。

      • 绑核的原则是一个线程占用一个CPU,样例中的GUC参数说明可参考管理员指南。
      • 不恰当的绑核,例如将多个线程绑定在一个CPU上很有可能带来性能劣化。
      • 可以通过lscpu指令查看“CPU(s):”得知自己环境的CPU逻辑核心数。

      CPU逻辑核心数低于36则不建议使用此套绑核策略,此时建议使用默认配置(不进行参数设置)。