[FATAL] [lib.rs:482] ["refresh_buffer must not be called on CodedOutputStream create from slice"]

【TiDB 版本】v4.0.11

【问题描述】最近从TIDB中抽数据上云,有个任务总是在抽取大概1700W条记录,SIZE 2个G左右,运行5分钟左右,报TIKV timeout。查看TIKV 日志,发现TIKV有重启过的迹够用,看TIKV日志中有FATAL错误:

服务器日志中无OOM日志记录
相关TIKV完整日志如下:tikv.log.zip (2.3 MB)

我们分析一下日志

目前看下来是已知问题,TiKV 处单个响应大小超过 4GB 就会发生
https://github.com/tikv/tikv/issues/9012
本质问题是 :https://github.com/stepancheg/rust-protobuf/issues/530

目前暂时还没有修复,建议可以通过拆小请求的方式绕过这个问题。

rust-protobuf2 消息不能超过4G,这个我能理解。我不能理解的是一个简单的SELECT 查询场景,是在哪个环节,会拼出这么大的一条消息?有最大限制,就不能分拆成多条?(这个地方感觉肯定有优化空间)。即使有再多结果集只要内存够,也不至于死在这吧,求进一步解惑。

这个方便提供一下你们的 SELECT sql 语句以及对应的 explain 执行计划看下么?
还有目前重复执行这个 SQL 是不是还是会复现这个问题?

是必现,而且基本上导出这么多的量左右就会出错


执行计划如下:

从堆栈的信息看到的是 coprocessor response 返回的内容超过 4G 导致出现的问题,所以可能是查询的数据集中在某一个节点上导致的。
这个是否可以改写一下 SQL ,按批次获取数据看下还会有这个问题么。

是否有修改过 region-max-size,没有的话可以看下 TiKV 监控中 Server 下面的 Approximate Region Size 多大