TNSPING原理:

TNSPING位于ORACLE HOME/bin下,TNSPING只用于测试Listener是否可用(检查Socket是否可以连通),特别注意它不能检测数据库是否已经启动。

原理:类似于TCP/IP工具ping,tnsping会发送一个Message给DB Server Listener,DB listener会给出一个回复。

如果返回TNS-12541: TNS: no listener,一般表示服务端的Listener没有启动。

如果返回TNS-12154: TNS: Could not resolve service name,很可能是你的TNSNAMES.ORA有问题。

数据库客户端连接原理:Oracle客户端连接服务器,首先去找1521监听端口,然后监听器根据文件lisnter.ora文件中的GLOBAL_NAME来判断是否有一个GLOBAL_DBNAME 和 SERVICE_NAME 相等。如果相等,  再向server process进程发出请求,并返回一个随机端口,返回给客户端,客户端再来连接这个端口。最后建立客户端到SID标识的服务端实例的连接。

把两个原理搞懂后,就可以基本分析出各样连接关于客户端连数据库的疑难杂症:

1 ,可以用TNSPING通,但不能用SQLPLUS连上. 

报错ERROR:ORA-12545:Connect failed because target host or object does not exit

不能解析HOST或者object,肯定是tns文件中host名称问题,如果这些配置都是对的,在linux下考虑下

你的这个文件是DOS格式还是Unix格式。鉴别方式为:vi tnsnames.ora 看看每一行的后面是不是有^M这样的字符存在

2

维护人员反映数据库无法连接,现象是:tnsping 可以通,但是用sqlplus连接就无法连接,没有报错,就是一直挂在那边。前台应用程序是无法登录 。

登录数据库查看日志,正常。用sqlplus "/as sysdba" 可以登录 。show parameter session查是是330。查看监听日志是否超过2G(没有)。 怀疑是否是监听做怪,故重启一下监听。发现一样的结果。

这里能过查看netstat -na 发现有非常从的1521的端口。这时怀疑是否是系统内核参数设置不足。

手工kill 一个oracle 的连接进程后,通过过程客户端即可以登录。这样故障原因明确。

设置 

kernel.sem                   = 300 38400 300 128

上面的参数,加其加大。要来root口令:sysctl -p


以下为网下提供一个比较典型的这方面问题,来自于dba_hui的空间

一次怪异的sqlplus无法连接本机数据库问题
平台:windows
现象:在数据库机器上使用sqlplus无法以sys和system登陆进去,报错:ORA-12560: TNS:protocol adapter error
具体情况:
oracle的网络配置还是比较简单的,$ORACLE_HOME/network/admin/samples目录下有参考配置文件,还可以使用netca、netmgr图形化界面管理。
该机器上运行了两个实例,需要使用set ORACLE_SID=sid来确定一个实例。

(1)使用操作系统认证:
sqlplus / as sysdba
sqlplus system/passwd
或者
C:\> sqlplus /nolog
SQL> connect / as sysdba 
(2)使用tns
sqlplus as sysdba
sqlplus 
(3)使用easy connection
sqlpus as sysdba
sqlpus 

均报错ORA-12560: TNS:protocol adapter error
[oracle@cluster ~]$ oerr ora 12560
12560, 00000, "TNS:protocol adapter error"
// *Cause: A generic protocol adapter error occurred.
// *Action: Check addresses used for proper protocol specification. Before
// reporting this error, look at the error stack and check for lower level
// transport errors. For further details, turn on tracing and reexecute the
// operation. Turn off tracing when the operation is complete.

进行以下确认:
1、确认当前用户administrator属于ora_dba用户组。
2、确认密码文件存在。位于$ORACLE_HOME/database下。
3、确认监听器状态正常。位于$ORACLE_HOME/network/admin/listener.ora
lsnrctl status查看状态
netstat -an | more 确认监听器端口处于监听状态。
4、确认tns没有问题。位于$ORACLE_HOME/network/admin/tnsnames.ora
windows下没有tnsping,不方便。注意tnsping只能确认客户端到数据库主机ip上的端口是否畅通,并不能确认tns中的sid或者service_name正确。

以上都没有问题,仍然无法连接。
之所以觉得怪异,是因为有以下发现:
1、在查看监听器日志的过程中,位于$ORACLE_HOME/network/log/listener.log,发现:
数据库是测试数据库,在这期间,各种开发工具,包括jdbc都能连接到该数据库实例。
2、另外一个实例也是这个情况。

google一番,尝试均无效,开启lsnrctl的trace跟踪,也未发现异常。
现在仔细想来,其实自己忽略了最重要的区别:
sys和system不能登录;而开发工具能够登录(使用的一般用户)。本质原因是sys和system是依靠密码文件来进行验证的,而一般用户是通过数据库中保存的密码来进行验证的。
忽略的一个最大现象是:未尝试在数据库机器上使用非sys/system用户登陆(确认sqlplus是否正常);未尝试在开发客户端使用sys/system来登陆(确认密码是否正确)。

在metalink上查询ORA-12560,找到下面这篇文章:
Connect As Sysdba On Windows Fails With ORA-12560: TNS:protocol adapter error [ID 989716.1]

Symptoms:
A 'connect / as sysdba' on Windows fails witb an ORA-12560 as shown:

C:\> sqlplus /nolog
SQL> connect / as sysdba 
ERROR:
ORA-12560: TNS:protocol adapter error

Cause:
The PATH environment variable was incorrectly set.

In this case, an Oracle Client software home was set as the first entry in the PATH and not the Oracle Database software home. Therefore, the client version of sqlplus was used. 

The connection as SYSDBA was unable to make a connection using the client software because a password file was not in use and this is deemed as a remote connection. Connection as 

a user other than SYSDBA worked because a password file from a remote connection is not needed for this type of user.


Solution:
Set the PATH environment variable to specify the database ORACLE_HOME as the first directory in the path.

这篇文章说明的非常清楚,是因为path环境变量中,client端的路径放到了server端的路径前面,从而导致sqlplus调用的是客户端的sqlplus。
PATH环境变量告诉操作系统从哪里查找可执行命令,在哪个路径中先找到就使用哪个路径中的可执行命令。

查看系统的环境变量如下:
D:\Documentum\Shared;D:\Documentum\product\6.\bin;D:\Documentum\fulltext\fast;D:\Documentum\fulltext\dsearch;C:\Documentum\Shared;D:\oracle\product\10.2.0\client_1\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;D:\PROGRA~1\IBM\TDSV6~1.2DB\BIN;D:\PROGRA~1\IBM\TDSV6~1.2DB\FUNCTION;D:\PROGRA~1\IBM\TDSV6~1.2DB\SAMPLES\REPL;D:\oracle\product\10.2.0\db_1\BIN;D:\jdk1.6.0_03\bin;%SystemRoot%\SysWOW64


果然如metalink所言,D:\oracle\product\10.2.0\client_1\bin 这个客户端路径放在 D:\oracle\product\10.2.0\db_1\BIN 服务端的前面了,cmd中使用sqlplus调用了客户端的的sqlplus。

解决方法:
1、调整PATH环境变量,把服务端放到前面;
2、使用绝对路径。

 

 总结:遇到此类问题,

  一先看看配置,tnsnames.ora 里对不对,这里面格式是否DOS,特别有些人喜欢直接从windows上面拷贝到Linux下。

 二连接过程中出现错误代码的,根据代码在metalinks 搜一搜。

 三 连接过程中卡住的,这时要看日志,并向系统内核参数看看是否设置这过小。

    讲个题外话题,排错过程中不管什么时候要首先想到日志,这是排错基本掌握的,

    排错还要会用对比法 ,如果出现数据库客户端连不上,把这个客户端下的tnsname.ora拿到别的机器上测试,也是很管用的。