Postgresql分布式插件plproxy的使用详解

Simple remote function call

节点61/62(datanode)

CREATE TABLE users (username text, email text);
insert into users values ('user0', 'user0@gmail.com');
insert into users values ('user1', 'user1@gmail.com');
insert into users values ('user2', 'user2@gmail.com');

节点60(proxy)

create or replace extension plproxy;
CREATE FUNCTION get_user_email(i_username text)
RETURNS SETOF text AS $$
 CONNECT 'host=localhost port=9461 dbname=postgres connect_timeout=10';
 SELECT email FROM users WHERE username = $1;
$$ LANGUAGE plproxy;
SELECT * from get_user_email('user0');

Configuring Pl/Proxy clusters with SQL/MED

节点60(proxy)

CREATE FOREIGN DATA WRAPPER plproxy;
CREATE SERVER usercluster FOREIGN DATA WRAPPER plproxy
OPTIONS (connection_lifetime '1800',
   p0 'host=localhost port=9461 dbname=postgres connect_timeout=10',
   p1 'host=localhost port=9462 dbname=postgres connect_timeout=10' );
CREATE USER MAPPING FOR PUBLIC SERVER usercluster;

Partitioned remote call

节点60(proxy)

CREATE OR REPLACE FUNCTION insert_user(i_username text, i_emailaddress text)
RETURNS integer AS $$
 CLUSTER 'usercluster';
 RUN ON hashtext(i_username);
$$ LANGUAGE plproxy;

节点61/62(datanode)

CREATE OR REPLACE FUNCTION insert_user(i_username text, i_emailaddress text)
RETURNS integer AS $$
  INSERT INTO users (username, email) VALUES ($1,$2);
  SELECT 1;
$$ LANGUAGE SQL;

Putting it all together

节点60(proxy)

SELECT insert_user('Sven','sven@somewhere.com');
SELECT insert_user('Marko', 'marko@somewhere.com');
SELECT insert_user('Steve','steve@somewhere.cm');

plproxy–2.7.0.sql

-- handler function
CREATE FUNCTION plproxy_call_handler ()
RETURNS language_handler AS 'plproxy' LANGUAGE C;
-- validator function
CREATE FUNCTION plproxy_validator (oid)
RETURNS void AS 'plproxy' LANGUAGE C;
-- language
CREATE LANGUAGE plproxy HANDLER plproxy_call_handler VALIDATOR plproxy_validator;
-- validator function
CREATE FUNCTION plproxy_fdw_validator (text[], oid)
RETURNS boolean AS 'plproxy' LANGUAGE C;
-- foreign data wrapper
CREATE FOREIGN DATA WRAPPER plproxy VALIDATOR plproxy_fdw_validator;

补充:PostgreSQL 水平分库——plproxy

1、PL/Proxy安装

1、1 编译安装

tar -zxvf plproxy-2.7.tar.gz
cd plproxy-2.7
source /home/postgres/.bashrc
make
make install

1、2 创建pl/proxy扩展

itm_pg@pgs-> psql
psql (10.3)
Type "help" for help.
postgres=# create database proxy;
CREATE DATABASE
postgres=# \c proxy
You are now connected to database "proxy" as user "postgres".
proxy=# create extension plproxy;
CREATE EXTENSION
proxy=# \dx
                List of installed extensions
 Name  | Version |  Schema  |            Description       

---------+---------+------------+-----------------------------------------------
-----------
 plpgsql | 1.0   | pg_catalog | PL/pgSQL procedural language
 plproxy | 2.8.0  | public   | Database partitioning implemented as procedura
l language
(2 rows)

2、pl/proxy配置

修改数据库节点pg_hba.conf:

修改两个数据节点的pg_hba.conf,保证代理节点可以访问。

# TYPE DATABASE    USER      ADDRESS         METHOD
 host all       all       192.168.7.177/32     trust

在SQL/MED方法在pl/proxy节点进行集群配置:

proxy=# create schema plproxy; --下面的函数都是创建在plproxy这个schema下面
CREATE SCHEMA
proxy=# create user bill superuser;
CREATE ROLE
--创建一个使用plproxy FDW的服务器
proxy=# CREATE SERVER cluster_srv1 FOREIGN DATA WRAPPER plproxy
proxy-#     OPTIONS (
proxy(#         connection_lifetime '1800',
proxy(#         disable_binary '1',
proxy(#         p0 'dbname=pl_db0 host=192.168.7.166',
proxy(#         p1 'dbname=pl_db1 host=192.168.17.190'
proxy(#         );
CREATE SERVER
proxy=# \des
      List of foreign servers
   Name   | Owner | Foreign-data wrapper
--------------+-------+----------------------
 cluster_srv1 | bill | plproxy
(1 row)
proxy=# grant usage on FOREIGN server cluster_srv1 to bill;
GRANT
--创建用户映射
proxy=# create user mapping for bill server cluster_srv1 options (user 'bill');
CREATE USER MAPPING
proxy=# \deu
 List of user mappings
  Server  | User name
--------------+-----------
 cluster_srv1 | bill
(1 row)

配置完成!在"CLUSTER"模式中;才需要上述配置;在"CONNECT"模式中是不需要的。

3、pl/proxy测试

在两个数据节点创建测试表:

postgres=# create database pl_db1;
CREATE DATABASE
postgres=# create user bill superuser;
CREATE ROLE
postgres=# \c pl_db1 bill
You are now connected to database "pl_db1" as user "bill".
pl_db1=# create table users(userid int, name text);
CREATE TABLE

3、1数据水平拆分测试

在每个数据节点创建insert函数接口

pl_db1=# CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
pl_db1-# RETURNS integer AS $$
pl_db1$#    INSERT INTO users (userid, name) VALUES ($1,$2);
pl_db1$#    SELECT 1;
pl_db1$# $$ LANGUAGE SQL;
CREATE FUNCTION

–pl_db0节点一样

2、在PL/Proxy数据库创建同名的insert函数接口

proxy=# CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
proxy-# RETURNS integer AS $$
proxy$#   CLUSTER 'cluster_srv1';
proxy$#   RUN ON ANY;
proxy$# $$ LANGUAGE plproxy;
CREATE FUNCTION

3、在PL/Proxy数据库创建读的函数get_user_name()

proxy=# CREATE OR REPLACE FUNCTION get_user_name()
proxy-# RETURNS TABLE(userid int, name text) AS $$
proxy$#   CLUSTER 'cluster_srv1';
proxy$#   RUN ON ALL ;
proxy$# SELECT userid,name FROM users;
proxy$# $$ LANGUAGE plproxy;
CREATE FUNCTION

4、在pl/proxy节点插入数据进行测试

SELECT insert_user(1001, 'Sven');
SELECT insert_user(1002, 'Marko');
SELECT insert_user(1003, 'Steve');
SELECT insert_user(1004, 'bill');
SELECT insert_user(1005, 'rax');
SELECT insert_user(1006, 'ak');
SELECT insert_user(1007, 'jack');
SELECT insert_user(1008, 'molica');
SELECT insert_user(1009, 'pg');
SELECT insert_user(1010, 'oracle');

5、在节点数据库查看数据分布情况

pl_db1=# select * from users;
 userid | name
--------+-------
  1001 | Sven
  1003 | Steve
  1004 | bill
(3 rows)

我们在proxy节点查询下:

proxy=# SELECT USERID,NAME FROM GET_USER_NAME();
 userid | name
--------+--------
  1005 | rax
  1006 | ak
  1008 | molica
  1009 | pg
  1002 | Marko
  1004 | bill
  1007 | jack
  1010 | oracle
  1001 | Sven
  1003 | Steve
(10 rows)

因为创建insert_user函数时使用的是ROW ON ANY,表示随机再一台机器上进行执行,因此实现了数据在不同节点的随机分布,接下来改成ROW ON ALL,实验在不同节点进行数据的复制。

run on , 是数字常量, 范围是0 到 nodes-1; 例如有4个节点 run on 0; (run on 4则报错).

run on ANY,

run on function(…), 这里用到的函数返回结果必须是int2, int4 或 int8.

run on ALL, 这种的plproxy函数必须是returns setof…, 实体函数没有setof的要求.

3、2数据复制测试

选择users表作为实验对象;我们先清理表users数据;在数据节点创建truncatet函数接口

pl_db1=# CREATE OR REPLACE FUNCTION trunc_user()
pl_db1-# RETURNS integer AS $$
pl_db1$#    truncate table users;
pl_db1$#    SELECT 1;
pl_db1$# $$ LANGUAGE SQL;
CREATE FUNCTION

2、在PL/Proxy数据库创建同名的truncate函数接口

proxy=# CREATE OR REPLACE FUNCTION trunc_user()
proxy-# RETURNS SETOF integer AS $$
proxy$#    CLUSTER 'cluster_srv1';
proxy$#    RUN ON ALL;
proxy$#  $$ LANGUAGE plproxy;
CREATE FUNCTION

–检查发现数据已经清理掉了

proxy=# SELECT TRUNC_USER();
 trunc_user
------------
     1
     1
(2 rows)

3、在PL/Proxy数据库创建函数接口 insert_user_2

proxy=# CREATE OR REPLACE FUNCTION insert_user_2(i_id int, i_name text)
proxy-#  RETURNS SETOF integer AS $$
proxy$#    CLUSTER 'cluster_srv1';
proxy$#    RUN ON ALL;
proxy$#  TARGET insert_user;
proxy$#  $$ LANGUAGE plproxy;
CREATE FUNCTION

4、插入几条数据

proxy=# SELECT insert_user_2(1004, 'bill');
 insert_user_2
---------------
       1
       1
(2 rows)
proxy=# SELECT insert_user_2(1005, 'rax');
 insert_user_2
---------------
       1
       1
(2 rows)
proxy=# SELECT insert_user_2(1006, 'ak');
 insert_user_2
---------------
       1
       1
(2 rows)
proxy=# SELECT insert_user_2(1007, 'jack');
 insert_user_2
---------------
       1
       1
(2 rows)

5、查看每个节点数据情况

pl_db1=# select * from users;
 userid | name
--------+-------
  1004 | bill
  1005 | rax
  1006 | ak
  1007 | jack
(4 rows)
pl_db0=# select * from users;
 userid | name
--------+-------
  1004 | bill
  1005 | rax
  1006 | ak
  1007 | jack
(4 rows)

两个数据节点的数据一样,实现了数据的复制。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • postgresql 中的加密扩展插件pgcrypto用法说明

    近期测试了一下postgresql的加密扩展插件pgcrypto的aes加密 安装加密扩展插件:pgcrypto 在主节点上安装 create extension pgcrypto; aes加解密函数简单介绍 encrypt(data bytea, key bytea, type text) --加密 decrypt(data bytea, key bytea, type text) --解密 data 是需要加密的数据:type 用于指定加密方法 ASE方式加密: select encrypt

  • 在PostgreSQL中设置表中某列值自增或循环方式

    在postgresql中,设置已存在的某列(num)值自增,可以用以下方法: //将表tb按name排序,利用row_number() over()查询序号并将该列命名为rownum,创建新表tb1并将结果保存到该表中 create table tb1 as (select *, row_number() over(order by name) as rownum from tb); //根据两张表共同的字段name,将tb1中rownum对应值更新到tb中num中 update tb set

  • 基于PostgreSQL密码重置操作

    今天我在用命令行登陆postgresql的时候,忽然忘记密码了,重试了N次还是不行,然后我就试着上网找解决之道,最后完美的解决了,可是后来我才发现还有个更简单的方法,该篇博客用来记录自己沙雕行为. 工具已登陆 这个就是最简单的方法,你有工具登陆过,完全可以通过工具来修改(可是我当时完全没想到这个...),我是通过Navicat来连接的,可以直接通过Navicat来修改步骤如下: 1.连接数据库 2.点击角色 3.选择角色 4.填入新密码 5.保存之后,关闭连接,编辑连接就OK了. 工具未登录 W

  • PostgreSQL表膨胀监控案例(精确计算)

    膨胀率的精确计算 PostgreSQL自带了pgstattuple模块,可用于精确计算表的膨胀率.譬如这里的tuple_percent字段就是元组实际字节占关系总大小的百分比,用1减去该值即为膨胀率. #插入1000W数据 postgres=# insert into t select id,id from generate_series(1,10000000) as id; INSERT 0 10000000 #表膨胀系数为0.097 postgres=# select *, 1.0 - tu

  • PostgreSQL 实现登录及修改密码操作

    PostgreSQL登录 1.可通过客户端pgAdmin III直接登录 2.可通过命令行 命令:psql -h 10.10.10.10 -U user -d postgres -p 5570 -h:数据库IP -U:登录用户 -d:登录的数据库 -p:登录端口 方法:进入postgreSQL的客户端安装目录(我的安装目录:C:\Program Files\PostgreSQL\9.4\bin),执行psql命令,其中\q表示退出数据库 修改密码 直接执行以下sql即可修改密码 alter us

  • Postgresql 默认用户名与密码的操作

    在UNIX平台中安装PostgreSQL之后,PostgreSQL会在UNIX系统中创建一个名为"postgres"当用户.PostgreSQL的默认用户名和数据库也是"postgres", 不过没有默认密码.在安装PostgreSQL之后可以以默认用户登录,也可以创建新当用户名. 以默认用户登录 Yu @Coat ~ $ sudo su postgres #切换至postgres postgres @Coat /home /Yu $ psql postgres #

  • Postgresql分布式插件plproxy的使用详解

    Simple remote function call 节点61/62(datanode) CREATE TABLE users (username text, email text); insert into users values ('user0', 'user0@gmail.com'); insert into users values ('user1', 'user1@gmail.com'); insert into users values ('user2', 'user2@gmai

  • jQuery图片缩放插件smartZoom使用实例详解

    e-smart-zoom-jquery.js插件,下载地址及示例:https://github.com/e-smartdev/smartJQueryZoom 插件描述:通过将鼠标悬停在图片上,滚动鼠标滚轮即可实现图片的放大或者缩小效果. smartZoom使用 举个栗子,上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <tit

  • jQuery.Validate表单验证插件的使用示例详解

    jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求. 请在这里查看示例 validate示例 示例包含 验证错误时,显示红色错误提示 自定义验证规则 引入中文错误提示 重置表单需要执行2句话 源码示例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <

  • Hadoop 分布式存储系统 HDFS的实例详解

    HDFS是Hadoop Distribute File System 的简称,也就是Hadoop的一个分布式文件系统. 一.HDFS的优缺点 1.HDFS优点: a.高容错性 .数据保存多个副本 .数据丢的失后自动恢复 b.适合批处理 .移动计算而非移动数据 .数据位置暴露给计算框架 c.适合大数据处理 .GB.TB.甚至PB级的数据处理 .百万规模以上的文件数据 .10000+的节点 d.可构建在廉价的机器上 .通过多副本存储,提高可靠性 .提供了容错和恢复机制 2.HDFS缺点 a.低延迟数

  • vue 使用axios 数据请求第三方插件的使用教程详解

    axios 基于http客户端的promise,面向浏览器和nodejs 特色 •浏览器端发起XMLHttpRequests请求 •node端发起http请求 •支持Promise API •监听请求和返回 •转化请求和返回 •取消请求 •自动转化json数据 •客户端支持抵御 安装 使用npm: $ npm i axiso 为了解决post默认使用的是x-www-from-urlencoded 去请求数据,导致请求参数无法传递到后台,所以还需要安装一个插件QS $ npm install qs

  • Hadoop-3.1.2完全分布式环境搭建过程图文详解(Windows 10)

    一.前言 Hadoop原理架构本人就不在此赘述了,可以自行百度,本文仅介绍Hadoop-3.1.2完全分布式环境搭建(本人使用三个虚拟机搭建). 首先,步骤: ① 准备安装包和工具: hadoop-3.1.2.tar.gz ◦ jdk-8u221-linux-x64.tar.gz(Linux环境下的JDK) ◦ CertOS-7-x86_64-DVD-1810.iso(CentOS镜像) ◦工具:WinSCP(用于上传文件到虚拟机),SecureCRTP ortable(用于操作虚拟机,可复制粘

  • vue 插件的方法代码详解

    在开发项目的时候,我们一般都用 vue-cli 来避免繁琐的 webpack 配置和 template 配置.但是官方 cli3 现在并不支持搭建 plugin 开发的项目. 还好,已经有大神(Kazupon)走在了我们前面,我们就用现成的vue-cli-plugin-p11n. 如果你没有安装 vue-cli,请先安装 npm i -g @vue/cli 首先,搭建项目 vue create [your plugin name] && cd [your plugin name] vue

  • bootstrap中日历范围选择插件daterangepicker的使用详解

    daterangepicker是bootstrap的一个日历插件 主要用来选择时间段的插件 这个插件很好用 也很容易操作  引入相关插件 <!-- 需要引用的依赖库 --> <script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script> <script type="text/javascript&quo

  • jQuery.validate.js表单验证插件的使用代码详解

    Validate Validate是基于jQuery的一款轻量级验证插件,内置丰富的验证规则,还有灵活的自定义规则接口,HTML.CSS与JS之间的低耦合能让您自由布局和丰富样式,支持input,select,textarea的验证. 效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="vi

  • VSCode的使用配置以及VSCode插件的安装教程详解

    配置篇 打开设置界面 许多设置都需要在设置界面进行,所以想要配置第一步就应该是打开设置界面. 1> 鼠标操作打开.File --> Preferences --> Settings 2> 界面左下角的设置图标 打开设置有的是代码视图,有的不是,可以通过设置右上角的三个点进行切换. tab键的缩进控制 VSCode默认的tab键是缩进4个空格,但是有很多时候我们需要修改这个缩进,如vue用ES6的时候缩进4个空格会报错,这里我们就可以修改这个配置. 首先就是打开设置 直接搜索 tab

随机推荐