在Oracle中,TNS:listener是什么?

13

这个问题可能有点超出了ServerFault的范围,但考虑到我以前在Oracle方面提问时得到了帮助,所以我还是先在这里尝试一下。

我正在尝试从PHP连接到一个Oracle数据库,但是遇到了以下错误:

ORA-12505: TNS:listener does not currently know of SID given in connect descriptor

这是PHP报告的错误,也是出现在Oracle的listener.log中的错误。

我目前遇到的问题是修复此错误。我想要得到回答的更大问题是Oracle连接模型是如何工作的?

这是在我的本地Windows机器上运行的开发环境,一直到现在都一直在工作。不幸的是,这个环境是交给我的(我没有设置它),而设置它的人不可用于帮助我调试。

如果我在MySQL或PostgreSQL中遇到类似的错误(这两个系统我比较熟悉),我会检查数据库进程是否正在运行,然后尝试使用用户名/密码/连接字符串手动连接到数据库。 不幸的是,我不熟悉Windows上的Oracle工具(除了SQL Developer之外),并且我不知道在Oracle的上下文中TNS:listener或SID是什么(我有模糊的想法,但是在调试此类问题时模糊的想法很少有用)。

任何一般性的建议都将不胜感激。

根据评论的更新:

我的tnsnames.ora文件中有许多条目,其中相关条目为

OBS2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = steel-ae39650)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = OBS2)
    )
  )

当我运行时,这并没有反映在实例列表中

    LSNRCTL> services

所以我认为我的下一个问题是,我如何尝试手动启动OBS2实例?


1
一个TNS条目是连接到Oracle的连接字符串的一部分。 - OMG Ponies
3个回答

9

TNS名称就像是您的服务实例的别名。在这方面,TNS监听器服务充当了一种查找服务的服务。如果您尝试通过TNS名称连接的实际服务无效,则会出现该错误消息。

您可以使用命令行工具测试TNS监听器是否正确地看到了该服务:

%>lsnrctl services

应该输出以下内容:
Service "myservice" has 1 instance(s).
  Instance "myinstance", status READY, has 1 handler(s) for this service...
    Handler(s):
      "D000" established:0 refused:0 current:0 max:1002 state:ready
         DISPATCHER <machine: LOCALHOST, pid: 12345>
         (ADDRESS=(PROTOCOL=tcp)(HOST=LOCALHOST)(PORT=6789))

请您提供相关的TNS条目(在tnsnames.ora文件中)。该文件位于ORAHOME\client或db\ADMIN\NETWORK。如果您同时拥有客户端和服务器,请确保两份tnsnames.ora文件的值都是正确的,以确保安全。
以下是在tnsnames.ora中定义TNS名称“mydb”的示例:
myDbAlias =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 12345)(QUEUESIZE = 100))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = myservice)
    )
  )

1
更新了包含相关信息的问题。看起来相关的TNS条目没有在监听程序中反映出来。有没有一种手动启动TNS实例的方法?另外可能相关的是,如果我使用dbca并尝试为所讨论的数据库/模式(正确的术语是什么?)“配置数据库选项”,我会收到以下错误:ORA-02778:为日志目录给定的名称无效。我通过创建一个新的数据库并导入最近的转储解决了我的问题,但我仍然对这种情况的任何调试技巧感兴趣。 - Alana Storm
你说你在使用Windows系统,所以你应该能够在Windows服务组件中看到服务是否正在运行。开始->管理工具->服务。查看OracleServiceOBS2(我猜测名称可能不同)。然后从那里启动它。你的TNS监听器服务也在那里,命名为OracleOraDb10g_home_1TNSListener。 - Mike Atlas
1
所以,让我感到困惑的是一个 Oracle 数据库如何可以正常运行,而另一个却不能。也就是说,当我列出服务时,我看到其他数据库(OBS3、OBS4 等)都已经启动了。所有数据库都由 OracleServiceOBS2 控制,还是每个数据库都有自己的 OracleServiceOBS2?(如果这不太清楚,请原谅,因为我在这方面不知道我不知道什么!) - Alana Storm
1
你只是从另一个系统过来,对Oracle术语的选择有点不熟悉。可以查看这个SO主题:https://dev59.com/YXNA5IYBdhLWcg3wHp-B - Mike Atlas
特别值得澄清的是:一个实例可以有多个表空间(你称之为数据库?)。 - Mike Atlas
显示剩余3条评论

4

我想补充一下,最近我也遇到了类似的连接问题,一直被困扰,直到我找出了问题所在。

首先,关键字SID和SERVICE_NAME并不完全相同。这是我的第一个错误假设。在许多环境中,你可以交换使用SID和SERVICE_NAME,但并非总是如此,这取决于具体情况。

话虽如此,你的错误已经暴露了问题:在连接字符串中指定了SID而不是tnsnames成功使用的SERVICE_NAME

因此,如果你正在代码中指定连接字符串,请尝试在连接字符串中使用SERVICE_NAME关键字(*或者,如果你已经使用了SERVICE_NAME却无法连接,请尝试使用SID关键字*)。

我知道这个答案过于简单了,但它很容易尝试,有可能能够帮助某些人省去一些烦恼。

希望能对你有所帮助。


1

Mike Atlas的回答相当全面,但请注意,您可以使用[//]host_name[:port][/service_name]连接到没有发布tnsname的10g(或更高版本)数据库

希望对你有所帮助

C.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接