【YashanDB知识库】swap空间使用超大报错

问题描述

问题单

使用GROUP_CONCAT函数时,数据库swap表空间上涨厉害

测试用例

drop table tmp1;
create table tmp1(c1 int,c2 double,c3 varchar(500),c4 int);
 
begin
for i in 1 .. 4994196 loop
insert into tmp1 select random()*100000000,random()*5000000,'hello world test xxxxxiio','' from dual;
end loop;
commit;
end;
/
 
select c1,c2,LISTAGG(c3) value_list from tmp1 where c4 is null group by c1,c2 having to_char(LISTAGG(c3)) = '15395169080,15395169080';
-- 能出结果,(swap空间590M)
 
源表数据2百多M,这个group_concat sql使用1百多G swap空间还不够
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';
-- 出不来结果,swap空间越来越大,(直到128.063G,报错退出)
YAS-02025 no free space in virtual memory pool
 
select c1,c2,group_concat(c3) value_list from tmp1 where c4 is null group by c1,c2 ;
-- 能出结果,swap空间一直增大(直到33.188G,报错退出)
YAS-00103 no free block in application pool
 
select c1,c2,group_concat(c3) value_list from tmp1 group by c1,c2
-- 能出结果,swap空间一直增大(直到33.188G,报错退出)
YAS-00103 no free block in application pool
 
select c1,c2 from tmp1 group by c1,c2 ;
-- 能出结果,swap空间到一定大小停下(128M)4994196行
 
select group_concat(c3) value_list from tmp1 ;
-- 能出结果,swap空间一定大小停下(252M)
 
select * from (
select c1,c2,group_concat(c3) value_list from tmp1 where C4 is null group by c1,c2
) where to_char(value_list) = '15395169080,15395169080';

结论

  • 23.2版本尝试该问题,现象相同。

  • 确认内置函数group_concat,该函数返回lob类型,导致vm大量增长。该接口需要优化。

规避方法

可以使用listagg替换group_concat。但是如果超过8000个字节,文本会被截断。

分析代码发现,group_concat返回的是lob类型,每一个分组都会申请一个lob空间,每一个lob空间都是88K大小,测试例子有4994196分组,所以它就会申请49941968*8K大小空vm空间,大概是304.8G大小,才能跑完,导致的问题。

代码分析如下

group_concat申请VM空间流程

调用流程

group_concat

group_concat返回lob类型,每一个分组都会申请一个lob空间

string转lob时,tmpVar是源表字段数据,调用anlLobAppend给value->vLob申请lob对象空间

VM空间申请

调用流程

vmAllocAndOpen
doVmAlloc
vmAllocSwap
vmAllocExtend
spcAllocExtent
doAllocExt
spcAllocDataFileExt

申请空间:

如上unitBlocks = 8,申请8个块的空间

如下:4是swap的表文件id

VM空间扩展

调用流程

spcAllocExtent
doExtendExt
spcExtendDatafile
dfExtend
dbExtendDevice
dbBuildDeviceBlocks
writeDevice
writeFile
write

一次扩大,写64M空间,8192*8192

posted @ 2024-07-17 14:54  YashanDB  阅读(6)  评论(0编辑  收藏  举报