Ubuntu下PostgreSQL数据库集群(PL/Proxy)配置方法
2019独角兽企业重金招聘Python工程师标准>>>
数据库集群:N个数据库堆到一起,找一个当个头头,管理所有的数据库并让它们协同工作。当然了,要不要找个头头,找几个头头,如何协作等等问题这些都可以商量和约定,因此,也就形成了不同的数据库集群。
如果数据库系统是PostgreSQL,这个集群就是PostgreSQL数据库集群。
PostgreSQL数据库管理集群的方法有很多,有人提出了PL/Proxy方式的集群(这才是本文的重点)。这个PL/Proxy方式的集群是这样的:有很多安装了PostgreSQl数据库的计算机,有台计算机是头头,我们把这个头头叫做proxy,其他的叫做database0,database1……。
以三台机器的集群为例子,看看PostgreSQL集群的架构是什么。
proxy节点:proxy节点实际上也是一个PostgreSQL数据库 节点,但是所有数据均不存放到proxy节点上,主要做三件事情:
1.接受用户的sql查询;
2.分析用户的sql查询并转换成集群上执行的SQL语句;
3.合并集群执行sql的结果,然后返回给用户。
说白了,就是把用户的sql语句交给database0,database1去执行,然后合并执行结果返回给用户。
database1节点和 database2节点:
就是普通的数据库节点,接收proxy节点的sql查询请求并返回结果给proxy节点,是真正存放数据的节点。
集群结构图,结构更清晰一些:
开始创建一个数据库集群吧,需求如下:
1.创建一个如集群结构图所示的集群,数据库集群中均操作同一个数据库“arvindb”;
2.用户通过客户端操作proxy节点在集群中创建一个表user(说白了就是要通过集群的方法在Database0和Database1的arvindb中创建一个叫做user的表);
3.用户通过客户端操作proxy节点在集群上插入多个记录信息到集群的user表上(需要把插入操作分布到两个Database节点上);
4.用户通过客户端操作proxy节点在集群上查询集群上的所有user记录;
(版本号需要留意一下,版本不同的话,可能会导致情况大不相同)
操作性较强的步骤:
第一步:创建三个空的虚拟机器并把这三台虚拟机的网卡设置搞定(比如,是否桥接,是否NAT之类)(有钱的话,自己买三台电脑,3条网线和一个集线器)。
可以创建虚拟机的软件如VMWare, VirtualPC, Xen等等,本文的实验用的是VMWare.
第二步:三个虚拟机全部安装Ubuntu-12.04
第三步:三个虚拟机全部安装PostgreSQL数据库系统
如何安装和配置请参见Ubuntu下 Postgresql-9.1安装及配置
第四步:将每台服务器的设定成允许任何机器使用任何账号访问任何数据库
root@ubuntuserver:~# vi /etc/postgresql/9.1/main/pg_hba.conf
—>改变行:host all all 0.0.0.0 0.0.0.0 md5
—>修改为:host all all 0.0.0.0 0.0.0.0 trust
如果没有此行则添加此行,具体说明参见Ubuntu下 Postgresql-9.1安装及配置。
第五步:三个虚拟机全部创建数据库Arvindb:
root@ubuntuserver:~# psql –U postgres -h 127.0.0.1
postgres=# create database “arvindb”;
创建数据库的详细方法请参见Ubuntu下 Postgresql-9.1安装及配置
第六步:在 proxy 节点上安装过程语言plproxy(安装 plproxy 必须使用 root 用户,否则不能正常安装)
root@ubuntuserver:~# sudo apt-get install postgresql-9.1-plproxy
这一步的目的是:使proxy节点知道怎样指挥集群(实验中,就是指挥database0和database1),换句话就是说,让prxoy知道三件事情:
第七步:为proxy节点上的数据库”arvindb “创建plproxy过程语言(前提是你之前安装过这个语言):
第八步:为proxy节点的”arvindb”数据库创建plpgsql过程语言:
之所以创建plpgsql语言,是因为plproxy过程语言本身需要调用plproxy目录下的三个由plpgsql过程语言定义的三个函数。
plpgsql 是postgresql自带的过程语言(含义是,安装 postgresql数据库的时候plpgsq.so文件就会被安装到postggresql的lib文件夹下,对于apt-get install postgresql方式安装的9.1版本数据库系统的lib文件夹是/usr/lib/postgresql/9.1)。
自带的含义就是“HANDLER plpgsql_call_handler”; 和“VALIDATOR plpgsql_validator;” 这两个函数应该是数据库系统为plpgsql过程语言默认设置的handler函数和validator函数(这个是我的猜测,还没有证实),所以创建plpgsql的时候不需要指定handler函数和validator函数(当 然,validator函数本省就是可选的)。有图有真相: 如果数据库系统中的模板数据template1没有创建plpgsql过程语言的话,每一个数据库要使用plpgsql语言之前,都需要创建该语言,以数据库arvindb为例的语句是:
root@ubuntuserver:~#sudo -u postgres createlang plpgsql “Arvindb”
第九步:在proxy节点上创建名字为plproxy的schema:
root@ubuntuserver:~# sudo -u postgres psql -d “Arvindb”
Arvindb=# create schema plproxy;
第十步:在proxy节点上的plproxy目录下创建三个函数:
get_cluster_config
get_cluster_partitions
get_cluster_version
root@ubuntuserver:~# sudo -u postgres psql Arvindb
创建函数的SQL代码如下:
key := 'statement_timeout'; //就是给 key 变量赋值,赋的值为’statement_timeout’
val := 60; //就是给 val 变量赋值,赋的值为 60
CREATE OR REPLACE FUNCTION plproxy.get_cluster_partitions(cluster_name text)
IF cluster_name = 'arvincluster' THEN //cluster_name 是群集的名字
RETURN NEXT 'dbname=hldb host=10.3.12.2'; //数据库节点的数据库名和 IP 地址
RETURN NEXT 'dbname=hldb host=10.3.12.3'; //数据库节点的数据库名和 IP 地址
RAISE EXCEPTION 'Unknown cluster'; //–如果群集名不存在,抛出异常,这个是在数据库内部处理的,最终会写入日志中。‘Unknown cluster’是报错信息
CREATE OR REPLACE FUNCTION plproxy.get_cluster_version(cluster_name text)
IF cluster_name = ' arvincluster ' THEN
RAISE EXCEPTION 'Unknown cluster';
下面是解释,不想了解的话,可以直接跳过。
三个函数的作用:
plproxy.get_cluster_config: 这个函数其实是获取不同的集群的配置,我们这里可以给不同的集群(比如Arvindb等)不同的类似超时时间、长短连接等的设置。
plproxy.get_cluster_partitions: 这个函数是让plproxy可以找到对应的集群,“Arvindb ”是集群的名称,根据自己的需要指定,这个名称在后面查询的时候要用到;”dbname”, “host” 等参数就是PostgreSQL标准的数据库连接串的配置方法,本试验中就是database0节点和database1节点的信息告诉proxy节点。
plproxy.get_cluster_version: 这个函数其实是plproxy用于判断是否给前端返回已经cache过的结果用的,这样,因为函数本身可以动态更新(无需down机),那么我们可以通过重新创建函数,返回不同RETURN的值,实现cache的失效控制。
plproxy过程语言设计的目的是实现数据库集群,集群受proxy节点管理,proxy获取集群的信息(比如节点的IP地址等等信息)的方法就 是调用上面创建的三个函数,所以配置集群信息的方法就是创建/修改这三个函数。
使用plproxy过程语言的用户不需要显式的调用这三个函数,但是在调用plproxy过程语言定义的函数的时候,plproxy过程自己会在内部调用目录plproxy下的这三个函数:
I.对于plproxy.get_cluster_config和plproxy.get_cluster_partitions函数,内部调用一次后就 不再调用;
以plproxy.get_cluster_partitions为例子的实验是:
a.执行plproxy 过程语言定义的函数–>成功;
b.删除plproxy.get_cluster_partitions函 数,调用plproxy过程语言定义的函数,执行成功。
一个特殊情况:如果删除plproxy.get_cluster_partitions函数之前,数据库系统从未执行过任何plproxy过程语言定义的 函数,执行plproxy过程语言定义的函数将会失败).
另外一个实验是:
a.执行plproxy 过程语言定义的函数–>成功;(集群信息为“dbname=Arvindb host=10.13.19.55”和dbname=Arvindb host=10.13.19.70)
b.修改plproxy.get_cluster_partitions函 数(集群信息为“dbname=Arvindb host=10.13.19.55”和dbname=Arvindb host=10.13.19.71, 调用plproxy过程语言定义的函数,执行成功。但是使用的集群信息仍然是:“dbname=Arvindb host=10.13.19.55”和dbname=Arvindb host=10.13.19.70)。
II.对于plproxy.get_cluster_version函数,执行plproxy过程语言定义的函数的时候,内部每次都会调用plproxy.get_cluster_version函数。 实验的方法可与参考前面的方法。
总结一下:如果修改了plproxy.get_cluster_config和plproxy.get_cluster_partitions函 数,想立即生效 的话,就需要重启postgresql服务(其他方法还没有深究过):/etc/init.d/postgresql-8.4 restart
从网上参考的资料,以及相关pdf中参看的代码会有一些问题:字符不对 ,同样为单引号,但是pdf中的单引号是‘(看清楚:不是正确的’),等等之类很难发现的错误,严重影响了工作进度。
再补充一下:下面的实验表明 postgresql下的函数定义/修改/删除是及时生效的:
创建一个函数:
CREATE OR REPLACE FUNCTION fun_test() RETURNS integer AS
$BODY$ SELECT 33; $BODY$
LANGUAGE ‘sql’ VOLATILE COST 100;
执行这个函数:
select fun_test();———> 正常执行
删除这个函数:
DROP FUNCTION fun_test;
执行这个函数:
select fun_test(); ——–>执行失败:找不到函数fun_test();
第十一步:在proxy节点上创建三个函数:
public.ddlexec(sql_request text)
public.dmlexec(sql_request text)
public.dqlexec(sql_request text)
root@ubuntuserver:~# sudo -u postgres psql Arvindb
创建的sql代码是:
CREATE OR REPLACE FUNCTION ddlexec(query text)
RETURNS SETOF integer AS
$BODY$
CLUSTER 'arvincluster';
RUN ON ALL;
$BODY$
LANGUAGE 'plproxy' VOLATILE
COST 100
ROWS 1000;
CREATE OR REPLACE FUNCTION dmlexec(query text)
RETURNS SETOF integer AS
$BODY$
CLUSTER 'arvincluster';
RUN ON ANY;
$BODY$
LANGUAGE 'plproxy' VOLATILE
COST 100
ROWS 1000;
CREATE OR REPLACE FUNCTION dqlexec(query text)
RETURNS SETOF record AS
$BODY$
CLUSTER 'arvincluster';
RUN ON ALL;
$BODY$
LANGUAGE 'plproxy' VOLATILE
COST 100
ROWS 1000; ROWS 1000;执行后在pgAdmin3客户端观看到的效果是:
下面是解释,不想了解的话,可以直接跳过。
这三个函数的作用就是:用户通过调用者三个函数操纵集群(比如select ddlexec(‘create table usertable’)就会在集群的database0和database1上同时创建一个表usertable)。
这三个函数都是plproxy过程语言的函数,函数中的RUN指令会调用集群节点上的同名函数,所以还需为集群上的数据库节点database0和database1创建同名的函数(只要同名,不需要也是plproxy过程语言定义)。
RUN ON指令之后的的ALL表示在集群上的所有数据库节点上运行(本试验就是database0和databse1都要执行)
RUN ON指令之后的的ANY表示在集群上的任取一个数据库节点上运行(本试验就是database0和databse1中任意取一个执行)
RUN ON 之后也可以是一个数字: 表示在几号节点上运行,比如 RUN ON 0/RUN ON 1。也可以自己写一个算法决定如何分配任务: 比如RUN ON hashtext(表的主键值)&1。表示将表的主键(文本类型)计算出一个hash值,然和1做与运算。就可以根据主键分配数据库节点。
第十二步:为database0和database1节点的”Arvindb”数据库创建plpgsql过程语言
root@ubuntuserver:~# sudo -u postgres psql Arvindb
Arvindb=# create language plpgsql;
或者:sudo -u postgres createlang plpgsql “Arvindb”
创建的原因是:database0和database1节点需要创建一些函数,这些函数是plpgsql过程语言定义的。
第十三步:在database0和database1节点上创建下面三个函数
public.ddlexec(sql_request text)
public.dmlexec(sql_request text)
public.dqlexec(sql_request text)
root@ubuntuserver:~# sudo -u postgres psql Arvindb
创建的SQL语句如下:
CREATE OR REPLACE FUNCTION ddlexec(query text)
RETURNS integer AS
$BODY$
declare
ret integer;
begin
execute query;
return 1;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION dmlexec(query text)
RETURNS integer AS
$BODY$
declare
ret integer;
begin
execute query;
return 1;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION 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;执行后在pgAdmin3客户端观看到的效果是:
第十四步:集群创建user表,在proxy上执行:
root@ubuntuserver:~# sudo -u postgres psql Arvindb
Arvindb=# select ddlexec('create table usertable(id integer)');
可以通过pgAdmin3看到创建的结果:
第十五步:向集群的user表中插入一些数据,在proxy上执行:
root@ubuntuserver:~# sudo -u postgres psql Arvindb
select dmlexec(‘insert into usertable values(0)’);
select dmlexec('insert into usertable values(0)');
select dmlexec('insert into usertable values(1)');
select dmlexec('insert into usertable values(2)');
select dmlexec('insert into usertable values(3)');
select dmlexec('insert into usertable values(4)');
select dmlexec('insert into usertable values(5)');
select dmlexec('insert into usertable values(6)');
select dmlexec('insert into usertable values(7)');
select dmlexec('insert into usertable values(8)');
select dmlexec('insert into usertable values(9)');
select dmlexec('insert into usertable values(10)');
可以通过pgAdmin3看到创建的结果(数据存到那个节点取决于分配算法):
第十六步:查询集群的user表的记录,在proxy上执行:
select * from dqlexec('select * from usertable') as (id integer);
注意:必须要有as之后的内容,原因是, plpgsql过程语言的record返回类型需要有列定义。
可以通过pgAdmin3看到创建的结果:
续:
可能出现的问题 |
解决方案 |
用apt-get安装时,无法找到安装包 |
(1) 更新安装源地址,建议用百度安装源 输入命令 :sudo vim /etc/apt/sources.list(安装源自己找,删除原有代码,复制到里面就可以了) (2) 查看网络是否连接,ip、netmask、getway、dns是否正确配置 输入命令:sudo vim /etc/network/interfaces (3) 更新apt-get 输入命令:apt-get update |
运行引用代码时,提示出现错误 |
(1) 双引号,或单引号使用错误,手动更改为符合要求的。 (2) 丢失分号(;)应特别注意。 |
apt-get安装pgadmin3时,没有出现图形界面 |
(1)建议独立下载pgadmin3并安装 |
……. |
………. |
著:经过作者实践检验,可以正常实施.若有疑问,请加QQ;505024705
或e-mail:hl_linux@yahoo.cn
转载于:https://my.oschina.net/u/588294/blog/66751
Ubuntu下PostgreSQL数据库集群(PL/Proxy)配置方法相关推荐
- PostgreSQL流复制之二:pgpool-II实现PostgreSQL数据库集群(转发+整理)
转发来源: PostgreSQL的集群技术比较:https://iwin.iteye.com/blog/2108807 参考:https://blog.csdn.net/yaoqiancuo3276/ ...
- ubuntu下搭建redis集群
前言 ubuntu下搭建redis集群步骤 步骤 准备工作 redis的集群管理工具依赖于ruby,先安装 sudo apt-get install ruby 上传redis和ruby的接口配置文件 ...
- mysql 数据库集群状态查看_MySQL数据库集群进行正确配置步骤
MySQL数据库集群进行正确配置步骤 2010-06-09 10:47 arrowcat 博客园 字号: 我们今天是要和大家一起分享的是对MySQL数据库集群进行正确配置,我前两天在相关网站看见的资料 ...
- 迅搜xunsearch全文搜索引擎在负载均衡集群中的配置方法
迅搜xunsearch全文搜索引擎在负载均衡集群中的配置方法 近来在一个电商项目中需要对商品检索实现中文分词和全文搜索功能,,于是使用了国内做得比较好并且是开源的迅搜全文搜索引擎,对PHP支持良好并且 ...
- 【Data Cluster】真机环境下MySQL数据库集群搭建
真机环境下MySQL-Cluster搭建文档 MySQL Cluster简介 MySQL cluster 和 Oracle RAC 完全不同,它采用 无共享架构Shared nothing(share ...
- redis 集群目标、集群查看、配置方法及过程、哨兵配置启动
集群目标 主从复制,读写分离:故障切换(通过哨兵实现) 查看集群状态 info replication 配置方法 只设置从数据库就可以了:最佳实践,在主数据库配置masterauth <mast ...
- k8s集群下创建高可用postgresql数据库集群实践
K8s 安装 pg集群服务器 主要的目的是做到自动灾备切换,利用kubernetes 集群做到高可用的数据库服务. 三个节点, 2节点部署 proxy,sentinel,3节点keeper (DB) ...
- Ubuntu下搭建Kubernetes集群(3)--k8s部署
1. 关闭swap并关闭防火墙 首先,我们需要先关闭swap和防火墙,否则在安装Kubernetes时会导致不成功: # 临时关闭 swapoff -a# 编辑/etc/fstab,注释掉包含swap ...
- Ubuntu下Nginx/PHP/MYSQL开发环境的配置方法
最近将原来的程序都迁移到了Nginx下来了,用了Ubuntu也有一段时间大了,慢慢了习惯了下Linux的操作,在加上Linux下性能确实不错,就开始配置了. 配置了 Ubuntu 9.10 Ngin ...
- Ubuntu下安装Audacious音乐播放器详细配置方法(中文化,歌词显示等)
Windows下有不少比较有名气的音乐播放器,例如千千静听,Kugou,foobar和QQ音乐等,但是ubuntu下的音乐播放器则没有这么丰富,但是现在则给大家介绍一款ubuntu下的"千千 ...
最新文章
- Cmake 实例学习 一
- 机器人学会对自己下手了,螺丝松了自己拧
- see rebel case 无法越狱_周星驰为什么不拍喜剧,王晶:年纪大了,无法面对自己...
- 【转】SharePoint 2013 开发——开发并部署webpart
- mysql declare 赋值_sql server和mysql变量赋值的区别 以及 MySql Declare
- IntelliJ IDEA这样配置,代码效率嗖嗖的
- 如何将索引碎片数量降至最低
- window.open在Safari浏览器出现的问题
- mysql 程序无法连接_程序无法连接到服务器不知道怎么解决
- 微信开发者服务器是什么意思,详解微信开发者文档——2接入服务器至微信开发平台...
- Sublime LiveReload
- Access宏学习总结
- LaTeX及TeXstudio下载地址
- 使用Selenium爬取淘宝商品
- Nginx安装及简介
- PATA1142 Maximal Clique(测试点2、3)
- python 模拟鼠标,键盘点击
- Microsoft Exchange Server邮箱管理
- java lambda表达式 steam api
- c语言证明加法交换律,与环定义相关的问题证明交换环定义为:集合R上定义加法和乘法,使得R中任何元素满足:(1)加法交换律 (2)加法结合律(3...
热门文章
- android NDK 详解
- android studio for android learning (二十四 )bitmap and bitmapFactory
- Activation function in Neural Network
- 多元函数四则运算的一阶微分公式的存在性与性质
- 483. Smallest Good Base 1
- java打印出日历_java控制台打印本月的日历
- nginx服务无法停止(Windows)
- 不要在考虑需求之前更多的在意你的职业镀金
- [CF888G] Xor-mst (Trie 树,最小生成树)
- mysql增删改处理