やまだです。
ある日、PostgreSQLでOracleのテーブルを参照したい、との依頼を受けて作業したのですが、 その際にはまった点などもあったので、誰かの役に立つこともあるかもしれない、というわけで書き留めておきます。
使用したのは下記、PostgreSQLの拡張になります。
- Foreign Data Wrapper for Oracle: Project Home Page
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
で環境変数を設定し、そのままpsql
でCREATE 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での外部表作成、およびデータもちゃんと見れました。 作業完了~。