首页 » ORACLE [C]系列, ORACLE 9i-23c » Oracle 12cR2新特性: 使用DBMS_TNS package 在数据库中tnsping

Oracle 12cR2新特性: 使用DBMS_TNS package 在数据库中tnsping

数据库中的dblink创建时如果使用了tnsnames.ora中的别名,那么在日后梳理数据库中所有的DBLINK 与哪些主机的数据库有连接时?通过DBA_DB_DBLINKS视图可能无法直接取到IP地址, 如修改数据库用户名或迁移数据库主机变更IP时就需要那么做。通常需要登录数据库主机使用tnsping 别名的方式来解析IP,如果一个数据库中的DBLINK很多就需要更多的时间去梳理。在几年前我面临这个需求时自己写过一个shell脚本来简化操作How to list all db links in oracle DB to generate a flat file? (生成dblink列表文件), 但是如果当时创建dblink时在session级使用了非默认的tnsnames.ora如指定了TNS_ADMIN,查找对应的tnsnames.ora和解析工作变的更佳复杂。所幸在oracle 12.2版本中提供了新的package DBMS_TNS, 可以不登录主机(终端)在数据库内部就可以解析。

SQL> desc DBMS_TNS
FUNCTION RESOLVE_TNSNAME RETURNS VARCHAR2
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 TNS_NAME                       VARCHAR2                IN

[oracle@anbob ~]$ tnsping anbob/anbob
TNS Ping Utility for Linux: Version 12.2.0.1.0 - Production on 16-MAR-2017 14:16:27
Copyright (c) 1997, 2016, Oracle.  All rights reserved.

Used parameter files:
/u02/app/oracle/product/12.2.0/db_1/network/admin/sqlnet.ora
Used EZCONNECT adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=anbob))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.56.3)(PORT=1521)))
OK (10 msec)

[oracle@anbob ~]$ tnsping pdbanbob

TNS Ping Utility for Linux: Version 12.2.0.1.0 - Production on 16-MAR-2017 15:06:44
Copyright (c) 1997, 2016, Oracle.  All rights reserved.
Used parameter files:
/u02/app/oracle/product/12.2.0/db_1/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = anbob.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = pdbanbob.com)))
OK (10 msec)

[oracle@anbob ~]$ env|grep TNS
[oracle@anbob ~]$ cd $ORACLE_HOME/network/admin
[oracle@anbob admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /u02/app/oracle/product/12.2.0/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

LISTENER_ANBOB =
  (ADDRESS = (PROTOCOL = TCP)(HOST = anbob.com)(PORT = 1521))


ANBOB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = anbob.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = anbob.com)
    )
  )

pdbANBOB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = anbob.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = pdbanbob.com)
    )
  )
cdb210 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.31.210)(PORT = 1521))
    (LOAD_BALANCE = NO)
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCL122)
    )
  )

DBMS_TNS
SQL> select dbms_tns.resolve_tnsname('cdb210') from dual;
DBMS_TNS.RESOLVE_TNSNAME('CDB210')
------------------------------------------------------------------------------------------------
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.31.210)(PORT=1521))(LOAD_BALANCE=NO)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL122)(CID=(PROGRAM=oracle)(HOST=anbob)(USER=oracle))))

SQL> select dbms_tns.resolve_tnsname('anbob/anbob.com') from dual;
DBMS_TNS.RESOLVE_TNSNAME('ANBOB/ANBOB.COM')
----------------------------------------------------------------------------------------------
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=anbob.com)(CID=(PROGRAM=oracle)(HOST=anbob)(USER=oracle)))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.56.3)(PORT=1521)))

SQL> select dbms_tns.resolve_tnsname('149.0.0.1/anbob') from dual;
DBMS_TNS.RESOLVE_TNSNAME('149.0.0.1/ANBOB')
------------------------------------------------------------------------------
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=anbob)(CID=(PROGRAM=oracle)(HOST=anbob)(USER=oracle)))(ADDRESS=(PROTOCOL=TCP)(HOST=149.0.0.1)(PORT=1521)))

SQL> select dbms_tns.resolve_tnsname('300.0.0.0/anbob') from dual;
DBMS_TNS.RESOLVE_TNSNAME('300.0.0.0/ANBOB')
------------------------------------------------------------------------------------------------

Note:
dbms_tns和tnsping一样可以解析EZCONNECT和TNSNAMES,但是不会验证IP和PORT是否能通信,所以这点不会像tnsping那样与listener通信返回通信结果,就像上面使用的149.0.0.1这样的IP, 但是对于无效的IP如300.0.0.0和不存在的主机名也是无法解析的返回空。

这样一来像开始我提到的,如果取数据库中所有DBLINK的源端主机信息就更加容易。

SQL> select owner,db_link,dbms_tns.resolve_tnsname(host) from dba_db_links;
OWNER                           DB_LINK
-------------------------     ----------------------------------------------------------
DBMS_TNS.RESOLVE_TNSNAME(HOST)
----------------------------------------------------------------
SYS                            SYS_HUB


SYS                           LINK_PROD.COM
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anbob.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=pdbanbob.com)(CID=(PROGRAM=oracle)(HOST=anbob)(USER=oracle))))

SYS                            LINK_CDB210.COM
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.31.210)(PORT=1521))(LOAD_BALANCE=NO)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL122)(CID=(PROGRAM=oracle)(HOST=anbob)(USER=oracle))))

打赏

, , ,

对不起,这篇文章暂时关闭评论。