以下提供的sql,以及报错信息中的IP、端口、PID均为称述本问题的测试样例。

具体报错:

psql:test.sql:1: ERROR:  function cannot execute on a QE slice because it accesses relation "demo_gp_table"  (seg1 slice1 000.000.000.00:00000 pid=1234567)
CONTEXT:  SQL statement "select field2 into field from demo_gp_table
    where field1 = param"
PL/pgSQL function demo_gp_func (character varying) line 1 at SQL statement
ANALYZE

问题原因:

GP数据库中,函数demo_gp_func在查询切片(QE slice)上访问了一个无法在该查询切片上直接访问的数据表demo_gp_table。并且该报错信息提供了发生错误的查询切片的具体信息,包括它所在的段(seg1),切片编号(slice1),服务器的IP和端口,以及进程ID。

注:环境中QE slice信息查询,先切admin用户su gpadmin,gpstate -s查询具体信息。

sql样例:

(1)被调用方sql,数据表创建。

drop table if exists demo_gp_table;
create table demo_gp_table (
field1       varchar(16),
field2       integer
) distributed by (field1);

insert into demo_gp_table (field1,field2) values ('field1', 2);

(2)函数sql。

drop function demo_gp_func (param varchar(16));
create or replace function demo_gp_func (param varchar(16))
returns int
as $$
declare field decimal(10, 2);
begin
    select field2 into field from demo_gp_table
    where field1 = param;
   
    if field > 1  then
        return 11111111;
    else
        return 0;
    end if;
end;
$$ language plpgsql;

(3)调用方sql。

select demo_gp_func('field1') as test_field;

一、前言

 1、GP数据库介绍。

Greenplum数据库是一种基于开源PostgreSQL数据库的先进的大规模并行处理(MPP)数据库管理系统。它专为处理大规模数据集而设计,非常适合于数据仓库、大规模数据分析和商业智能应用。以下是Greenplum数据库的详细介绍:

核心特性
(1)大规模并行处理(MPP):Greenplum数据库采用MPP架构,通过将数据分布在多个服务器节点上并行处理,实现了高速查询和数据分析。
(2)数据压缩:Greenplum数据库支持高效的数据压缩技术,可以显著减少存储需求并提高I/O效率。
(3)列式存储:除了传统的行式存储,Greenplum还支持列式存储,这对于分析查询特别有利,因为它可以大大减少需要读取的数据量。
(4)事务处理:作为一个基于PostgreSQL的数据库,Greenplum支持完整的ACID事务处理。
(5)容错和高可用性:Greenplum数据库支持数据冗余和自动故障转移,确保了系统的高可用性。
架构
(1)Master节点:控制查询的分配和执行,并协调所有Segment节点。Master节点还存储系统目录和元数据。
(2)Segment节点:存储实际的数据,并执行查询的并行部分。每个Segment拥有数据的一部分,所有Segment共同构成完整的数据集。
使用场景
(1)数据仓库:用于存储大量历史数据,支持复杂的查询和分析。
商业智能(BI):支持实时和批量的报告生成,帮助用户做出数据驱动的决策。
(2)大数据分析:适用于处理PB级别的大数据集,进行复杂的数据挖掘和分析。
主要优势
(1)高性能:通过并行处理和优化查询,Greenplum能够快速处理大量数据。
(2)可扩展性:可以轻松添加更多的Segment节点来扩展系统的处理能力和存储容量。
(3)成本效益:基于开源技术,Greenplum提供了相对较低的总拥有成本。
管理和监控
Greenplum数据库提供了管理和监控工具,如Greenplum Command Center,用于监控系统性能、执行管理任务和优化查询。

2、关于QE slice上无法访问数据表的问题。

目前仅识别到函数访问数据表有问题,sql调用数据表正常。

(1)函数访问:在Greenplum数据库中定义一个函数并执行它时,数据库可能需要在所有切片(segments)上执行这个函数。如果函数中包含的查询需要跨切片访问数据(即数据不在同一个切片上),Greenplum会尝试执行数据移动(Motion操作)来满足查询需求。如果这种数据移动不被允许或不能执行,就会导致错误(本篇报错)。
(2)SQL调用:直接执行SQL语句时,数据库优化器可以更好地控制查询的执行计划。它可能会决定在主节点master上执行整个查询,或者只在一个或几个切片上执行,从而避免了跨切片的数据移动。此外,优化器可能会选择不同的执行路径,如使用哈希聚合而不是排序聚合,这可能导致不需要跨切片数据移动。

二、解决方案

1、分布式复制策略。

创建数据表demo_gp_table,插入数据后,执行分布式复制策略,将此数据表分别复制到所有segment上,使得无论函数位于哪个segment,都可调用数据表。

alter table demo_gp_table set distributed replicated;

(1)数据均匀分布:由于每个节点都拥有完整的表数据,因此查询时不需要进行数据重分布,这对于小表或经常需要全表扫描的表来说可能是有益的。
(2)存储空间:这种策略会增加存储需求,因为每个节点都会存储表的所有数据。
(3)数据更新:对复制表的更新操作需要在所有节点上执行,可能会增加写入操作的复杂性和时间。

综上,分布式复制策略仅适用于小表或需要频繁进行全表扫描的表,对于而对于大表或写入操作频繁的表,可能会增加写入操作的复杂性和时间,应该采取以下方案。

2、使函数在主节点master上执行。

将函数demo_gp_func声明到master上执行,此处存有数据库的元数据,使得函数调用不会报错。

drop function demo_gp_func (param varchar(16));
create or replace function demo_gp_func (param varchar(16))
returns int
as $$
declare field decimal(10, 2);
begin
    select field2 into field from demo_gp_table
    where field1 = param;
   
    if field > 1  then
        return 11111111;
    else
        return 0;
    end if;
end;
$$ language plpgsql
execute on master;

(1)系统管理:Master节点负责整个Greenplum数据库系统的管理。它处理所有的外部连接,并协调所有的数据库操作。
(2)查询解析和优化:当客户端提交查询时,Master节点负责解析SQL语句,生成查询计划,并将查询计划优化后发送到各个Segment节点执行。
(3)元数据管理:Master节点存储数据库的元数据,包括表和索引的定义、权限信息、系统配置参数等。
(4)事务管理:Master节点负责事务的协调,确保分布式事务的原子性和一致性。
(5)数据分发:在创建表或插入数据时,Master节点会根据表的分布策略将数据行分发到相应的Segment节点。

三、总结

在项目中遇到的这个问题,关于GP数据库其他特性还有待挖掘。对于此问题,由于我使用的数据表数据量小,所以采取了分布式复制策略,解决了此问题。在复现此问题时,本来想着写个shell脚本调用sql,但是sql执行每次都在主节点master上,导致问题无法复现,并且数据库的segment不能连接,只能拿出原本项目代码找多节点测试环境进行复现,并验证解决方案,然后用样例整理文档。感叹有时候复现问题比解决问题更难。

简单小记,相互学习!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐