postgis在postgres-xl上使用出错

问题1

插件 postgis--2.4.5 在 postgres-xl-10alpha2 使用,执行命令"create extension postgis",

在内部执行sql文件内容的过程中,在执行insert into spatial_ref_sys 操作 报 spatial_ref_sys 视图不存在。

分析发现视图spatial_ref_sys 是在sql文件前面创建的,为什么后面执行插入数据报不存在呢?

原因分析

create view 只在coordinator上创建,而不在datanode 上创建。

这样如果创建的函数的相关内容包含视图则会无法创建。

示例:

create table tx1(id int);

create view v1 as select id from tx1;

CREATE OR REPLACE FUNCTION ADDN(a INT,b INT) RETURNS boolean AS

$$

SELECT COALESCE((select true from v1), false)

$$ LANGUAGE 'sql' STABLE

COST 100;

 

ERROR: 42P01: relation "v1" does not exist

LOCATION: pgxc_node_report_error, execRemote.c:6413

那应该是这个问题了,问题修改也比较清晰,在coordinator上执行create view时会现在本地执行,然后再根据情况看是不是需要发送到远端(datanode)上执行(直接调用相应的函数将plantree发送过去), 那么这个view 应该没去执行该去远端执行的操作。

该问题修改:

1. 应该修改的位置在函数 ProcessUtilityPost 中,将create view对应的代码下面的 要去的远端节点只在coordinator上执行改为在所有节点上执行即可。

2.需要修改drop view/alter view 对应的远端节点,需要修改函数 ExecUtilityFindNodesRelkind

 

这个是我发给pgxl bug邮件列表的内容:

http://lists.postgres-xl.org/pipermail/postgres-xl-bugs-postgres-xl.org/2018-November/000491.html

根据回复在最新的postgres-xl版本已经解决了,我的邮箱却收不到回复邮件,有点奇怪,只能在归档路径中查看了, 更新了xl代码确实已经修改了。

问题2

postgis--2.4.0版本在postgres-xl上执行“create extension postgis” 报:

db1=# create extension postgis;

ERROR: Fail to process utility query on remote node.

DETAIL: ERROR: type "gidx" does not exist

 

将问题简化为

CREATE OR REPLACE FUNCTION gidx_in(cstring)

RETURNS gidx

AS '$libdir/postgis-2.4','gidx_in'

LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

 

CREATE OR REPLACE FUNCTION gidx_out(gidx)

RETURNS cstring

AS '$libdir/postgis-2.4','gidx_out'

LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

 

CREATE OR REPLACE FUNCTION overlaps_geog(gidx, gidx)

RETURNS boolean

AS '$libdir/postgis-2.4','gserialized_gidx_gidx_overlaps'

LANGUAGE 'c' IMMUTABLE STRICT;

 

CREATE TYPE gidx (

internallength = variable,

input = gidx_in,

output = gidx_out,

storage = plain,

alignment = double

);

 

do language plpgsql $$

declare

begin

IF NOT EXISTS(SELECT 1 from pg_operator WHERE oprname = '&&' AND

oprleft::regtype::text LIKE '%gidx') THEN

CREATE OPERATOR && (

LEFTARG = gidx,

RIGHTARG = gidx,

PROCEDURE = overlaps_geog,

COMMUTATOR = &&

);

end if;

end $$;

 

将上面的内容放在文件编译生成的share文件夹相关路径下

/home/wln/install/install_102/share/postgresql/extension/postgis--2.4.0.sql

这样仍能够重现问题(原来的这个文件有4万多行)

原因分析

现象:直接psql -f 该文件没问题,而通过create extension postgis 在coordinator上调用函数CreateExtension去执行execute_sql_string却出现问题,有点奇怪。

定位分析,插件执行流程为:

1. 先在本地coordinator上执行create extension 语句(在pg_extension表中插入一行数据)

  然后执行该插件对应的sql文件即上面的postgis--2.4.0.sql文件的内容

2. 将create extension 语句下发到远端(各个datanode上), 每个datanode在本节点执行CreateExtension函数并执行插件对应的sql文件即上面的postgis--2.4.0.sql文件的内容。

现在出现问题的原因:coordinator执行postgis--2.4.0.sql文件内容时,如create table 语句是不会再下发到各个datanode上的,但是像存储过程、insert语句仍会下发到datanode上去执行,这样在coordinator执行上面文件内容的存储过程语句时,此时coordinator 上是已经创建了type gidx的,但是此时coordinator上 还没开始下发create extension语句到datanode,所以此时datanode上是没有这个类型的,所以datanode 接收存储过程并去执行是必然报错的。

根据现有的分布式数据库postgre-xl 处理插件逻辑见函数CreateExtension,插件对应的sql文件,如果内部使用了存储过程,则极其容易引起错误(涉及对象在coordinator上datanode上执行create extension先后顺序),如果使用了insert into 也会出现问题(如果insert的对象在前面创建则该语句下发到datanode上其表对象此时还未创建)。

针对postgis在postgres-xl的问题,可以使用下面方法进行处理:

1. 规避,在插件对应的sql文件内容不要使用存储过程及insert操作, insert 操作可以放在create extension后手动执行。

2. 修复该问题,修改postgres-xl处理插件的现有逻辑:在coordiantor本地执行时,根据语句情况进行下发操作,这样在coordinator上和datanode上可以看作同步操作,不存在现在coordinator上执行完sql文件内容然后datanode再去执行这个sql文件内容;create extension语句下发到datanode上执行时只执行在pg_extension表插入一行记录操作,不再去执行sql文件内容。

已试着修改,同时提交给了postgres-xl 官方, 见 

http://lists.postgres-xl.org/pipermail/postgres-xl-bugs-postgres-xl.org/2018-November/000495.html

 

你可能感兴趣的:(postgres-xc,分布式数据库)