2015年(55)
分类: LINUX
2015-01-22 10:53:59
PostgreSQL是一款开源的SQL数据库,支持标准SQL,用户可以通过JDBC驱动连接PostgreSQL进行应用程序开发。用户通过 扩展PostgreSQL功能,让开发者可以使用SQL语句访问SequoiaDB数据库,完成SequoiaDB数据库的增、删、查、改操作。本文就针 对如何扩展PostgreSQL功能,实现PostgreSQL对接SequoiaDB进行介绍。
1 部署PostgreSQL
本教程为PostgreSQL与SequoiaDB的对接教程,所以作者建议使用者在sdbadmin用户下(SequoiaDB数据库默认用户)安装并使用PostgreSQL(本教程使用的PostgreSQL版本为9.3.4)。
1)源码编译PostgreSQL
下载链接:
解压后编译安装(需要root权限)
$> tar -zxvf postgresql-9.3.4.tar.gz $> cd postgresql-9.3.4/ $> ./configure && make && make install
$>su - sdbadmin
$>cp -rf /usr/local/pgsql ~/
$>cd pgsql
5)环境变量添加PostgreSQL的lib库
$>export LD_LIBRARY_PATH=$(pwd)/lib:${LD_LIBRARY_PATH}
建议用户将PostgreSQL的lib加到sdbadmin用户的环境变量中,否则每次登陆sdbadmin使用PostgreSQL,都需要手工添加PostgreSQL的lib 到 LD_LIBRARY_PATH中
$> echo "export LD_LIBRARY_PATH=$(pwd)/lib:${LD_LIBRARY_PATH}" >> ~/.bash_profile
$>mkdir pg_data
$>bin/initdb -D pg_data/
1.2安装SequoiaDB-PostgreSQL插件
**1)
创建PostgreSQL的lib 目录**获取PostgreSQL的libdir路径
$> PGLIBDIR=$(bin/pg_config --libdir)
如果显示的libdir目录不存在,则需要用户自己手工创建目录
$> mkdir -p ${PGLIBDIR}
2)创建PostgreSQL的extension目录
获取PostgreSQL的sharedir路径
$> PGSHAREDIR=$(bin/pg_config --sharedir)
在shardir目录上再创建extemsion目录
$> mkdir -p ${PGSHAREDIR}/extension
3)从SequoiaDB的安装包中,拷贝PostgreSQL的扩展文件
从SequoiaDB安装后的postgresql目录中拷贝sdb_fdw.so文件到PostgreSQL的lib目录,SequoiaDB默认安装目录为/opt/sequoiadb
$> cp -f /opt/sequoiadb/postgresql/sdb_fdw.so ${PGLIBDIR}
4)将sdb_fdw.control和sdb_fdw--1.0.sql脚本拷贝到extension目录中,两个脚本需要用户手工编辑
$> cp -f sdb_fdw.control ${PGSHAREDIR}/extension/ ; $> cp -f sdb_fdw--1.0.sql ${PGSHAREDIR}/extension/ ;
# sdb_fdw extension comment = 'foreign data wrapper for SequoiaDB access' default_version = '1.0' module_pathname = '$libdir/sdb_fdw' relocatable = true
/* contrib/mongo_fdw/sdb_fdw--1.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION sdb_fdw" to load this file. \quit CREATE FUNCTION sdb_fdw_handler() RETURNS fdw_handler AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION sdb_fdw_validator(text[], oid) RETURNS void AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FOREIGN DATA WRAPPER sdb_fdw HANDLER sdb_fdw_handler VALIDATOR sdb_fdw_validator;
1.3 部署PostgreSQL
1)
检查端口是否被占用PostgreSQL默认启动端口为”5432”,检查端口是否被占用(检查操作建议使用root用户操作,只有检查端口需要root权限,其余操作还是需要在sdbadmin用户下操作)
$>netstat -nap | grep 5432
如果5432端口被占用或者希望修改PostgreSQL的启动端口,则执行:
$> sed -i "s/#port = 5432/port = 11780/g" pg_data/postgresql.conf
2)启动Postgresql服务进程(需要使用sdbadmin用户执行以下命令)
$> bin/postgres -D pg_data/ >> logfile 2>&1 &
3)检查PostgreSQL是否启动成功
执行命令:
$> netstat -nap | grep 5432
结果为:
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 20502/postgres unix 2 [ ACC ] STREAM LISTENING 40776754 20502/postgres /tmp/.s.PGSQL.5432
4)创建PostgreSQL的database
$> bin/createdb -p 5432 foo
5)进入PostgreSQL 环境
$> bin/psql -p 5432 foo
2 PostgreSQL连接SequoiaDB
以下操作均在PostgreSQL shell 环境下执行
2.1 PostgreSQL与SequoiaDB建立关联
1)加载SequoiaDB连接驱动
foo=# create extension sdb_fdw;
2)配置与SequoiaDB连接参数
foo=# create server sdb_server foreign data wrapper sdb_fdw options(address '192.168.30.182', service '11810', user 'sdbadmin', password 'cmbc123');
3)关联SequoiaDB的集合空间与集合
注:集合空间与集合必须已经存在于SequoiaDB,否则查询出错。
默认情况下,表的字段映射到SequoiaDB中为小写字符,如果强制指定字段为大写字符,创建方式参考注意事项1
映射SequoiaDB 的数组类型,创建方式参考注意事项2
foo=# create foreign table test (name text, id numeric) server sdb_server options ( collectionspace 'chen', collection 'test' ) ;
foo=# select * from test;
foo=# insert into test values('one',3);
foo=# update test set id=9 where name='one';
7)查看所有的表(show tables;)
foo=# \d
8)查看表的描述信息
foo=# \d test
foo=# drop foreign table test;
10)退出PostgreSQL shell环境
foo=# \q
2.2 使用须知
2.2.2 注意事项
1)注意字符的大小写
SequoiaDB 中的集合空间、集合和字段名均对字母的大小写敏感
假设SequoiaDB 中存在名为TEST的集合空间,CHEN的集合,在PostgreSQL中建立相应的映射表
foo=# create foreign table sdb_upcase_cs_cl (name text) server sdb_server options ( collectionspace 'TEST', collection 'CHEN' ) ;
假设SequoiaDB 中存在名为foo的集合空间,bar的集合,而且保存的数据为:
{ "_id": { "$oid":"53a2a0e100e75e2c53000006" }, "NAME": "test" }
在PostgreSQL中建立相应的映射表
foo=# create foreign table sdb_upcase_field (“NAME” text) server sdb_server options ( collectionspace 'foo', collection 'bar' ) ;
执行查询命令:
foo=# select * from sdb_upcase_field;
查询结果为:
NAME ------ test (1 rows)
假设SequoiaDB中存在foo集合空间,bar集合,保存记录为:
{ "_id": { "$oid":"53a2de926b4715450a000001" }, "name": [ 1, 2, 3 ], "id": 123 }
在PostgreSQL 中建立相应的映射表
foo=# create foreign table bartest (name numeric[], id numeric) server sdb_server options ( collectionspace 'foo', collection 'bar' ) ;
执行查询命令:
foo=# select * from bartest;
查询结果:
name | id ---------+----- {1,2,3} | 123
如果PostgreSQL连接的SequoiaDB 协调节点重启,在查询时报错
ERROR: Unable to get collection "chen.test", rc = -15 HINT: Make sure the collectionspace and collection exist on the remote database
解决方法:
退出PostgreSQL shell
foo=# \q
重新进入PostgreSQL shell
$> bin/psql -p 5432 foo
2.2.3 调整PostgreSQL配置文件
1)查看pg_shell中默认的配置
执行命令:
foo=#\set
结果为:
AUTOCOMMIT = 'on' PROMPT1 = '%/%R%# ' PROMPT2 = '%/%R%# ' PROMPT3 = '>> ' VERBOSITY = 'default' VERSION = 'PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973], 64-bit' DBNAME = 'foo' USER = 'sdbadmin' PORT = '5432' ENCODING = 'UTF8'
foo=#\set FETCH_COUNT 100
调整为每次ps_shell每次获取100 条记录立即返回记录,然后再继续获取。
直接在pg_shell中修改配置文件,只能在当前pg_shell中生效,重新登录pg_shell需要重新设置。
执行命令:
$> ${PG_HOME}/bin/pg_config -sysconfdir
结果为:
/opt/sequoiadb/pgsql/etc
如果显示目录不存在,自己手动创建即可
$> mkdir -p /opt/sequoiadb/pgsql/etc
将需要修改的参数写入配置文件中
$>echo "\\set FETCH_COUNT 100" >> /opt/sequoiadb/pgsql/etc/psqlrc
$>sed -i 's/#client_min_messages = notice/client_min_messages = debug1/g' pg_data/postgresql.conf
$>sed -i 's/#log_min_messages = warning/log_min_messages = debug1/g' pg_data/postgresql.conf
3 使用客户端连接PostgreSQL
1)修改PostgreSQL的监听地址
$>sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '0.0.0.0'/g" pg_data/.conf
$>linenum=$(cat -n pg_data/pg_hba.conf | grep "# IPv4 local connections:" | awk '{print $1}'); \ let "linenum=linenum+1";varStr="host all all 0.0.0.0/0 trust"; \ sed -i "${linenum} a${varStr}" pg_data/pg_hba.conf;
$>bin/pg_ctl stop -s -D pg_data/ -m fast; bin/postgres -D pg_data/ >> logfile 2>&1 &
package com.sequoiadb.sample; import java.sql.*; public class postgresql_sample { static{ try { Class.forName"org.postgresql.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main( String[] args ) throws SQLException{ String pghost = "192.168.30.182"; String port = "5432"; String databaseName = "foo"; // postgresql process is running in which user String pgUser = "sdbadmin"; String url = "jdbc:postgresql://"+pghost+":"+port+"/" + databaseName; Connection conn = DriverManager.getConnection(url, pgUser, null); Statement stmt = conn.createStatement(); String sql = "select * from sdb_upcase_field "; ResultSet rs = stmt.executeQuery(sql); boolean isHeaderPrint = fae; while (rs.next()) { ResultSetMetaData md = rs.getMetaData(); int col_num = md.getColumnCount(); if (isHeaderPrint){ for (int i = 1; i <= col_num; i++) { System.out.print(md.getColumnName(i) + "|"); isHeaderPrint = true; } } for (i = 1; i <= col_num; i++) { System.out.print(rs.getString(i) + "|"); } System.out.print(); } stmt.close(); conn.close(); } }