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