插件 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代码确实已经修改了。
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