文章目录

PostgreSQL本身没有集群功能,但是有开源的第三方解决方案,比较成熟的有Postgres XC(PGXC)和Postgres XL(PGXL)。PGXC跟进PostgreSQl的版本相对比较快,PGXL的功能比较强大一些,主要多了MPP (Massively Parallel Processing) Parallelism。PGXC集群的架构主要分全局事务管理器、协调器和数据节点三个部分,通过全局事务管理器(GTM ,Global Transaction Manager)作为单点来控制多个协调器(Coordinator),由协调器来解析SQL并把SQL分到多个数据节点(Data Node)上,取回数据后合并数据集,返回给调用者。大致结构如下图,

本文使用源码在单机上搭建PostgreSQL的集群,实际的集群环境应该是需要多台服务器,但搭建的操作步骤是类似的。实际上,安装过程本身和PostgreSQL也有很多相似之处。

先去下载PGXC的源码包,在sourceforge上有最新版,本文使用的版本是pgxc-v1.0.4.tar.gz。建立独立的用户pgxc用于管理集群,并用新的账号解压源码包。

1
2
3
4
5
6
7
8
9
10
11
[root@anzhy ~]# adduser pgxc
[root@anzhy ~]# su - pgxc
[pgxc@anzhy ~]$ exit
logout
[root@anzhy ~]# cp Downloads/pgxc-v1.0.4.tar.gz ~pgxc/
[root@anzhy ~]# su - pgxc
[pgxc@anzhy ~]$ ls
pgxc-v1.0.4.tar.gz
[pgxc@anzhy ~]$ tar xzf pgxc-v1.0.4.tar.gz
[pgxc@anzhy ~]$ ls
pgxc-v1.0.4.tar.gz postgres-xc-1.0.4

解压后的源码需要编译,编译的过程和PostgreSQL类似,有一些依赖需要安装,由于之前这台机器在安装PostgreSQL的时候已经装过依赖程序了,所以不会提示缺少依赖的情况。具体可以参考之前的文章。以下只简单列一下编译的步骤,

1
2
3
4
5
6
7
8
9
10
11
12
[pgxc@anzhy ~]$ mkdir postgres-xc
[pgxc@anzhy ~]$ mkdir data
[pgxc@anzhy ~]$ pwd
/home/pgxc
[pgxc@anzhy ~]$ cd postgres-xc-1.0.4/
......
[pgxc@anzhy ~]$ ./configure --prefix=$HOME/postgres-xc
......
[pgxc@anzhy ~]$ make
......
[pgxc@anzhy ~]$ make install
......

一切正常的话,上述每个步骤都会提示成功,Postgres XC最终会安装在$HOME/postgres-xc目录下。下面在.bashrc中配置必要的环境变量,

1
2
3
4
5
6
7
export PGHOME=/home/pgxc/postgres-xc
export PGPORT=15431
export PGDATA=$PGHOME/../data/db_1/data
export LANG=en_US.utf8
export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH
export PATH=$PGHOME/bin:$PATH:.
export MANPATH=$PGHOME/share/man:$MANPATH

接下来就可以初始化数据库了,由于是要模拟双机,所以需要创建db_1和db_2两个数据节点。同样使用initdb命令,如下,

1
2
[pgxc@anzhy ~]$ initdb -D $HOME/data/db_1/data --nodename db_1
[pgxc@anzhy ~]$ initdb -D $HOME/data/db_2/data --nodename db_2

修改两个数据节点的postgresql.conf中的参数,主要是GTM的选项,如下,

1
2
3
4
listen_addresses = '*'
port = 15431 # change to 15432 for db_2
gtm_host = '192.168.1.7'
gtm_port = 6666

其中,port参数两个节点不能相同(分别为15431和15432),否则会出错,gtm的地址要写本机的ip地址,其实对于单机的情况写localhost也是可以的。然后修改pg_hba.conf的参数配置数据节点的连接和认证,在IPv4那一段加入以下配置,

1
2
host all all 192.168.1.7/32 trust
host all all 0.0.0.0/0 md5

配置完2个数据节点之后,然后去做GTM的初始化,

1
[pgxc@anzhy ~]$ initgtm -Z gtm -D $HOME/data/gtm/data

接下来做协调器的配置,先做初始化,

1
2
[pgxc@anzhy data]$ initdb -D $HOME/data/coor_1/data --nodename coor_1
[pgxc@anzhy data]$ initdb -D $HOME/data/coor_2/data --nodename coor_2

从这个命令可以看出,其实协调器和数据节点是很相似的,他们的初始化命令是一样的。同样,也要配置协调器的参数,先是postgresql.conf中的参数,

1
2
3
4
5
listen_addresses = '*'
port = 1921 # change to 1922 for coor_2
gtm_host = '192.168.1.7'
gtm_port = 6666
pooler_port = 6667 # change to 6668 for coor_2

设置中要注意的地方和数据节点一样,协调器的设置中多了一个pooler_port的连接池相关设置,pg_hba.conf的设置和数据节点一样,加入以下配置,

1
2
host all all 192.168.1.7/32 trust
host all all 0.0.0.0/0 md5

接下来就可以启动集群了,启动的顺序是,GTM->数据节点->协调器,先启动GTM,并查看状态。

1
2
3
4
5
6
[pgxc@anzhy ~]$ gtm_ctl -Z gtm -D $HOME/data/gtm/data/ start
server starting
[pgxc@anzhy ~]$ gtm_ctl -Z gtm -D $HOME/data/gtm/data status
gtm_ctl: server is running (PID: 2884)
"-D" "/home/pgxc/data/gtm/data"
1 master

也可以简单的直接运行GTM,如下,

1
[pgxc@anzhy ~]$ gtm -D $HOME/data/gtm/data/

同样,数据节点的启动,也有两种方式,如下,

1
2
[pgxc@anzhy ~]$ pg_ctl start -D $HOME/data/db_1/data -Z datanode
[pgxc@anzhy ~]$ pg_ctl start -D $HOME/data/db_2/data -Z datanode

1
2
[pgxc@anzhy ~]$ postgres -X -D $HOME/data/db_1/data
[pgxc@anzhy ~]$ postgres -X -D $HOME/data/db_2/data

协调器的启动和数据节点是类似的,如下,

1
2
[pgxc@anzhy ~]$ pg_ctl start -D $HOME/data/coor_1/data -Z coordinator
[pgxc@anzhy ~]$ pg_ctl start -D $HOME/data/coor_2/data -Z coordinator

1
2
[pgxc@anzhy ~]$ postgres -X -D $HOME/data/coor_1/data
[pgxc@anzhy ~]$ postgres -X -D $HOME/data/coor_2/data

本文都是使用前一种方法启动的,截图如下,

启动后,可以用netstat和ps查看监听端口,和进程状态,如下图,

将上述启动步骤放在一个脚本中,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
gtm_ctl -Z gtm -D $HOME/data/gtm/data/ start
sleep 3s
gtm_ctl -Z gtm -D $HOME/data/gtm/data status
pg_ctl start -D $HOME/data/db_1/data -Z datanode
pg_ctl start -D $HOME/data/db_2/data -Z datanode
sleep 2s
pg_ctl start -D $HOME/data/coor_1/data -Z coordinator
pg_ctl start -D $HOME/data/coor_2/data -Z coordinator

关闭集群的顺序是相反的,协调器->数据节点->GTM,如下图,

同样,将上述操作合并成一个脚本,如下,

1
2
3
4
5
6
7
8
9
#!/bin/bash
pg_ctl stop -D $HOME/data/coor_2/data -Z coordinator
pg_ctl stop -D $HOME/data/coor_1/data -Z coordinator
pg_ctl stop -D $HOME/data/db_2/data -Z datanode
pg_ctl stop -D $HOME/data/db_1/data -Z datanode
gtm_ctl stop -Z gtm -D $HOME/data/gtm/data/

然后就可以登陆了,登陆其中一个协调者节点,如下,

最后一步是注册各个节点,如上登陆协调者节点1和2,运行如下脚本,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
drop node coor_1;
drop node coor_2;
create node coor_1 with(TYPE=coordinator,HOST='192.168.1.7',PORT=1921);
create node coor_2 with(TYPE=coordinator,HOST='192.168.1.7',PORT=1922);
drop node db_1;
drop node db_2;
create node db_1 with(TYPE=datanode,HOST='192.168.1.7',PORT=15431,primary=false);
create node db_2 with(TYPE=datanode,HOST='192.168.1.7',PORT=15432,primary=false);
alter node coor_1 with(TYPE='coordinator',HOST='192.168.1.7',PORT=1921);
alter node coor_2 with(TYPE='coordinator',HOST='192.168.1.7',PORT=1922);
alter node db_1 with(TYPE=datanode,HOST='192.168.1.7',PORT=15431,primary=true);
alter node db_2 with(TYPE=datanode,HOST='192.168.1.7',PORT=15432,primary=false);
select pgxc_pool_reload();
select * from pgxc_node;

如果是第一次运行,drop相关的步骤也可以不运行,运行完之后,就可以看到多个节点正常的运行起来了。注意,一定要每个协调者节点都运行如上的脚本,否则可能在建数据库的时候报错12

1
2
3
4
5
6
7
postgres=# create database test;
ERROR: No Datanode defined in cluster
HINT: You need to define at least 1 Datanode with CREATE NODE.
STATEMENT: create database test;
ERROR: No Datanode defined in cluster
STATEMENT: create database test;
ERROR: No Datanode defined in cluster

另外,可以将上述脚本保存成文件pgxc_register.sql,并在之前的启动脚本之后加上注册步骤,每次启动的时候即可自动完成,如下

1
2
3
4
sleep 2s
psql -d postgres -p 1921 -f pgxc_register.sql
psql -d postgres -p 1922 -f pgxc_register.sql

下面做一些简单的建表测试,先登陆协调节点1,新增数据库,建表,并插入4笔数据,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[pgxc@anzhy ~]$ psql -d postgres -p 1921
psql (PGXC 1.0.4, based on PG 9.1.13)
Type "help" for help.
postgres=# create database test;
CREATE DATABASE
postgres=# \c test
You are now connected to database "test" as user "pgxc".
test=# create table test_table(id int);
CREATE TABLE
test=# insert into test_table values(1);
INSERT 0 1
test=# insert into test_table values(2);
INSERT 0 1
test=# insert into test_table values(3);
INSERT 0 1
test=# insert into test_table values(4);
INSERT 0 1
test=# commit;
COMMIT
test=# select count(*) from test_table;
count
-------
4
(1 row)

然后登陆协调节点2,查询刚才新增的表中的数据,发现已经可以查到了,

分别登陆数据节点1和2,发现数据分散在这2个节点上,每个节点上2条数据,

至此,Postgres XC的集群搭建已经成功。如果要使用Postgres XL的话,步骤非常类似。

文章目录

欢迎来到Valleylord的博客!

本博的文章尽量原创。