Webサイトのお助け隊

CentOS7 から unixODBC 使って Firebird へ接続した話

390 views
約16分

備忘録として

CentOS7+Apache2.4+php5.6っていう指定・・・もう古い

CentOS7インストール

ググればある!から省く

Apache2.4インストール

これもググれ!

PHP5.6インストール

こちらはPHPを切り替えたい要望なので、5.4~8.1までPHP-FPMで動作するよう実装

//Remiレポジトリをインストール
# yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
# yum install yum-utils
# yum-config-manager --enable remi

//php54、55、56、73、74、80、81をインストール
# for v in 54 55 56 73 74 80 81; do yum -y install php$v php$v-php-{gd,xml,mbstring,mysqlnd,embedded} ; done
# for v in 54 55 ; do yum -y install php$v-php-pecl-{apc,memcached} ; done
# for v in 56 73 74 80 81; do yum -y install php$v-php-{opcache,pecl-apcu,pecl-memcached} ; done

//php-fpmをインストール
# for v in 54 55 56 73 74 80 81; do yum -y install php$v-php-fpm ; done
# for v in 54 55 56 ; do sed -i '/pm = /s/dynamic/ondemand/' /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
# for v in 73 74 80 81; do sed -i '/pm = /s/dynamic/ondemand/' /etc/opt/remi/php$v/php-fpm.d/www.conf ; done
# for v in 54 55 56 ; do sed -i "s/9000/90$v/" /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
# for v in 73 74 80 81; do sed -i "s/9000/90$v/" /etc/opt/remi/php$v/php-fpm.d/www.conf ; done

//Apacheのバーチャルホストにした
# mkdir /home/ユーザー名/public_html/
# mkdir /home/ユーザー名/public_html/logs

//ディレクトリパス=/home/ユーザー名/public_html/
# cat /etc/httpd/conf.d/ユーザー名.conf
<VirtualHost *:80>
    ServerName ドメイン名
    DocumentRoot /home/ユーザー名/public_html/
    ErrorLog /home/ユーザー名/public_html/logs/php56-error.log
    CustomLog /home/ユーザー名/public_html/logs/php56-access.log combined
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9056"
    </FilesMatch>
</VirtualHost>

//PHP-FPMテイクオフ
# for v in 54 55 56 73 74 80 ; do systemctl start php$v-php-fpm ; systemctl enable php$v-php-fpm ; done

Firebird Driverを入れる

PHP7以上ならpdo_firebirdっていうモジュールを入れれば済む話
しかし、PHP5.6で動作させるにはライブラリがないので、ODBC経由で接続させなきゃいかん

まずは、Firebirdドライバーを入れる
ググれば楽勝モードだったのに、これが一番苦労した

ドライバーのダウンロード

http://www.firebirdsql.org/en/odbc-driver/

ODBC ドライバー 最新バージョン2.0.5のLinux AMD64 Libraryをダウンロード
ダウンロードリンクじゃなくて1画面前置きされたからwgetできない・・・面倒くさい

OdbcFb-LIB-2.0.5.156.amd64.gz

とりあえずこれを解凍解凍解凍…で、現れる libOdbcFb.so を/usr/lib/あたりにぶち込む

# mv OdbcFb-LIB-2.0.5.156/libOdbcFb.so /usr/lib/
# chmod 0755 /usr/lib/libOdbcFb.so

unixODBCをインストール

こちらは難しくないこれからが地獄

# yum -y install unixODBC unixODBC-devel

// odbcinst.iniの編集
// 末行に以下を追加
[Firebird]
Description=Firebird/InterBase(r) driver
Driver=/usr/lib/libOdbcFb.so
UsageCount=1

エラーのはじまりと対処

isqlで接続チェック!

# isql Firebird SYSDBA MASTERKEY -v
[01000][unixODBC][Driver Manager]Can't open lib '/usr/lib/libOdbcFb.so' : file not found
[ISQL]ERROR: Could not SQLConnect

なんかエラー吐いた・・・ファイルは存在するのにnot foundってちょっと何言ってるかわかんない

// ちょっとどちらを参照してるかldd コマンドでチェック
# ldd /usr/lib/libOdbcFb.so
        linux-vdso.so.1 =>  (0x00007ffdd66dd000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fef99630000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fef9942c000)
        libodbcinst.so.1 => not found
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fef98f12000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fef98c10000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fef989fa000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fef9862c000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fef98429000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fef99b82000)
        libltdl.so.7 => /lib64/libltdl.so.7 (0x00007fef9821f000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fef98003000)

あれ?libodbcinst.so.1ってとこだけ「not found」されてる
ls で探してみるとない?

# find / -name libodbcinst.so.1
//・・・無反応
//ディレクトリを見に行く!
# ls /usr/lib64/ | grep libodbcinst
libodbcinst.so
libodbcinst.so.2
libodbcinst.so.2.0.0

おや?libodbcinst.so.1だけがないやん!!
ググってみると、Firebirdのドライバからは.so.1を見に行ってまっせってこと・・・
しょうがないので、シンボリックリンクで代用でもしてみる!

# ln -s /usr/lib64/libodbcinst.so.2.0.0 /usr/lib64/libodbcinst.so.1

どないや?ってことで、もう一度isqlを試す!

# isql Firebird sysdba masterkey -v
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

やったー♪オーケーじゃん?終わりーーーお疲れっしたーあざっしたー
って思って、SQL文叩いてテスト

SQL>select b.RDB$FIELD_NAME FIELD_NAME, d.RDB$TYPE_NAME TYPE_NAME, c.RDB$FIELD_LENGTH FIELD_LENGTH, b.RDB$NULL_FLAG NULL_FLAG, case when (select y.RDB$CONSTRAINT_TYPE from rdb$relation_constraints y inner join rdb$index_segments z on y.RDB$INDEX_NAME=z.RDB$INDEX_NAME where z.RDB$FIELD_NAME = b.RDB$FIELD_NAME and y.RDB$RELATION_NAME=b.RDB$RELATION_NAME) LIKE 'PRIMARY%' then 1 else 0 end PRIMARY_KEY from RDB$RELATION_FIELDS b inner join RDB$FIELDS c on b.RDB$FIELD_SOURCE=c.RDB$FIELD_NAME inner join rdb$types d on c.RDB$FIELD_TYPE=d.RDB$TYPE and d.RDB$FIELD_NAME='RDB$FIELD_TYPE' where b.RDB$RELATION_NAME = 'テーブル名' order by b.RDB$FIELD_POSITION;
+--------------------------------+--------------------------------+-------------+----------+------------+
| FIELD_NAME                     | TYPE_NAME                      | FIELD_LENGTH| NULL_FLAG| PRIMARY_KEY|
+--------------------------------+--------------------------------+-------------+----------+------------+
| フィールド1                    | VARYING                        | 1           |          | 0          |
| フィールド2                    | VARYING                        | 1           |          | 0          |
+--------------------------------+--------------------------------+-------------+----------+------------+
SQLRowCount returns -4974962741
2 rows fetched
SQL>

(。´・ω・)ん? SQLRowCount returns -4974962741 ・・・?
2行しかないのに何の値?おかしくない?ここも「2」で終わるはずなんに・・・

何度やってもどのテーブルをSELECTしても同じ・・・
これ、やっぱりシンボリックリンクなんて騙してやってるから狂ってる?

ググってもこんなところを探す日本人はおらず、こんな面倒くさいことをやる人類もいない
やったけど情報を晒していないかな?

色々ググって、読めない英語頑張って、このURLにたどり着く・・・約6時間(むしろ遅くね?)

https://www.firebirdnews.org/howto-install-firebird-odbc-driver-for-unixodbc-from-source/

最新のソースからmakefileすればどうにかなるかな?

# tar -zxvf OdbcJdbc-src-2.0.5.156.tar.gz
# cd OdbcJdbc-src-2.0.5.156/OdbcJdbc/Builds/Gcc.lin
# make -f makefile.linux
../makefile.environ:6: ARCH is x86_64
../makefile.environ:21: ODBCMANAGER is unixODBC in /usr/lib64
../makefile.environ:50: FBINCDIR is /usr/include
../makefile.environ:56: FBLIBDIR is /usr/lib64
g++ -w -D_REENTRANT -D_PTHREADS -DEXTERNAL -DunixODBC -I/usr/include -I/usr/include -I/include -I/usr/include -fPIC -m64 -DNDEBUG -c ../../IscDbc/Attachment.cpp -o Release_x86_64/obj/Attachment.o
make: g++: コマンドが見つかりませんでした
//ここでつまずく
//g++はgcc-c++をインストールせよってググった♪
# yum -y install grep gcc-c++

//これでもう一回メイクユアハッピー
# make -f makefile.linux
//エラーなく終了・・・completeさえでなかったから不安

# cd Release_x86_64
# cp libOdbcFb.so /usr/lib/libOdbcFb.so

既存のlibOdbcFb.soのバックアップとるの忘れたと思ったけど、もう一回ダウンロードすればいいので先に進む

先ほどのlddコマンドで参照先を確認

# ldd /usr/lib/libOdbcFb.so
        linux-vdso.so.1 =>  (0x00007ffd02338000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f85a61f5000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f85a5ff1000)
        libodbcinst.so.2 => /lib64/libodbcinst.so.2 (0x00007f85a5ddf000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f85a5ad7000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f85a57d5000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f85a55bf000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f85a51f1000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007f85a4fee000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f85a6791000)
        libltdl.so.7 => /lib64/libltdl.so.7 (0x00007f85a4de4000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f85a4bc8000)

お?さっきのlibodbcinst.so.1がlibodbcinst.so.2になっとる!
シンボリックリンク作らないでも良いってことは・・・

SQL>select b.RDB$FIELD_NAME FIELD_NAME, d.RDB$TYPE_NAME TYPE_NAME, c.RDB$FIELD_LENGTH FIELD_LENGTH, b.RDB$NULL_FLAG NULL_FLAG, case when (select y.RDB$CONSTRAINT_TYPE from rdb$relation_constraints y inner join rdb$index_segments z on y.RDB$INDEX_NAME=z.RDB$INDEX_NAME where z.RDB$FIELD_NAME = b.RDB$FIELD_NAME and y.RDB$RELATION_NAME=b.RDB$RELATION_NAME) LIKE 'PRIMARY%' then 1 else 0 end PRIMARY_KEY from RDB$RELATION_FIELDS b inner join RDB$FIELDS c on b.RDB$FIELD_SOURCE=c.RDB$FIELD_NAME inner join rdb$types d on c.RDB$FIELD_TYPE=d.RDB$TYPE and d.RDB$FIELD_NAME='RDB$FIELD_TYPE' where b.RDB$RELATION_NAME = 'テーブル名' order by b.RDB$FIELD_POSITION;
+--------------------------------+--------------------------------+-------------+----------+------------+
| FIELD_NAME                     | TYPE_NAME                      | FIELD_LENGTH| NULL_FLAG| PRIMARY_KEY|
+--------------------------------+--------------------------------+-------------+----------+------------+
| フィールド1                    | VARYING                        | 1           |          | 0          |
| フィールド2                    | VARYING                        | 1           |          | 0          |
+--------------------------------+--------------------------------+-------------+----------+------------+
SQLRowCount returns 2
2 rows fetched
SQL>

やったー!なんとかなっとる=♪

ブラウザからも問題なく接続できてめでたしめでたし

まとめ

古いOSとかPHPは新しいので攻めようね♪

今回はお客様のフレームワークが古いために止む無くの決断トライでした。

About The Author

uiarb合同会社代表社員masahiro irabu
FacebookでシェアTwitterでシェアPinterestでシェア