athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

PostgreSQLからOracleに接続するためのoracle_fdwをインストールした時にはまったこと

やまだです。

ある日、PostgreSQLOracleのテーブルを参照したい、との依頼を受けて作業したのですが、 その際にはまった点などもあったので、誰かの役に立つこともあるかもしれない、というわけで書き留めておきます。

使用したのは下記、PostgreSQLの拡張になります。

PostgreSQLは9.5です。

oracle_fdwのインストール

ダウンロード~インストール(make install)

とっても簡単。

curl -O https://github.com/laurenz/oracle_fdw/archive/ORACLE_FDW_1_4_0.zip
unzip oracle_fdw-ORACLE_FDW_1_4_0.zip
cd oracle_fdw-ORACLE_FDW_1_4_0/
make
make install

以上で、PostgreSQLのインストール先にライブラリが入ります。

もしこの辺でうまくいかなかったらREADME.oracle_fdw の下記のあたりとか怪しいかもしれないです。

oracle_fdw has been written as a PostgreSQL extension and uses the Extension Building Infrastructure "PGXS". It should be easy to install.

You will need PostgreSQL headers and PGXS installed (if your PostgreSQL was installed with packages, install the development package). You need to install Oracle's C header files as well (SDK package for Instant Client).

Make sure that PostgreSQL is configured "--without-ldap" (at least the server). See "Problems" below.

Make sure that "pg_config" is in the PATH (test with "pg_config --pgxs"). Set the environment variable ORACLE_HOME to the location of the Oracle installation.

https://github.com/laurenz/oracle_fdw/blob/master/README.oracle_fdw#L522-L538

PostgreSQLでの作業(CREATE EXTENSION)

CREATE EXTENSIONでエラーが発生する場合

下記のようなエラーが起きることがあります(というか起きました)。

ERROR: ライブラリ"/usr/pgsql-9.5/lib/oracle_fdw.so"をロードできませんでした: libclntsh.so.12.1: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません

実際にはそのファイルは存在し、postgresユーザも参照可能(参照できない場合はchmod 775とかしとく)なのに、見れない。なぜ。。。 しばらく悩んで本家のGitHubのissueを見つけた。OSSバンザイ。

https://github.com/laurenz/oracle_fdw/issues/64

以下適当な訳。

Q:LD_LIBRARY_PATHやORACLE_HOMEは設定したはずなのにつながらないよ! A:ほんとに?PostgreSQL server process (postmaster).の環境変数確認してみ? cat /proc/<pid>/environ | xargs -0 -n 1

Q:ありがと!確認してみる!

Q:あ、設定できてなかったから.bash_profileに設定してみたよ。 そしたら動いたよ。ありがと。

A:手動で開始した場合はシェルの環境変数引き継いじゃうけど startup scriptとかで起動した場合は引き継がないです。 なので、PostgreSQLの起動スクリプト内の変数を設定することをお勧めします。 前に言ったように、ldconfigをを使用すると、さらにいいよ。

まんまと質問者の状況と同じでした。

作業時はシェル上でexport環境変数を設定し、そのままpsqlCREATE EXTENSION ...を実施した。 その後、PostgreSQLを再起動したため、必要な環境変数が未設定の状態で起動したことが原因。

というわけで、.bash_profileへ追加してもいいのだけど、 今回はldconfigを使用するため/etc/ld.so.conf.d/oracle.confに下記を追加。

echo "/opt/oracle/app/oracle/product/12.1.0/client_1/lib/" >> /etc/ld.so.conf.d/oracle.conf
ldconfig

なお、ldconfig実行時に下記のメッセージが出たが、oracle_fdwとしては問題ない模様。

ldconfig: /opt/oracle/app/oracle/product/12.1.0/client_1/lib/libexpat.so.1 はシンボリックリンクではありません

以上を実施後、念のためsystectl restart postgresql-9.5として再起動しても問題無いことも確認しました。

外部表作成時にエラーが発生する場合

よしよし、じゃあ外部表作っちゃうぞー。

ERROR: error connecting to Oracle: OCIEnvCreate failed to create environment handle

なんかやっぱり環境変数回りで失敗してる模様。仕方がないのでpotgresユーザの.bash_profileに書いたが、反映されず。 なのでsystemctlが使用する/usr/lib/systemd/system/postgresql-9.5.serviceをいじって下記の行を追加した。

  • Environment=ORACLE_HOME=/opt/oracle/app/oracle/product/12.1.0/client_1
  • Environment=LD_LIBRARY_PATH=/opt/oracle/app/oracle/product/12.1.0/client_1/lib
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades.  If you want to customize, the
# best way is to create a file "/etc/systemd/system/postgresql-9.5.service",
# containing
#       .include /lib/systemd/system/postgresql-9.5.service
#       ...make your changes here...
# For more info about custom unit files, see
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F

# Note: changing PGDATA will typically require adjusting SELinux
# configuration as well.

# Note: do not use a PGDATA pathname containing spaces, or you will
# break postgresql-setup.
[Unit]
Description=PostgreSQL 9.5 database server
After=syslog.target
After=network.target

[Service]
Type=forking

User=postgres
Group=postgres

# Note: avoid inserting whitespace in these Environment= lines, or you may
# break postgresql-setup.

# Location of database directory
Environment=PGDATA=/var/lib/pgsql/9.5/data/
Environment=ORACLE_HOME=/opt/oracle/app/oracle/product/12.1.0/client_1
Environment=LD_LIBRARY_PATH=/opt/oracle/app/oracle/product/12.1.0/client_1/lib

# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog

# Disable OOM kill on the postmaster
OOMScoreAdjust=-1000

ExecStartPre=/usr/pgsql-9.5/bin/postgresql95-check-db-dir ${PGDATA}
ExecStart=/usr/pgsql-9.5/bin/pg_ctl start -D ${PGDATA} -s -w -t 300
ExecStop=/usr/pgsql-9.5/bin/pg_ctl stop -D ${PGDATA} -s -m fast
ExecReload=/usr/pgsql-9.5/bin/pg_ctl reload -D ${PGDATA} -s

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

[Install]
WantedBy=multi-user.target

その後、systemctl restart postgresql-9.5.serviceとしたら

Warning: postgresql-9.5.service changed on disk. Run 'systemctl daemon-reload' to reload units.

と、警告されたので、警告通りsystemctl daemon-reloadで、 再度systemctl restart postgresql-9.5.serviceを実行。

後はPostgeSQLでの外部表作成、およびデータもちゃんと見れました。 作業完了~。