【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