【问题标题】:Can't create Database Link to remote DB in Oracle-DB无法在 Oracle-DB 中创建指向远程 DB 的数据库链接
【发布时间】:2012-04-30 08:19:44
【问题描述】:

我们公司有一个 CRM 系统,它使用 Oracle 11g 数据库。它由第三方供应商开发。

我们无权访问运行 CRM 系统的服务器。但是,我们有可用的 DBA 登录数据(SYS 用户)。它包括:

  • 服务器IP:172.1.2.3
  • 端口:1521
  • SID: abc
  • 用户:系统
  • 密码:*

我们可以使用它通过Oracle SQL Developer 3.1(连接>>属性)访问数据库

现在必须将部分数据从 CRM 数据库复制到驻留在另一台服务器上的 其他 Oracle 数据库中。

据我了解,我需要在我的目标数据库中创建一个数据库链接。我尝试过这样的事情:

CREATE PUBLIC DATABASE LINK xxx CONNECT TO sys IDENTIFIED BY ***** USING 'MYTNSENTRY'

我的tnsnames.ora如下:

MYTNSENTRY =
 (DESCRIPTION = 
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.1.2.3)(PORT = 1521))
   )
 (CONNECT_DATA =
   (SERVICE_NAME = abc)
 )
)

.... 和我的 listener.ora 看起来像这样:

MYLISTENER=
  (DESCRIPTION=
    (ADDRESS_LIST=
      (ADDRESS=(PROTOCOL=tcp)(HOST=172.1.2.3)(PORT=1521))
      ))
SID_LIST_MYLISTENER=
  (SID_LIST=    
    (SID_DESC=
      (SID_NAME=MYTNSENTRY)
      (ORACLE_HOME=C:\somepath) # path to Oracle home of target DB
      (PROGRAM=extproc)))

PROGRAM=extproc 是正确的选择吗?还有其他几个程序可供选择。我什至无法用 lsnrctl 启动监听器,因为它无法“验证用户”或其他东西。具有讽刺意味的是,侦听器设置和数据库链接到 MS SQL 服务器 工作顺利。

现在,尽管缺少有关 CRM 数据库系统的一些重要信息,但仍然可以在 SQL Developer 中连接到数据库。难道不是也可以在两个 Oracle DB 之间建立连接吗?请帮助我设置和创建数据库链接。

----- 编辑:--------

Alex Poole 的提示帮助我让它发挥作用。我用过

  show parameters service_names;

获取完整的服务名称。它的格式为 abc.def,其中 def 是域。因此,我将域名添加到 tnsnames.ora 中的 TNS 别名中:

MYTNSENTRY =
 (DESCRIPTION = 
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.1.2.3)(PORT = 1521))
   )
 (CONNECT_DATA =
   (SERVICE_NAME = abc.def)
 )
)

可以在目标数据库服务器的命令提示符下使用 tnsping MYTNSENTRY 测试连接。 tnsnames.ora 是本地的。但是,我删除了对“本地”listener.ora 的所有更改,因为监听器确实驻留在 CRM 服务器上。

SQL 命令基本没有变化,但现在连接正常:

CREATE PUBLIC DATABASE LINK xxx CONNECT TO some_user IDENTIFIED BY ***** USING 'MYTNSENTRY'

【问题讨论】:

  • 您拥有该条目的 TNSNames 文件来自“其他”(非 CRM)oracle 数据库上的 TNSNames 文件,对吗?我不确定您是否必须对目标数据库上的侦听器做任何事情。至少我从来不需要。据我所知,目标数据库像任何其他连接一样处理传入的数据库链接(但我可能错了)
  • 我也很确定您不想以 sys 用户的身份创建数据库链接(或者,至少,我不会......如果只是为了安全起见)
  • 同意。 SYS 在 Oracle 中是非常特殊的,应格外小心/谨慎对待。
  • 我会在sys 中重复不要这样做。您需要引用您的密码;它不是一个对象,它是一个字符串。
  • 是的,tnsnames.ora 来自“目标”数据库。我需要在“创建数据库链接”SQL 语句中引用服务名称。由于我没有关于 CRM 服务器上运行的内容的信息,因此我打算创建自己的 Listener/TNS 别名来提供服务。然后,该侦听器将用于访问远程 (=CRM) 数据库。感谢您对 sys 用户的安全问题的提示,我将使用另一个用户。

标签: oracle database-connection database-link heterogeneous-services


【解决方案1】:

除非必要,否则不仅不能以 SYS 身份连接,而且不能通过数据库链接以 SYS 身份连接。

【讨论】:

  • 我最初的想法是在测试时不要因为缺乏权限而遇到其他问题。但既然它甚至有限制,我想我会改变它,即使是为了测试。
【解决方案2】:

您说过SIDabc,但在tnsnames.ora 中,CONNECT_DATA 部分中的SERVICE_NAME。它们并不总是相同的——参见this question,或者这个Ask Tom entry。您实际上并没有说出您遇到了什么错误,但只需将其更改为 SID = 可能会有所不同。

listener.ora,实际上是侦听器,位于托管 CRM 数据库的服务器上,而不是托管您的“目标”数据库的服务器上。您可以从显然已经配置好的 SQL Developer 进行连接。 tnsnames.ora 确实需要是本地的。

但如果您确实知道 CRM 数据库的 service_name,您可以跳过它并使用 EZCONNECT 语法来定义链接中的所有内容:

CREATE PUBLIC DATABASE LINK xxx
CONNECT TO non-sys IDENTIFIED BY *****
USING '//172.1.2.3:1521/service_name';

检查您的 SQL Developer 配置,看看它是否已经在使用服务名称,而不是 SID,如果没有,您需要发现它。如果您有权访问 CRM 服务器,则可以使用 lsnrctl 查找已注册的服务名称,但您似乎不需要连接到数据库并运行 show parameters service_namesselect value from v$parameter where name = 'service_names';

创建公共链接需要比私人链接更多的权限,而公共链接的安全性可能较低,因为它会将您的 CRM 数据库暴露给目标链接上的任何人。所以我只会在真正需要时将其公开,如果您能够创建一个只读帐户,无论哪种方式都可以连接到一个只读帐户。

另请注意,如果您的目标数据库将global_names 设置为true,则数据库链接名称必须与远程服务名称匹配。

【讨论】:

  • 您建议使用 '//172.1.2.3:1521/abc.domain'。在我的情况下,如何查找 .domain 信息?我必须检查是否有任何非管理员用户可以看到我们需要的所有表格。不过,我不愿意在我不完全理解的系统上修改用户权限。
  • @user748261 - 我的意思是服务名称,我猜的是格式。我已经用一些链接和更多信息更新了答案。不过,请在您的问题中添加您看到的实际错误,因为我有点在黑暗中拍摄!
  • 我已经编辑了我的原始帖子。您可能在黑暗中开枪,但您是对的 :-)。我希望我的编辑能够明确解决方案的工作原理。
猜你喜欢
  • 2022-10-16
  • 2020-04-05
  • 2014-11-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 2015-12-24
  • 1970-01-01
相关资源
最近更新 更多