YashanDB|swap空间暴涨导致报错?group
【问题分类】SQL执行异常 / 虚拟内存异常 【关键词】swap 空间、group_concat、VM 内存、YAS-02025、YAS-00103
问题现象
某客户在使用 group_concat 函数进行数据聚合时,数据库 swap 空间迅速飙升,最终触发系统报错。
测试示例如下:
代码语言:javascript代码运行次数:0运行复制select c1,c2,group_concat(c3) value_list
from tmp1
where c4 is null
group by c1,c2
having to_char(group_concat(c3)) = '15395169080,15395169080';
原始数据量仅 200M
查询执行过程中 swap 空间不断扩大,最终达到 128G+ 后系统报错:
代码语言:javascript代码运行次数:0运行复制YAS-02025 no free space in virtual memory pool
YAS-00103 no free block in application pool
其他类似 SQL 也出现不同程度的虚拟内存飙升问题。
初步排查
对比发现:
使用 listagg 函数时资源占用可控,但有字符长度截断风险(超过 8000 字节会被截断)
使用 group_concat 则会持续拉高虚拟内存,直至 swap 爆满
原因分析:group_concat 返回 LOB 类型,每组独立申请内存
经源码分析确认:
group_concat 每处理一个分组时,都会申请一个 LOB 对象空间
每个 LOB 默认申请约 88K 的 VM 内存
测试数据共 499 万分组,累计申请内存 ≈ 304G
流程摘要如下:
代码语言:javascript代码运行次数:0运行复制group_concat → anlLobAppend → vmAllocAndOpen → doVmAlloc → vmAllocSwap → 扩展VM空间
内存分配细节:
每次申请单元块数(unitBlocks)为 8
每次扩展文件空间 64M,频繁写入 swap 文件
导致 swap 空间快速膨胀,最终触发内存不足错误
规避建议
1.避免大分组数量使用 group_concat 尽量不要对超大数据量进行分组聚合,尤其是在 group_concat 下的组合字段非常长的情况下。
2.可使用 listagg 替代 group_concat(有长度限制) 如果聚合字段内容较短,可以使用如下 SQL 替代:
代码语言:javascript代码运行次数:0运行复制select c1, c2, listagg(c3) value_list
from tmp1
where c4 is null
group by c1, c2;
注意:listagg 有最大长度限制,超过将被截断。
3.优化 LOB 内存管理机制(后续版本建议) 建议升级至后续版本,或关注官方对 group_concat 的内存优化发布进展。
错误参考信息
YAS-02025: 无法为虚拟内存池分配空间
YAS-00103: 应用内存池中无可用块
发布评论