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

GP统计分区表数据大小异常问题

叶同学专栏 2021-04-16
894

问题描述

在生产环境中,遇到这样的一个问题,用函数pg_relation_size统计分区表的各个子分区表时,直接统计出来的数据是正确的,但关联自己定义的配置表后,统计出来的结果就有问题,GP4和GP6版本都有这情况出现

场景复现

建分区表并插入数据

drop table tmp;

create table public.tmp(
id int
,par text
,info text
distributed by (id
PARTITION BY LIST(par) 
          (
          PARTITION p00 VALUES('00'), 
          PARTITION p01 VALUES('01'), 
          PARTITION p02 VALUES('02'), 
          PARTITION p03 VALUES('03'), 
          PARTITION p04 VALUES('04'), 
          PARTITION p05 VALUES('05'), 
          PARTITION p06 VALUES('06'), 
          PARTITION p07 VALUES('07'), 
          PARTITION p08 VALUES('08'), 
          PARTITION p09 VALUES('09')
          );

insert into public.tmp
select generate_series(1,10000),'00','yejf';

建配置表并插入数据

drop table public.cfg;
create table public.cfg(schemaname text,tablename text);
insert into public.cfg values('public','tmp');

不关联配置表时统计结果正常

select  pg_relation_size(p.partitionschemaname||'.'||p.partitiontablename) data_size
,p.partitionschemaname||'.'||p.partitiontablename tablename
from pg_partitions p 
--join   public.cfg tb   on p.schemaname=tb.schemaname and p.tablename=tb.tablename
where p.schemaname||'.'||p.tablename='public.tmp';

结果数据

2097152;"public.tmp_1_prt_p00"

关联配置表时统计结果异常

select  pg_relation_size(p.partitionschemaname||'.'||p.partitiontablename) data_size
,p.partitionschemaname||'.'||p.partitiontablename tablename
from pg_partitions p 
join   public.cfg tb   on p.schemaname=tb.schemaname and p.tablename=tb.tablename
where p.schemaname||'.'||p.tablename='public.tmp';

结果数据

32768;"public.tmp_1_prt_p00"

原因是pg_relation_size跑到计算节点上执行了,这样的话,只取到了一个计算节点实例的表尺寸数据,这问题在GP6之前的版本都没有好的办法解决,只能改写sql,确保函数在master上执行,而不是下发执行。

在GP6版本中,可以对表public.cfg建replicated表,结合gp_dist_random函数,就可以确保函数在所有实例上被执行,数据再进行分组汇总统计即可得到正确的结果。代码如下

drop table public.cfg;
create table public.cfg(schemaname text,tablename text)
DISTRIBUTED REPLICATED;
insert into public.cfg values('public','tmp');

统计结果

select tablename,sum(data_size)
from(
select  pg_relation_size(p.partitionschemaname||'.'||p.partitiontablename) data_size
       ,p.partitionschemaname||'.'||p.partitiontablename tablename
from pg_partitions p 
join  gp_dist_random('public.cfg') tb  on p.schemaname=tb.schemaname and p.tablename=tb.tablename
where p.schemaname||'.'||p.tablename='public.tmp'
)t
group by tablename;
--
2097152;"public.tmp_1_prt_p00"


文章转载自叶同学专栏,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论