0x00 問題場景
1. 環境配置
角色 | 名稱 | 版本 | 位數 | 備註 |
---|---|---|---|---|
數據庫 | Oracle Database | 11g Release 2,11.2.0.1.0 | 32 bit | |
數據庫操作系統 | Windows 7 Professional | 6.1.7601, Service Pack 1 | 32-bit | \ |
客戶端操作系統 | Windows 7 Professional | 6.1.7601, Service Pack 1 | 64 bit | \ |
數據庫客戶端 | Navicat Premium | 12.0.11 | 64 bit | \ |
2. 問題說明
Oracle數據安裝完後死活連接不上,各種莫名其妙的報錯。遇到的錯誤碼如下:
navicat 11的報錯
Cannot load OCI DLL, 193:C:\Program Files\PremiumSoft\Nacicat Premium\instantclient_11_2\oci.dll
Instant Client package is required for Basic and TNS connection.
For more information:http://wiki.navicat.com/wiki/index.php/Instant_client_required
ORA-28547:connection to server failed, probable Oracle Net admin error
navicat 12的報錯
Oracle library is not loaded.
ORA-28547:connection to server failed, probable Oracle Net admin error
新建了一個數據庫test_db,配置了新的listener
ORA-12514: TNS:listener does not currently know of service requested in connect
查看服務狀態
服務實例的狀態全是’UNKNOWN’,蛋疼。
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。
C:\Users\test>lsnrctl status
LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - Production on 25-11月-2019 16:2
6:22
Copyright (c) 1991, 2010, Oracle. All rights reserved.
正在連接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))
LISTENER 的 STATUS
------------------------
別名 LISTENER
版本 TNSLSNR for 32-bit Windows: Version 11.2.0.1.0 - Produ
ction
啓動日期 25-11月-2019 10:27:03
正常運行時間 0 天 5 小時 59 分 18 秒
跟蹤級別 off
安全性 ON: Local OS Authentication
SNMP OFF
監聽程序參數文件 C:\app\test\product\11.2.0\dbhome_1\network\admin\list
ener.ora
監聽程序日誌文件 c:\app\test\diag\tnslsnr\WIN-xxxxxxxx898\listener\aler
t\log.xml
監聽端點概要...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.182.146)(PORT=1521)))
服務摘要..
服務 "CLRExtProc" 包含 1 個實例。
實例 "CLRExtProc", 狀態 UNKNOWN, 包含此服務的 1 個處理程序...
服務 "orcl" 包含 1 個實例。
實例 "orcl", 狀態 UNKNOWN, 包含此服務的 1 個處理程序...
服務 "test_db" 包含 1 個實例。
實例 "test_db", 狀態 UNKNOWN, 包含此服務的 1 個處理程序...
命令執行成功
C:\Users\test>
因爲嘗試了各種方法,報的錯也是百花齊放,就是沒有解決問題。
0x01 問題分析
遇到的第一個問題就是
ORA-28547:connection to server failed, probable Oracle Net admin error
這個問題說的就是navicat的連接器錯誤,無法連接到服務端。這裏引入一個連接器概念Oracle Instant Client
。
Oracle Instant Client是什麼
Oracle Instant Client enables applications to connect to a local or remote Oracle Database for development and production deployment. The Instant Client libraries provide the necessary network connectivity, as well as basic and high end data features, to make full use of Oracle Database. It underlies the Oracle APIs of popular languages and environments including Node.js, Python and PHP, as well as providing access for OCI, OCCI, JDBC, ODBC and ProC applications. Tools included in Instant Client, such as SQLPlus and Oracle Data Pump, provide quick and convenient data access.
這裏解釋下前兩句:
Oracle Instant Client使應用程序可以連接到本地或遠程Oracle數據庫,以進行開發和生產部署。Instant Client庫提供必要的網絡連接以及基本和高端數據功能,以充分利用Oracle數據庫。
正常連接Oracle數據庫可以是用Oracle配套的SQL Plus工具連接,或者Oracle的客戶端,大約700M左右,很重。
但是爲了客戶端輕量級連接,*Oracle Instant Client**提供了一個動態庫oci.dll。這個庫文件只有幾百K,只要用了它,腰不酸腿不疼,一口氣上五樓,不費勁兒(暴露年齡了。。)。自己寫個程序,調用幾個函數即可以遠程操作Oracle數據庫。Navicat默認也是使用了Oracle的這個庫,但默認版本爲10.2的。
問題來了,我數據庫是11.2,但是連接庫是10.2的版本,明顯版本太低導致不匹配。所以需要使用11.2版本的oci.dll。
Oracle Instant Client是一個大包,下面有很多分類適用不同場景。具體分類如下:
Instant Client Package | 描述 | 關聯 |
---|---|---|
Basic | 運行OCI,OCCI和JDBC-OCI應用程序需要的所有文件 | OCI OCCI JDBC-OCI |
Basic Light | 只包含英語錯誤信息, 只支持unicode,ascii,西歐字符集。 | OCI OCCI JDBC-OCI |
SDK | 提供開發OCI和OCCI程序所需的頭文件和makfile示例3 | |
SQL*Plus | 提供SQL*Plus命令行工具用於執行SQL和PL/SQL語句和腳本 | SQL*Plus |
Tools | 提供Data Pump, SQL*Loader and Workload Replay Client | Data Pump SQL*Loader WRC |
ODBC | 提供ODBC相關的庫 | ODBC |
Precompilers | 提供ProC and ProCOBOL預編譯相關的庫 | Pro*C and Pro*COBOL |
JDBC-OCI Supplement | 支持國際化相關庫 | JDBC-OCI |
網上廣爲流傳的一種說法是,oci.dll需要使用32 bit的版本,有兩個流派闡述了爲什麼要是32 bit的。
第一種說法是: oracle 數據庫是32bit的,不管navicat是多少位,oci.dll需要跟服務器端的保持一致。
第二種說法是:navicat只有32bit的版本,所以oci.dll必須跟navicat保持一致。
於是下載了Instant Client Downloads for Microsoft Windows 32-bit
然而還是報錯。
第二中說法似乎比較靠譜,但是我navicat就是64 bit的。Oracle Instant Clien有tBasic版本和Basic Light版本。兩個都包含oci.dll,第一直覺是下載一個Basic Light,文件比較小,更輕量。
於是在Instant Client Downloads for Microsoft Windows (x64) 64-bit中下載了instantclient-basiclite-windows.x64-11.2.0.4.0.zip
然而出現新的錯誤
Cannot load OCI DLL, 193:C:\Program Files\PremiumSoft\Nacicat Premium\instantclient_11_2\oci.dll
Instant Client package is required for Basic and TNS connection.
For more information:http://wiki.navicat.com/wiki/index.php/Instant_client_required
百思不得其解,衍生出了琢磨服務器端的監聽器,有發現了很多問題。這裏就不在描述了。
這裏直接說下最終答案吧,就是oci.dll要符合3個條件:
- 與數據庫版本相同,這裏是Version 11.2.0.4.0
- 與客戶端程序的位數相同,這裏navicat是64 bit的所以選擇64 bit
- 使用Basic版本,不能使用Basic Light
哦,第一個流派衍生出的一種方法不得不說,就是直接從服務器上拷貝oci.dll給navicat用。奇怪的是這個oci.dll跟官網上的32bit的package中的大小不同,開始感覺可能是一種解決方案。後來只能說,道理狗屁不通,方法只知其表。navicat的32 bit應該可以用,但是64 bit是沒用的。
0x02 解決方案
使用64 bit的navicat下載64 bit的Instant Client Package -Version 11.2.0.4.0 - Basic的文件。
下載地址如下:
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html#license-lightbox
需要oracle賬號登錄下載
下載好後解壓到navicat的安裝目錄下:
C:\Program Files\PremiumSoft\Navicat Premium 12
打開navicat,【工具】- 【選項】-【環境】
將解壓出來的oci.dll文件的絕對路徑填入到OCI library(oci.dll)的表單中。
確定,關閉navicat重啓後生效。
0x03 參考文獻
https://www.oracle.com/database/technologies/instant-client.html
https://www.oracle.com/database/technologies/112010-win32soft.html
https://www.oracle.com/database/technologies/instant-client/microsoft-windows-32-downloads.html