0%

pgSQL集群工具PLproxy——基本代理函数

准备工作参见《部署》

假设基本配置如下:

  1. server name: cluster_zly
  2. proxy db role:proxy —\du
  3. proxy db name:proxy —\l
  4. data db role:zlyadmin(数据节点操作用户) —\du
  5. data db name:zlydb0,zlydb1(双数据节点) —\l
  6. schema:zly —\dn

PL/Proxy语言详解

  • 共支持下列4个语句:CONNECT,CLUSTER,RUN,SELECT;
  • 每个函数要么包含CONNECT,要么包含CLUSTER+RUN
  • SELECT可选,如果不使用SELECT,会调用数据节点的同名函数;若使用则在数据节点直接执行此SQL;
  • RUN语句也可以不使用,等价于RUN ON ANY;

CONNECT

CONNECT 'libpg connstr' | CONNECT connect_func(...) | argname;

CONNECT后面可以直接跟一个libpq的连接字符串,也可跟一个函数,由其返回一个libpq连接串;或跟一个函数参数名,指定连接哪一个数据库。
一个proxy函数中只能出现一条connect语句

CONNECT 'hostaddr=172.16.3.150 dbname=db0 user=digoal port=1921';  

CLUSTER

CLUSTER 'cluster_name' | CLUSTER connect_func(...) | argname;

CLUSTER后面跟一个标识集群名称的字符串,也可以跟一个函数,由其返回一个集群名称;还可跟一个参数名,参数内容为一个集群名称。

RUN ON

RUN ON ALL | ANY | <NR> | partition_func(...);
  1. RUN ON ALL 表示在集群每个数据节点并行执行,必须returns setof
  2. RUN ON ANY 表示随机挑选一个节点执行
  3. RUN ON 表示指定某一数据节点的数字(0…n-1)执行
  4. RUN ON partition_func(…) 表示有函数particion_func()返回一个或多个hash值后将请求转到对应的后端数据节点上,如果是多个hash值,也是并行执行。

SPLIT

TARGET

TARGET other_function;

可以让后端的函数名与Proxy节点的函数名不一样,如:
<!—hexoPostRenderEscape:

CREATE OR REPLACE FUNCTION get_user_email(i_username text)
RETURNS SETOF text AS $$
CLUSTER ‘cluster_zly’;
RUN ON hashtext(i_username);
TARGET get_customer_email;

$$ LANGUAGE plproxy

proxy节点函数

ddl函数

CREATE OR REPLACE FUNCTION zly.ddlexec(query text)
RETURNS SETOF integer AS
$BODY$
CLUSTER 'cluster_zly';
RUN ON ALL;
$BODY$
LANGUAGE plproxy VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION zly.ddlexec(text)
OWNER TO postgres;

dml函数(随机insert,不适用update,delete)

CREATE OR REPLACE FUNCTION zly.dmlexec(query text)
RETURNS SETOF integer AS
$BODY$
CLUSTER 'cluster_zly';
RUN ON ANY;
$BODY$
LANGUAGE plproxy VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION zly.dmlexec(text) OWNER TO postgres;

dql函数(查询)

CREATE OR REPLACE FUNCTION zly.dqlexec(query text)
RETURNS SETOF record AS
$BODY$
CLUSTER 'cluster_zly';
RUN ON ALL;
$BODY$
LANGUAGE plproxy VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION zly.dqlexec(text) OWNER TO postgres;

data节点函数

ddl函数

CREATE OR REPLACE FUNCTION zly.ddlexec(query text)
RETURNS integer AS
$BODY$
declare
ret integer;
begin
execute query;
return 1;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

dml函数(插入)

CREATE OR REPLACE FUNCTION zly.dmlexec(query text)
RETURNS integer AS
$BODY$
declare
ret integer;
begin
execute query;
return 1;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

dql函数(查询)

CREATE OR REPLACE FUNCTION zly.dqlexec(query text)
RETURNS SETOF record AS
$BODY$
declare
ret record;
begin
for ret in execute query 
loop
return next ret;
end loop;
return;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100
ROWS 1000;

测试

批量建表:

select zly.ddlexec('create table t1(id integer,name varchar(100))');

插入数据:

select zly.dmlexec('insert into t1 values(0,'aaa')');

查询数据数量:

select * from zly.dqlexec('select cast(count(id) as int) as cnt  from t1 ') as (cnt int) ;

查询数据内容:

select * from zly.dqlexec('select * from t1') as (id  integer, name varchar );