暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

GaussDB利用函数实现查询报错不中断的需求

原创 执剑者 2023-08-08
495

近期,项目上有一个统计表大小的需求,要求查出多个schema下所有表的当前使用容量,并且在查询过程中不能报错中断。根据需求编写SQL语句如下:

select n.nspname, c.relname, pg_table_size(c.oid) as tab_size 
 from pg_class c 
 join pg_namespace n 
  on c.relnamespace = n.oid 
 and n.nspname in ('schem1', 'schem2', 'schem3' ……) 
where c.relkind = 'r' 
 and c.oid > 16384 
order by tab_size desc;

上述语句在小业务量的数据库中查询没有问题,但是当给定的schema多达上千个、表的数量约百万个、业务增删改查频繁、数据量极大的情况下,该查询往往会持续很长时间。由于在查询开始时,函数pg_table_size会根据语句条件生成一个待统计的表清单,此时如果在查询过程中某张表被删除,查询语句则会报错中断。

除此之外,在查询过程中可能还会发生其他报错,例如节点异常、主备切换、事务同步延迟等,一旦语句中断,前面统计出来的结果都会回滚。众所周知,在PB级的GaussDB集群上统计所有表大小,其代价是巨大的,因此我们希望整个查询进程不会因为个别报错发生中断,而个别表因报错未能正常统计也是可以接受的。

在这个需求中,我们可以使用GaussDB函数中的exception分支来捕获错误语句,当统计到某张表时数据库发生报错,语句回滚,但不中断,跳过错误后继续执行。自定义函数语句如下:

create or replace function func_get_tablesize(tab_oid oid,out return_code text)
returns text 
language plpgsql 
as $$ 
declare v_sql text; 
       ts text;
begin 
 v_sql := 'select pg_table_size('||tab_oid||')'; 
 execute immediate v_sql into ts; 
 if ts is null 
  then return_code :=-1; 
 else 
  return ts; 
end if;
exception 
 when others then 
  return_code :=-1;
end$$;

上述自定义函数func_get_tablesize将系统函数pg_table_size进行了封装,当在统计某张表时集群发生报错或者该表大小为空,则返回-1。

使用函数func_get_tablesize替换掉统计表大小语句中的pg_table_size后,即可实现查询报错不中断的需求。

最后修改时间:2023-08-08 11:33:01
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论