由於網路上各個紀錄都大同「小異」,有些小差異又會令人頭昏腦脹,找不到錯誤,所以這裡會盡量把想的到的資訊都紀錄起來 ...
環境:Google 雲端 VM(Cloud Console)
環境:Google 雲端 VM(Cloud Console)
Oracle XE 11gR2
|
EPAS 9.6.3
| |
OS
|
CentOS 7.2
|
CentOS 7.2
|
CPU
|
n1-standard-1
|
f1-micro
|
RAM
|
1.7 GB
|
0.6 GB
|
內網 IP
|
10.128.0.3
|
10.146.0.2
|
SID / Database
|
XE
|
edb
|
設定的原理上,主要是利用 Oracle 的 ODBC DBLink 功能 dg4odbc(在 Oracle 10 則是 hsodbc),透過 Oracle 所在主機上面的 ODBC 設置,連線到異質資料庫。除了 PostgreSQL 之外,這個功能其實也能連到其他有提供 ODBC Driver 的資料庫,例如 MySQL 或是 MS SQL Server 等。
第一步是在 Oracle 資料庫主機上面裝 EDB 的 ODBC Driver。
這一步會有問題是,*nix 上面的 ODBC 界面使用的是 unixODBC 專案(另外的 iODBC 專案「好像」和 Oracle 有芥蒂吧,沒有試出來~)。但是該專案在 unixODBC-2.2.12 到 unixODBC-2.2.14 之間發生了 API 的變動,因此各 ODBC Driver 也就分成兩個世代了。具體來說,就是 Shared Object 版本差別;unixODBC-2.2.12 提供 libodbc.so.1,而 unixODBC-2.2.14 則提供 libodbc.so.2,並且自己弄 Soft Link 也不適用。
這一步會有問題是,*nix 上面的 ODBC 界面使用的是 unixODBC 專案(另外的 iODBC 專案「好像」和 Oracle 有芥蒂吧,沒有試出來~)。但是該專案在 unixODBC-2.2.12 到 unixODBC-2.2.14 之間發生了 API 的變動,因此各 ODBC Driver 也就分成兩個世代了。具體來說,就是 Shared Object 版本差別;unixODBC-2.2.12 提供 libodbc.so.1,而 unixODBC-2.2.14 則提供 libodbc.so.2,並且自己弄 Soft Link 也不適用。
在 CentOS 5.x 的生命週期時(今日已經 EOL 的版本)恰逢這變動,因此在該版的 YUM Repo 之中,最後(逝亡前)提供了兩個最新版本的 RPM 檔:unixODBC-2.2.12 以及 unixODBC64-2.2.14。以下為「截圖」;此外,企業版的 ODBC 驅動依賴的 glibc 函式庫(glibc >= 2.7)沒辦法支援到 RHEL 5.x 當時的版本(glibc-2.5),因此只可以用原本所提供的 postgresql-odbc64 的安裝檔,不然就要自行使用postgresql-odbc64 的 SRPM (postgresql-odbc64-09.00.0200-1.el5.src.rpm)更新 Driver 並編譯 . . .
所以,如果用太舊的 OS 就要注意一下~
在這裡我不用擔心這種問題:直接在 Oracle 所在的 Linux 主機安裝 unixODBC
bash-4.2$ sudo yum install unixODBC
並安裝 EDB 的 Connector 程式,我們可從下圖頁面下載
或是也可以用 CentOS 內建提供的,只是稍微舊了一些:
bash-4.2$ sudo yum install postgresql-odbc
在這裡進行企業版的 ODBC Driver 安裝
bash-4.2$ sudo setenforce 0 bash-4.2$ chmod +x ./edb-connectors-9.6.0.3-2-linux-x64.run bash-4.2$ sudo ./edb-connectors-9.6.0.3-2-linux-x64.run --mode text bash-4.2$ sudo setenforce 1
安裝後,ODBC Driver 位在 /opt/edb/connectors/odbc 裡面
接著設定 unixODBC 的參數檔:總共有兩個設定檔要處理。
1. /etc/odbcinst.ini 設定 Driver 資訊(安裝精靈已經協助設定完畢~)
. . . ( 略 )
[enterprisedb]
Description=EDB Postgres Advanced Server ODBC driver
Driver=/opt/edb/connectors/odbc/lib/edb-odbc.so
Setup=/opt/edb/connectors/odbc/lib/libodbcedbS.so
UsageCount=1
安裝內建 RPM 的人,可以參考相關的 SRPM 的 Readme 會提供設置範例。
2. /etc/odbc.ini 設定連線資訊
[edb_test] Driver=enterprisedb Description=Connection to edb database on the host edbvm Servername=10.146.0.2 Port=5444 Username=enterprisedb Password=edb_password Database=edb ReadOnly=no
上面紅字的 Driver 指的是 odbcinst.ini 中的 Driver 區塊標籤名稱
補上兩個參數檔的權限(應該是和設置 DBLink 關係不大,仍在此處附上)
bash-4.2$ ls -l /etc/odbc* -rw-r--r--. 1 root root 180 Jul 20 14:25 /etc/odbc.ini -rw-r--r--. 1 root root 744 Jul 20 14:22 /etc/odbcinst.ini
接著要先對 ODBC 測通:使用 unixODBC 的連線指令 isql 進行:記得測通前,要確定 EDB 的 pg_hba.conf 要允許 Oracle 主機所在網段可以登入才行
bash-$ isql -vv edb_test +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
如果沒有上面畫面,就是出錯了~~
ODBC 打通之後,接著就是 Oracle ODBC Gateway 的設定了。
設定上,主要有三個 Oracle 的設定檔要設置,以便讓 Oracle 相關程式可以存取 EDB
bash-4.2$ echo $ORACLE_HOME /u01/app/oracle/product/11.2.0/xe bash-4.2$ ls $ORACLE_HOME/hs/admin/ initdg4odbc.ora listener.ora.sample tnsnames.ora.sample bash-4.2$ ls $ORACLE_HOME/network/admin/ listener.ora samples tnsnames.ora
我們所要設定的是 $ORACLE_HOME/hs/admin/initdg4odbc.ora 以及 $ORACLE_HOME/network/admin/{listener.ora,tnsnames.ora},分別是 Oracle 透過ODBC 界面存取外部資料庫的設置(initdg4odbc.ora,Database Gareway for ODBC),一個提供 EDB 被 Oracle 連線的 Oracle Listener 界面(listener.ora,讓人家來聽的),以及 Oracle 一般連線資訊的設定(tnsnames.ora,去聽人家的)。
在此處,我們需要自行複製並命名一個 initdg4odbc.ora 的設定檔,其中的檔案名稱有規定,格式上需要為 initsid.ora,其中的 sid 是後面填寫 listener.ora 時打算填的 sid,這裡不仿叫做 initdg4edb.ora;然後在 listener.ora 作一個 ODBC-EDB 的 Listener;最後在 tnsnames.ora 增加 EDB 的連線資訊
bash-4.2$ cat /u01/app/oracle/product/11.2.0/xe/hs/admin/initdg4edb.ora # # HS init parameters # HS_FDS_CONNECT_INFO = edb_test HS_FDS_TRACE_LEVEL = OFF HS_FDS_SHAREABLE_NAME = /usr/lib64/libodbc.so #HS_FDS_DEFAULT_SCHEMA_NAME=public HS_LANGUAGE=AMERICAN_AMERICA.we8iso8859P1 # # ODBC specific environment variables # set ODBCINI=/etc/odbc.ini # # Environment variables required for the non-Oracle system # #set=
bash-4.2$ cat /u01/app/oracle/product/11.2.0/xe/network/admin/listener.ora # listener.ora Network Configuration File: SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = /u01/app/oracle/product/11.2.0/xe) (PROGRAM = extproc) ) (SID_DESC = (SID_NAME = dg4edb) (ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe) (PROGRAM=dg4odbc) #(ENVS="LD_LIBRARY_PATH=/opt/edb/connectors/odbc/lib/") ) ) LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE)) (ADDRESS = (PROTOCOL = TCP)(HOST = oraxe)(PORT = 1521)) ) ) DEFAULT_SERVICE_LISTENER = (XE)
bash-4.2$ cat /u01/app/oracle/product/11.2.0/xe/network/admin/tnsnames.ora # tnsnames.ora Network Configuration File: XE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oraxe)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE) ) ) epas96 = (DESCRIPTION= (ADDRESS = (PROTOCOL = TCP)(HOST=oraxe)(PORT=1521)) (CONNECT_DATA= (SID=dg4edb) ) (HS=OK) ) EXTPROC_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE)) ) (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO) ) )
注意
- epas96 這個 tnsname 聽的 IP 位置是 Oracle 自己這台的 IP,因為 ODBC 是在這裡啟動的;而不是填 EDB 的主機 IP
- initdg4odbc.ora 設置上發生錯誤的話,熟悉 Oracle 的人可以考慮設定 HS_FDS_TRACE_LEVEL 成 255 或 DEBUG 以啟用紀錄以進行除錯
- 另外,有些資料紀錄 initdg4odbc.ora 的參數 HS_FDS_SHAREABLE_NAME 設定成 PostgreSQL ODBC Driver,在這裡採納設定成 ODBC Driver Manager 的函式庫
- 還有,initdg4odbc.ora 裡面的 HS_LANGUAGE 這個不起眼的參數是關鍵,沒有設定好就會失敗!(而且好像還有分大小寫,有待各位實際試試)
- listener.ora 中的 ENVS 不一定要設定,至少此處使用正常
設置完,重新載入 Oracle 的 Listenrer,然後用 Oracle 的 tnsping 測通(這個測通並不是正常運作的直接保證,但可以用來確認 listener 和 tnsname 有沒有設定錯)
bash-4.2$ lsnrctl reload LSNRCTL for Linux: Version 11.2.0.2.0 - Production on 21-JUL-2017 14:10:46 Copyright (c) 1991, 2011, Oracle. All rights reserved. Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE))) The command completed successfully bash-4.2$ tnsping epas96 TNS Ping Utility for Linux: Version 11.2.0.2.0 - Production on 21-JUL-2017 14:11:06 Copyright (c) 1997, 2011, Oracle. All rights reserved. Used parameter files: Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION= (ADDRESS = (PROTOCOL = TCP)(HOST=oraxe)(PORT=1521)) (CONNECT_DATA= (SID=dg4edb)) (HS=OK)) OK (0 msec)
成功之後,就可以用 DBLink 了:以下為 Oracle DBLink 存取 EDB 裡面的範例表格為例:注意以下的帳號、密碼、表格名稱(還有欄位名稱)都要作雙引號固定小寫才行(在 Oracle 預設大寫,送到客戶端的指令中的物件名稱會被雙引號固定成大寫)~
bash-4.2$ sqlplus /nolog SQL*Plus: Release 11.2.0.2.0 Production on Fri Jul 21 14:20:20 2017 Copyright (c) 1982, 2011, Oracle. All rights reserved. SQL> conn hr/hr Connected. SQL> CREATE DATABASE LINK edblink CONNECT TO "enterprisedb" IDENTIFIED BY "edb" USING 'epas96'; Database link created. SQL> SELECT * FROM "dept"@edblink; deptno ---------- dname -------------------------------------------------------------------------------- loc -------------------------------------------------------------------------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS deptno ---------- dname -------------------------------------------------------------------------------- loc -------------------------------------------------------------------------------- 30 SALES CHICAGO 40 OPERATIONS deptno ---------- dname -------------------------------------------------------------------------------- loc -------------------------------------------------------------------------------- BOSTON SQL>
總算是設置完成。這個設置,多謝有 Oracle 高手相助,不然也無法設定成功~
經過測試,發現 Oracle 對異質資料庫的 DBLink,有一個不支援的用法:當我們在 Oracle 裡面執行以下方式的資料輸入會發生錯誤
INSERT INTO "table_on_edb"@"edblink" SELECT * FROM table_on_oracle;
下面是兩個總結表
一)Oracle ODBC DBLink 作 INSERT INTO ^^^ SELECT * FROM ^^^^; 的資料輸入
INSERT INTO ^^^ ⇒
|
test_o
|
"test_e"@"edblink"
|
SELECT * FROM ^^^
| ||
test_o
|
OK (Trivial)
|
ORA-02025 ERROR
|
"test_e"@"edblink"
|
OK
|
OK
|
二)EDB OCI DBLink 作 INSERT INTO ^^^ SELECT * FROM ^^^^; 的資料輸入
INSERT INTO ^^^ ⇒
|
test_e
|
test_o@oralink
|
SELECT * FROM ^^^
| ||
test_e
|
OK (Trivial)
|
OK
|
test_o@oralink
|
OK
|
OK
|
最後,關於 RHEL5 上面安裝上遇到的問題的解決(!),主要是去看一看 SRPM 裡面的 Readme 才能得知解法。所以有時候,Readme 是很重要的~~
參考資料
Josemar Furegatti de Abreu Silva: How to create database link between Oracle XE 11 vs PostgreSQL 9.3
其他類似的,只是連到其他類資料庫
一堆找錯誤的紀錄. . .
ORA-28500: connection from ORACLE to a non-Oracle system returned this message: ORA-02063: preceding line from
沒有留言:
張貼留言