代码改变世界

记录一则LOCAL_LISTENER的问题

2019-06-09 14:28 AlfredZhao 阅读(...) 评论(...) 编辑 收藏

有网友反映,他在一套Oracle的测试环境中配置有两个监听,分别监听不同端口。
目前想把环境上的一套数据库同时注册到这两个监听,他将数据库参数local_listener和tnsname.ora文件配置如下:


然后抛出问题:tnsname.ora中的service_name可以随便填吗?
如果答案是不可以,那为什么他测试随意更改这个service_name都不影响注册?
如果答案是可以?那为什么平日工作中这个service_name填错就连不上呢?

首先,可以验证他说的这个场景是可以复现的。但其实他的困惑是因为将两个原本独立的问题混为一团所致。可以将他的困惑分解为2个独立的问题:

1.tnsname.ora中的service_name可以随便填吗?

当tnsnames.ora作为客户端配置时,此时要求service_name必须和要连接的库中的service_names中的某个值保持对应,否则也无法连接。这个针对初级dba都是必备常识,不必多说了。

2.为什么他测试随意更改这个service_name都不影响注册?

因为他这里的tnsnames.ora配置条目是单纯给local_listener使用的,而对于local_listener的配置,官方有明确说明:

LOCAL_LISTENER specifies a network name that resolves to an address or address list of Oracle Net local listeners (that is, listeners that are running on the same machine as this instance). The address or address list is specified in the TNSNAMES.ORA file or other address repository as configured for your system.

也就是说local_listener配置可以是网络别名,而且从它的默认值:

可以看出,如果这个tnsnames.ora中的条目如果只是单纯给local_listener使用,那实际应该并不要求配置service_name的值,或者说CONNECT_DATA这一块都不需要配置。

根据这个猜想,我在测试环境也实际验证了下,如果将tnsnames.ora 配置文件中新增一个条目,只包含如下信息:

TEST001 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = db01.example.com)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = db01.example.com)(PORT = 1526))
    )
  )

然后配置数据库local_listener的参数为TEST001,此时验证就可以实现两个监听的正常注册。
那么现在再回过头去看网友提出的这个问题,就非常好解释了,因为他所谓的这个随便填写的service_name,实际对于local_listener来说本来就不需要,所以任意修改它的值都不会影响到数据库注册到监听。而针对客户端的连接,需要根据tnsnames.ora配置文件中的service_name实际连接到具体的数据库,自然就不能填写错误。