逻辑解码内存管理
逻辑解码内存管理介绍
逻辑解码任务执行过程中,产生的逻辑日志以事务粒度按提交序发送。解码到提交日志前,事务产生的逻辑日志堆积在内存中。为了避免解码任务占用过多内存,逻辑解码模块对内存使用进行了限制,涉及单个事务内存、所有事务总内存、事务修改记录行数三个维度;解码过程中触发以上限制条件时,逻辑解码任务将会对内存态逻辑日志进行落盘,生成临时文件。临时文件解码该事务的提交日志时删除。
内存管理与落盘规则
- 逻辑解码任务内存管理规则
表1 逻辑解码任务内存管理规则 内存管理维度
配置方式
触发落盘规则
单个事务修改记录行数
max_changes_in_memory
GUC
单个事务修改记录的行数超过该阈值时,该事务落盘;默认值4096。
所有事务总内存
max-reorderbuffer-in-memory
GUC(通过logical_decode_options_default参数配置)
DRS
所有事务内存总和超过该阈值时,继续申请内存的事务落盘;默认值0表示不检查,取值范围[0, 100]。
单个事务内存
max-txn-in-memory
GUC(通过logical_decode_options_default参数配置)
DRS
单个事务内存超过该阈值时,该事务落盘;默认值0表示不检查,取值范围[0, 100]。
当父事务以上述三种方式触发落盘,该父事务下的子事务触发连带落盘。
- 逻辑日志临时文件生成规则
事务以上述三个维度触发落盘时,事务数据所分布的块分别产生一个落盘文件。如下图所示:事务A产生的XLOG日志分布在block1、block3、block4上,共计产生三个临时文件。
图2 逻辑日志临时文件生成规则
事务临时落盘文件数量估算:临时落盘文件数量与子事务个数、事务执行时长、XLOG产生速率成正比。
考虑到子事务对性能的影响,建议子事务数量控制在1000以内。
- 事务磁盘IO时间开销评估公式
事务磁盘读写时间开销 = 临时落盘文件数量 *(2 * 网络时延 + 单次磁盘读时延 + 单次磁盘写时延)* K
系数K为重复读写系数,单个落盘文件可能经历多次读写,K略高于1。
典型排查场景
- 示例场景一:磁盘IO时延高,导致解码任务临时落盘文件读写耗时长,解码性能劣化。
- 场景类型:海量父子事务。
- 逻辑解码GUC参数配置:
- max_changes_in_memory = 4096。
- 逻辑解码任务启动参数配置:
- max-reorderbuffer-in-memory = 0(代表不检查该阈值)。
- max-txn-in-memory = 0(代表不检查该阈值)。
- 业务模型:
- 父事务:修改记录行数4098,单行数据大小1KB。
- 子事务:子事务数量100W;单个子事务记录行数10,单行数据大小1KB。
- 父子事务总数据量:10GB。
- 事务执行时长:100s。
- XLOG产生速率:30MB/s。
- XLOG块大小:16KB。
- 网络时延:使用远端存储,读写时延2ms。
- 场景分析:
- 是否触发落盘:当前没有配置内存维度的落盘参数,max_changes_in_memory=4096,业务中父事务记录行数量超过该阈值,父事务触发落盘,子事务虽不超过阈值,但由父事务连带落盘,因此产生海量临时文件。
- 事务磁盘读写时间开销估算:(100s * 30MB/s % 16KB)* (2 * 2ms + 0ms + 0ms)* 1 = 768s。
- 开发建议:
- 存在海量父子事务场景时,需评估当前内存管控阈值下,是否触发落盘;当涉及大量数据落盘时,需要评估网络时延和磁盘读写时延对逻辑解码性能的影响。
- 示例场景二:海量父子事务,未合理配置内存管控阈值,导致逻辑解码内存开销大。
- 场景类型:海量父子事务。
- 逻辑解码GUC参数配置:
- max_changes_in_memory = 4096。
- 逻辑解码任务启动参数配置:
- max-reorderbuffer-in-memory = 0(代表不检查该阈值)。
- max-txn-in-memory = 0(代表不检查该阈值)。
- 业务模型:
- 父事务:修改记录行数1,单行数据大小1KB。
- 子事务:子事务数量100W;单个子事务记录行数10,单行数据大小1KB。
- 父子事务总数据量:10GB。
- 场景分析:
- 是否触发落盘:当前没有配置内存维度的落盘参数,max_changes_in_memory=4096,业务中父事务和子事务记录行数量均不超过该阈值,因此不触发落盘。
- 事务内存开销估算:1 * 1KB + 100W * 10 * 1KB = 10GB。
- 开发建议:
- 存在海量父子事务场景时,建议配置max-reorderbuffer-in-memory 和max-txn-in-memory 参数,并且同时配置max_files_per_process和操作系统文件句柄阈值,以调大句柄数量限制,避免逻辑解码无可用文件句柄。
- 示例场景三:高并发场景下,未合理配置内存管控阈值,导致逻辑解码内存开销大。
- 场景类型:高并发。
- 逻辑解码GUC参数配置:
- max_changes_in_memory = 4096。
- 逻辑解码任务启动参数配置:
- max-reorderbuffer-in-memory = 0(代表不检查该阈值)。
- max-txn-in-memory = 0(代表不检查该阈值)。
- 业务模型:
- 事务修改记录行数4K,单行数据大小10KB。
- 并发连接数量:1K。
- 场景分析:
- 是否触发落盘:当前没有配置内存维度的落盘参数,max_changes_in_memory=4096,业务中事务记录行数量未超过该阈值,因此该事务逻辑日志存放在内存中。
- 事务内存开销估算 :
- 1K * 4K * 10KB = 40GB。
- 开发建议:
- 在高并发场景下,建议配置max-reorderbuffer-in-memory,并且同时配置max_files_per_process和操作系统文件句柄阈值,以调大句柄数量限制,避免逻辑解码无可用文件句柄。