13.2 设置 PL/Proxy

简短的理论介绍之后,我们可以继续前进并运行一些简单的PL/Proxy设置。要做到这一点,我们只需安装PL/Proxy并看看这是如何被使用的。

安装PL/Proxy是一件很容易的事。首先,我们要从http://pgfoundry.org/projects/plproxy/下载源代码。当然,如果对您的系统来说,预编译表是可用的话,您也可以安装二进制包。然而,在这一节中,我们将简单地从源代码执行安装,并看看事情如何在一个非常基本的水平工作。

安装过程的第一步是解压tar归档。这很容易使用如下的命令实现:

tar xvfz plproxy-2.5.tar.gz

一旦tar归档解压完毕,我们就可以进入新产生的目录,并通过调用 make && make install开始编译过程。

[请确保您的 PATH 变量指向 PostgreSQL 二进制目录。根据您当前的设置,它也可能需要还是用 root 用户运行您的安装过程 ]

如果您要确保您的安装没有问题,您也可以运行 make installcheck。它运行一些简单的测试,以确保您的系统正常运行。

13.2.1 一个基本的例子

为了让您开始,我们想以一种我们可以从所有的四个分区获得随机数的方法设置PL/Proxy。这是最基本的例子。它将展示PL/Proxy所有的基本概念。

要使用PL/Proxy,我们首先要把扩展加载到数据库:

test=# CREATE EXTENSION plproxy;

CREATE EXTENSION

这将安装所有您需要这工作的相关的代码和基础设施。然后,我们要创建四个数据库,这将存储我们要分区的数据。

test=# CREATE DATABASE p0;

CREATE DATABASE

test=# CREATE DATABASE p1;

CREATE DATABASE

test=# CREATE DATABASE p2;

CREATE DATABASE

test=# CREATE DATABASE p3;

CREATE DATABASE

一旦我们创建了这些数据库,我们就可以运行 CREATE SERVER了。现在的问题是:什么是服务器?在这个环境下,您可以把服务器作为为您提供您需要的数据的远端数据源。一个服务器总是基于一个模块(在我们的例子中,PL/Proxy),还可能带一些选项。在PL/Proxy情况下,这些选项只是一些分区;也可能有一些额外的参数,但目前为止,节点列表是这里最重要的事情:

CREATE SERVER samplecluster FOREIGN DATA WRAPPER plproxy

OPTIONS ( partition_0 'dbname=p0 host=localhost',

partition_1 'dbname=p1 host=localhost',

partition_2 'dbname=p2 host=localhost',

partition_3 'dbname=p3 host=localhost');

一旦我们创建了服务器,我们可以继续前进,并创建我们自己的用户映射。用户映射的过程是告诉系统我们在远程数据源上将是什么用户。可能会发生这种情况,在Proxy上,我们是用户A,但用户B在数据库服务器上。如果您正在使用一个外部数据封装器来来接数据库,比如 Oracle,这将是必不可少的。在PL/Proxy的情况下,用户在这些分区,Proxy也在这些分区,这是很常见的事情。

因此,我们可以如下创建一个映射:

CREATE USER MAPPING FOR hs SERVER samplecluster;

如果我们使用超级用户在系统上工作,它将是足够的。如果我们不是超级用户,我们需要给那些使用我们的虚拟服务器的用户授权。我们必须授予USAGE 权限以完成这件事。

GRANT USAGE ON FOREIGN SERVER samplecluster TO hs;

要查看我们的服务器是否已经成功创建,我们可以检查pg_foreign_server 系统表。它持有关于我们的虚拟服务器的所有相关信息。当您想知道目前有哪些分区的时候,您可以简单地咨询系统表和检查srvoptions:

test=# \x

Expanded display is on.

test=# SELECT * FROM pg_foreign_server;

-[ RECORD 1 ]

srvname | samplecluster

srvowner | 10

srvfdw | 16744

srvtype |

srvversion |

srvacl | {hs=U/hs}

srvoptions | {"partition_0=dbname=p0 host=localhost","partition_1=dbna

me=p1 host=localhost","partition_2=dbname=p2 host=localhost","partitio

n_3=dbname=p3 host=localhost"}

正如我们之前提到的,PL/Proxy主要是一个存储过程语言。我们必须运行存储过程来从我们的集群获取数据。在我们的例子中,我们要在samplecluster的所有节点上运行一个简单的 SELECT 语句。

CREATE OR REPLACE FUNCTION get_random() RETURNS setof text AS $$

CLUSTER 'samplecluster';

RUN ON ALL;

SELECT random();

$$ LANGUAGE plproxy;

该过程就像是一个普通的存储过程。这里唯一的事情是,它已经被使用PL/Proxy实现了。CLUSTER 关键字将告诉系统使用哪个集群。在许多情况下,拥有多个集群是很有用的(也许,如果不同的数据集在不同不同的服务器集中)。

然后,我们必须定义在哪里运行代码。我们可以在ANY(任何服务器),ALL(所有服务器)或者在一台特定的服务器上运运行。在我们的例子中能够,我们已经决定在所有的服务器上运行了。

这里最重要的事情是,当过程被调用时,我们将从每个节点得到一行数据,因为我们使用的是 RUN ON ALL 。在 RUN ON ANY 的情况下,我们将会只得到一条数据,因为查询会在集群内部的任何一个节点上运行。

test=# SELECT * FROM get_random();

get_random

-------------------

0.879995643626899

0.442110917530954

0.215869579929858

0.642985367681831

(4 rows)

13.2.2 分区的读与写

这个例子之后,我们希望把重点放在把PL/Proxy使用到分区读区上。请记住,PL/Proxy的目的是分布我们要向外扩展的负载到多个数据库系统上。

为了演示这是如何工作的,我们希望将用户数据分发到我们的四个数据库。第一步,我们必须在集群的四个数据库上都创建一个简单的表:

p0=# CREATE TABLE t_user (

username text,

password text,

PRIMARY KEY (username)

);

NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index

"t_user_pkey" for table "t_user"

CREATE TABLE

一旦我们创建了数据结构,我们就可以拿出一个过程在这个集群中实际地调度数据。一个简单的PL/proxy 过程将做这个工作:

CREATE OR REPLACE FUNCTION create_user(name text,

pass text) RETURNS void AS $$

CLUSTER 'samplecluster';

RUN ON hashtext($1);

$$ LANGUAGE plproxy;

这里的关键是,PL/Proxy将建成第一个输入的参数并在期望的节点上运行一个称为 create_user。的过程。RUN ON hashtext($1) 将是我们的分区函数。因此,这里的目标是,找到合适的节点并在该节点上执行相同的过程。所期望的节点上的最重要的部分是,create_user 过程将不会采用PL/Proxy写,而是采用简单的SQL,PL/pgSQL,或任何其它语言。PL/Proxy函数的唯一目的是找到正确的节点来执行下面的过程。

实际上把数据出入表中的每个节点上的过程是很简单的:

CREATE OR REPLACE FUNCTION create_user(name text,

pass text)

RETURNS void AS $$

INSERT INTO t_user VALUES ($1, $2);

$$ LANGUAGE sql;

这简直就是一个封装成可以在那些节点上实际工作的存储过程的 INSERT 语句。

一旦我们在所有的四个节点上部署了这个过程,我们可以尝试:

SELECT create_user('hans', 'paul');

在 test 据库中的PL/Proxy 过程将散列输入值,并计算出数据将在p3节点上,这是第四个节点:

p3=# SELECT * FROM t_user;

username | password

----------+----------

hans | paul

(1 row)

下面的SQL语句将介绍为什么第四个节点是正确的:

test=# SELECT hashtext('hans')::int4::bit(2)::int4;

hashtext

----------

3

(1 row)

请记住,我们从0开始计数,所以,第四个节点实际上是3号节点。

[请记住,分区函数可以是任何确定的程序。我们强烈地建议尽量使它简单。]

在我们的例子中,我们基于一个有相同名字的过程将在slave上执行的事实,在代理上执行了一个过程。但是,如果您要调用过程,该过程位于一个代理上,而该代理应该执行一些在期望节点上的其它过程又怎么样呢?要映射一个代理过程到其它的过程,有一个叫做  TARGET。

要把 create_user 映射到 create_new_user,只需把如下命令添加到您PL/Proxy 函数:

CREATE OR REPLACE FUNCTION create_user(name text,

pass text) RETURNS void AS $$

CLUSTER 'samplecluster';

TARGET create_new_user;

RUN ON hashtext($1);

$$ LANGUAGE plproxy;

PostgreSQL Replication之第十三章 使用PL/Proxy扩展(2)的更多相关文章

  1. PostgreSQL Replication之第十三章 使用PL/Proxy扩展(1)

    在这里添加一个slave,真的有一个很好的可扩展性的策略,这基本上足以满足大多数现代应用程序.使用一台服务器的情况下,许多应用程序就会完美地运行,您可能想添加以副本以给基础设施增加一些安全,但在许多情 ...

  2. PostgreSQL Replication之第十三章 使用PL/Proxy扩展(3)

    13.3 聪明地扩展与处理集群 建立集群不是您面临的唯一任务.如果所有的事情都做完了并且系统已经运行了,您可能需要到处调整配置. 13.3.1 添加和移动分区 一旦一个集群启动并运行,您可能会发现您的 ...

  3. PostgreSQL Replication之第六章 监控您的设置(4)

    6.4 处理监控工具 还有几个监控工具可以使您的日常生活更轻松. 其中最流行的监控工具是Nagios.它被广泛地使用,也支持各种软件组件. 要使用 Nagios 来监控您的 PostgreSQL 集群 ...

  4. PostgreSQL Replication之第四章 设置异步复制(4)

    4.4 基于流和基于文件的恢复 生活并不总只是黑色或白色:有时也会有一些灰色色调.对于某些情况下,流复制可能恰到好处.在另一些情况下,基于文件复制和PITR是您所需要的.但是也有许多情况下,您既需要流 ...

  5. PostgreSQL Replication之第四章 设置异步复制(2)

    4.2 配置级联复制 正如您在本章已经看到的,设置流复制真的很容易.只需要设置几个参数,做一个基础备份,并享受您的复制设置. 在许多情况下,这种情况更有一点点微妙.在这个例子中我们假设:我们要使用一个 ...

  6. PostgreSQL Replication之第四章 设置异步复制(1)

    执行完您的第一个即时恢复(PITR,Point-In-Time-Recovery),我们准备在一个真正的复制设置上工作.在本章,您将学会如何设置异步复制和流.我们的目标是确保您可以实现更高的高可用和更 ...

  7. PostgreSQL Replication之第十一章 使用Skytools(3)

    11.3 管理 pgq-queues Skytools 的一个核心组件是pgq.它提供了一个通用排队接口,它可以让您把消息从一个消息提供者传送到一个任意数目的接收者. 现在的问题是:一般来说,一个队列 ...

  8. PostgreSQL Replication之第十一章 使用Skytools(1)

    向您介绍了 Slony 之后,我们将介绍另外一种流行的复制工作.Skytools 是一个最初有 Skype 开发的软件包,它有多种用途.Skytools 不只是一个单一的程序,而且是一个工具与服务的集 ...

  9. PostgreSQL Replication之第七章 理解Linux高可用(6)

    7.6 PostgreSQL和高可用性 数据库是我们日常数字生活的一部分,并期望它们快速工作. 您浏览网上论坛吗?那个帖子在数据库中.您看医生吗?您的医疗记录在数据库中.您在网上购物吗?那个货物,您的 ...

随机推荐

  1. PHP文件操作 之往一个文件写入数据

    //打开一个文件 $f = fopen($filename,'wb'); $filename:打开一个文件,不存在则自动创建,如果不能创建,说明指定的文件目录有错误 wb:写入的方式 ---- 覆盖原 ...

  2. spring容器IOC创建对象<三>

    问题?Spring的DI讲解.DI有几种注入方式.一.spring的DI:依赖注入给属性赋值DI定义:一个对象类的属性可以使用springDI(依赖注入)来进行赋值,但是并不是所有的类属性都适合spr ...

  3. (转)js一道比较考验的题目

    转载下别人曾经出过的一道面试题,此题是他出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多难只是因为大多面试者 ...

  4. JS 去字符串空格 总结

    str为要去除空格的字符串: 去除所有空格: str = str.replace(/\s+/g,""); 去除两头空格: str = str.replace(/^\s+|\s+$/ ...

  5. php curl多线程抓取网页

    PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...

  6. Flume协作框架

    1.概述 ->flume的三大功能 collecting, aggregating, and moving 收集 聚合 移动 2.框图 3.架构特点 ->on streaming data ...

  7. Qt调用dll中的功能函数

    声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:   ...

  8. zepto源码--compact、flatten、camelize、dasherize、uniq--学习笔记

    1.compact 删除数组中的空元素(不是空字符串).undefined.null 在定义变量时,定义过filter = emptyArray.filter,即调用javascript原生的数组处理 ...

  9. Barricade---hdu5889(最短路+网络流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5889 题意:有n个点m条边,每条边的长度相同,我们可以默认为1,构成一个无向图:现在起点为1,终点为n ...

  10. github Mac端的使用案例

    1. 本地有一个仓库,是和网页版的github连接在一起的,平时用Terminal来控制的,怎么放在github的客户端呢? 解决办法: 1.1 点击左上角的+ 号,在弹出框中选择Add,然后choo ...