1 部署 PostgreSQL 1.1 安装 PostgreSQL 本教程为 PostgreSQL 与 SequoiaDB 的对接教程, 所以作者建议使用者在 sdbadmin 用户下 (SequoiaDB 数据库默认用户 ) 安装并使用 PostgreSQL( 本教程使用 PostgreSQL 9.3.4 版本 ) 1 源码编译 PostgreSQL 下载链接 :http://www.postgresql.org/ftp/source/ 解压后编译安装 ( 需要 root 权限 ) $>tar - zxvf postgresql- 9.3.4.tar.gz $>cd postgresql- 9.3.4/ $>./configure && make && make install PostgreSQL 的默认安装路径为 /usr/local/pgsql 2 切换用户 $>su - sdbadmin 3 拷贝 PostgreSQL 文件 $>cp - rf /usr/local/pgsql ~/ 4 进入 PostgreSQL 目录 $>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 6 创建 PostgreSQL 的数据目录 $>mkdir pg_data 7 初始化数据目录 ( 该操作只能操作一次 ) $>bin/initdb - D pg_data/ 1
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 ${SDBADMIN_HOME/postgresql/sdb_fdw.so ${PGLIBDIR 4 将 sdb_fdw.control 和 sdb_fdw- - 1.0.sql 脚本拷贝到 extension 目录中, 两个脚本需要用户手工编辑 $>cp - f sdb_fdw.control ${PGSHAREDIR/extersion ; $>cp - f sdb_fdw- - 1.0.sql ${PGSHAREDIR/extersion ; sdb_fdw.control 脚本内容 # sdb_fdw extension comment = 'foreign data wrapper for SequoiaDB access' default_version = '1.0' module_pathname = '$libdir/sdb_fdw' relocatable = true sdb_fdw- - 1.0.sql 脚本内容 /* contrib/mongo_fdw/sdb_fdw- - 1.0.sql */ - - complain if script is sourced in psql, rather than via CREATE EXTENSION 2
\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 用户操作 ) $> netstat - nap grep 5432 如果 5432 端口被占用或者希望修改 PostgreSQL 的启动端口, 则执行 : $> sed - i "s/#port = 5432/port = 11780/g" pg_data/postgresql.conf 2 启动 Postgresql 服务进程 $> 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 3
/tmp/.s.pgsql.5432 4 创建 PostgreSQL 的 database $> bin/createdb - p 5432 foo 5 进入 PostgreSQL shell 环境 $> 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, preferedinstance s ); 注 : 1) 如果用户指定多个协调节点, 避免一个协调节点出现异常后,PostgreSQL 无法使用, 创建 server 时, 应该写成 foo=# create server sdb_server foreign data wrapper sdb_fdw options(address '192.168.30.182:11810,192.168.30.183:11810,192.168.30.184:11810', service '', user 'sdbadmin', password 'cmbc123'); address 参数变成 hostname1:service1,hostname2:service2 ; 用户需要指定 service 为空字符串 ; 如果 SequoiaDB 没有建立用户密码登陆, 可以忽略 user 和 password 参数 2) preferedinstance 参数, 指定 PostgreSQL 访问 SequoiaDB 数据节点时, 优先连接哪种角色的数据节点, 默认为 s, 可输入参数 m / M / s / S / a / A /1-7, 分别表示 master/slave/anyone/node1- node7 3. 关联 SequoiaDB 的集合空间与集合 4
注 : 集合空间与集合必须已经存在于 SequoiaDB, 否则查询出错 默认情况下, 表的字段映射到 SequoiaDB 中为小写字符, 如果强制指定字段为大写字符, 创建方式参考注意事项 1 映射 SequoiaDB 的数组类型, 创建方式参考注意事项 2 foo=# create foreign table test (name text, id numeric) server sdb_server options ( collectionspace 'chen', collection 'test' ) ; 4. 查询 foo=# select * from test; 5. 写入数据 foo=# insert into test values('one',3); 6. 更改数据 foo=# update test set id=9 where name='one'; 7. 查看所有的表 (show tables;) foo=# \d 8. 查看表的描述信息 foo=# \d test 9. 删除表 foo=# drop foreign table test; 10. 退出 PostgreSQL shell 环境 foo=# \q 2.2 使用须知 2.2.1 数据类型的对应关系 SequoiaDB string String String int/double/long int int/double PostgreSQL text char/char(n) varchar/varchar(n) numeric int float 5
date date binary bytea timestamp timestamp array TYPE[] sample:text[] boolean boolean null text 2.2.2 注意事项 1 注意字符的大小写 SequoiaDB 中的集合空间 集合和字段名均对字母的大小写敏感 1) 集合空间 集合名大写假设 SequoiaDB 中存在名为 TEST 的集合空间,CHEN 的集合, 在 PostgreSQL 中建立相应的映射表 foo=# create foreign table sdb_upcase_cs_cl (name text) server sdb_server options ( collectionspace 'TEST', collection 'CHEN' ) ; 2) 字段名大写假设 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 6
(1 rows) 2 映射 SequoiaDB 中的数据类型假设 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 3 连接 SequoiaDB 协调节点错误如果 PostgreSQL 连接的 SequoiaDB 协调节点重启, 在查询时报错 ERROR: HINT: Unable to get collection "chen.test", rc = - 15 Make sure the collectionspace and collection exist on the remote database 解决方法 : 退出 PostgreSQL shell foo=# \q 重新进入 PostgreSQL shell 7
$> 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' 2 调整 pg_shell 查询时, 每次获取记录数 foo=#\set FETCH_COUNT 100 调整为每次 ps_shell 每次获取 100 条记录立即返回记录, 然后再继续获取 直接在 pg_shell 中修改配置文件, 只能在当前 pg_shell 中生效, 重新登录 pg_shell 需要重新设置 3 修改配置文件, 调整 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 4 调整 pg_shell 的日志级别 $>sed -i 's/#client_min_messages = notice/client_min_messages = debug1/g' 8
pg_data/postgresql.conf 5 调整 pg 引擎的日志级别 $>sed -i 's/#log_min_messages = warning/log_min_messages = debug1/g' pg_data/postgresql.conf 3 使用 java 客户端连接 PostgreSQL 3.1 修改 PostgreSQL 的连接配置 1 修改 PostgreSQL 的监听地址 $>sed - i "s/#listen_addresses = 'localhost'/listen_addresses = '0.0.0.0'/g" pg_data/postgresql.conf 2 修改信任的机器列表 $>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; 3 重启 PostgreSQL $>bin/pg_ctl stop - s - D pg_data/ - m fast ; bin/postgres - D pg_data/ >> logfile 2>&1 & 3.2 JDBC 连接程序 package com.sequoiadb.sample; import java.sql.*; public class postgresql_sample { static{ try { Class.forName("org.postgresql.Driver"); 9
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 = false; 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 (int i = 1; i <= col_num; i++) { 10
System.out.print(rs.getString(i) + " "); System.out.println(); stmt.close(); conn.close(); 11