某电信客户使用了我们zdata分布式存储来承载ODS/EDW/REPORT等系统。当然对于数仓环境来讲,zdata分布式架构是极其适合的。这里先不打广告了。
我们首先来看下客户的问题,客户想进行安全加固修改12.2 rac的listener端口,处理好之后测试发现ODS老环境(oracle 10.2.0.5)连接12.2 rac报错ora-28040.
错误大致如下:
[ora10g@killdb admin]$ sqlplus roger/roger@killdb
SQL*Plus: Release 10.2.0.5.0 - Production on Fri Jul 7 20:28:48 2017
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
ERROR:
ORA-28040: No matching authentication protocol
我们首先来看下这个的解释。
[ora10g@killdb admin]$ oerr ora 28040
28040, 0000, "No matching authentication protocol"
// *Cause: No acceptible authentication protocol for both client and server
// *Action: Administrator should set SQLNET_ALLOWED_LOGON_VERSION parameter
// on both client and servers to values that matches the minimum
// version supported in the system.
解释非常的清楚,客户端和数据库server端在建立认证时出现了异常,oracle建议设置sqlnet_allowed_logon_version参数。其实这里的解释稍微有些错误,根本没有这个参数.其实应该是SQLNET.ALLOWED_LOGON_VERSION。
如果你的数据库是oracle 12.1版本,而客户端版本较低,比如是oracle 10g那么则需要在数据库服务端和客户端的sqlnet.ora中加入SQLNET.ALLOWED_LOGON_VERSION参数。
在oracle 12.1版本中该参数如果没有设置,oracle 默认会认为是11. 而在Oracle 12.2版本中,该参数已经被废弃,进而通过另外如下2个参数来进行代替:
SQLNET.ALLOWED_LOGON_VERSION_SERVER=n
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=n
这2个参数如果在未进行设置的情况下,Oracle 12.2 会默认认为是12. 这样会导致较低版本的客户端无法连接oracle 12.2的数据库环境。
由于客户这里是12.2 rac,客户端是10.2.0.5。这里我进行简单的测试:
1、首先修改数据库server端(12.2)的sqlnet.ora
SQLNET.ALLOWED_LOGON_VERSION_SERVER=10
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=10
2、建议reload或者重启listener(不需要重启数据库)
3、客户端10g环境修改sqlnet.ora
#SQLNET.WALLET_OVERRIDE=TRUE
NAMES.DIRECTORY_PATH=(TNSNAMES,EZCONNECT)
#WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/home/ora10g/product/10.2/network/admin/wallet)))
sqlnet.expire_time = 1
SQLNET.ALLOWED_LOGON_VERSION_SERVER=10
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=10
4、进行ezconnect测试连接
[ora10g@killdb admin]$ sqlplus test/test@172.16.29.131:1521/roger
SQL*Plus: Release 10.2.0.5.0 - Production on Fri Jul 7 21:02:10 2017
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
www.killdb.com@select * from v$version;
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
PL/SQL Release 12.2.0.1.0 - Production 0
CORE 12.2.0.1.0 Production 0
TNS for Linux: Version 12.2.0.1.0 - Production 0
NLSRTL Version 12.2.0.1.0 - Production 0
5、修改tnsnames.ora(客户端),并进行tnsnames测试
pdbroger =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.29.131)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = roger)
)
)
6、通过tns进行访问连接
[ora10g@killdb admin]$ sqlplus test/test@pdbroger
SQL*Plus: Release 10.2.0.5.0 - Production on Fri Jul 7 20:49:04 2017
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
www.killdb.com@select * from v$version;
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
PL/SQL Release 12.2.0.1.0 - Production 0
CORE 12.2.0.1.0 Production 0
TNS for Linux: Version 12.2.0.1.0 - Production 0
NLSRTL Version 12.2.0.1.0 - Production 0
www.killdb.com@
我们可以看出,对于oracle 10g的环境来说,访问12.2 环境没有任何问题。
通过查询Oracle mos文档Client / Server Interoperability Support Matrix for Different Oracle Versions (文档 ID 207303.1)发现该文档中提供了server/client支持矩阵。其中明确表明10gR2 客户端不支持访问oracle 12.2环境。如下:
但是我们测试发现确实支持的。但是文档确说不支持。(尽管如此,无法确认是否有其他问题,建议还是文档为主).
由于好奇心做怪,我就想知道Oracle 9.2版本是否支持访问12.2 呢?
同样的测试方法,将12.2环境中的参数改成如下:
SQLNET.ALLOWED_LOGON_VERSION_SERVER=9
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=9
同时在oracle 9.2环境中修改为:
NAMES.DIRECTORY_PATH=(TNSNAMES,EZCONNECT)
SQLNET.ALLOWED_LOGON_VERSION_SERVER=9
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=9
经过测试发现无论是zcconnect模式还是tns模式,都无法访问Oracle 12.2,如下:
[ora9@killdb admin]$ sqlplus test/test@pdbroger
SQL*Plus: Release 9.2.0.8.0 - Production on Fri Jul 7 21:31:28 2017
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Segmentation fault
我们不难看出确实Oracle 12.2 确实不再支持9i了,但是仍然支持10g。这里我没有修改10g环境的参数,可见server端的参数是向下兼容的。
那么如果是你的应用是jdbc呢? oracle 10g或者9i的jdbc 支持访问Oracle 12c吗 ?
很明显10g仍然支持(12.1/12.2),不过9i 不在支持了(无论是12.1还是12.2).
可参考如下2篇文档:
DBC Version 10.2.0.4 Produces ORA-28040 Connecting To Oracle 12c (12.1.0.2) Database (文档 ID 2023160.1)
ORA-28040 Using JDBC 9i for Connection to 12c Database (文档 ID 2111118.1)
如下你要修改jdbc的配置,那么可参考如下的配置:
OracleDataSource ods = new OracleDataSource();
ods.setURL(jdbcURL);
ods.setUser("scott");
ods.setPassword("tiger");
Properties props = new Properties();
props.put("oracle.jdbc.allowedLogonVersion", 10);
ods.setConnectionProperties(props);
Connection con = ods.getConnection();
不过,我这里是Oracle 12.2 单机环境,对于Oracle 12.2 Rac,还需要进一步验证。无论如何,还是以Oracle mos文档为主更好一些,避免出现一些不必要和未知的问题。