一、总体概述

    Oracle RAC 监听器的配置与单实例稍有不同,但原理和实现方法基本上是相同的。在Oracle服务端中 tns进程用于为指定网络地址上的一个或多个Oracle 实例提供服务注册,并响应来自客户端对该服务提出的连接请求。一旦连接请求到达,并派生出一个服务器进程建立服务器与用户端之间的连接(专有服务器dedicated server)或转发服务请求(共享服务器模式shared server)。如果监听器知道多于一个实例提供所请求的服务,则可能会根据客户端与服务器端相关配置将请求定位到较低负载的实例为其提供服务。因此合理正确配置监听器以及tnsnames是Oracle RAC实现负载均衡以及failover的前提,本文将描述基于 CentOS 6.5 + Oracle 10g RAC 下监听器的配置。

一、节点上监听信息

1、两个节点及主机配置信息(racdbp,racdbs)  
    oracle@racdbp:/u01/oracle/db/network/admin> cat /etc/hosts  
      
    127.0.0.1       localhost.yeung.com   localhost  
    # Public   
    192.168.7.51   racdbp.yeung.com        racdbp
    192.168.7.52   racdbs.yeung.com        racdbs
    #Private   
    10.10.7.51   racdbp-priv.yeung.com   racdbp-priv  
    10.10.7.52   racdbs-priv.yeung.com   racdbs-priv  
    #Virtual   
    192.168.7.61   racdbp-vip.yeung.com    racdbp-vip  
    192.168.7.62   racdbs-vip.yeung.com    racdbs-vip  
  
2、节点racdbp上的listener.ora  
    oracle@racdbp:/u01/oracle/db/network/admin> more listener.ora  
    # listener.ora.racdbp Network Configuration File: /u01/oracle/db/network/admin/listener.ora.racdbp   
    # Generated by Oracle configuration tools.   
      
    LISTENER_RACDBP =  
      (DESCRIPTION_LIST =  
        (DESCRIPTION =  
          (ADDRESS = (PROTOCOL = TCP)(HOST = racdbp-vip.yeung.com)(PORT = 1521)(IP = FIRST))  
          (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.51)(PORT = 1521)(IP = FIRST))  
        )  
      )  
      
    SID_LIST_LISTENER_RACDBP =  
      (SID_LIST =  
        (SID_DESC =  
          (SID_NAME = PLSExtProc)  
          (ORACLE_HOME = /u01/oracle/db)  
          (PROGRAM = extproc)  
        )  
      )  
  
3、节点racdbp上的tnsnames.ora  
    oracle@bo2dbp:/u01/oracle/db/network/admin> more tnsnames.ora  
    #对于连接字符串RAC1A,RAC1B,RAC1在此处可以省略   
    #这些字符串通常用于客户端连接到数据库   
    RAC1B =  
      (DESCRIPTION =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))  
        (CONNECT_DATA =  
          (SERVER = DEDICATED)  
          (SERVICE_NAME = RAC1)  
          (INSTANCE_NAME = RAC1B)  
        )  
      )  
      
    RAC1A =  
      (DESCRIPTION =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))  
        (CONNECT_DATA =  
          (SERVER = DEDICATED)  
          (SERVICE_NAME = RAC1)  
          (INSTANCE_NAME = RAC1A)  
        )  
      )  
      
    RAC1 =  
      (DESCRIPTION =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))  
        (LOAD_BALANCE = yes)  
        (CONNECT_DATA =  
          (SERVER = DEDICATED)  
          (SERVICE_NAME = RAC1)  
        )  
      )  
      
    #下面是几个重要的用于设置local_listener 以及remote_listener参数的定义信息   
    LISTENER_RACDB =  
      (ADDRESS_LIST =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))  
      )  
      
    LISTENER_RACDBP =  
      (ADDRESS_LIST =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))  
      )  
      
    LISTENER_RACDBS =  
      (ADDRESS_LIST =  
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))  
      )    
 
  
4、节点racdbp上监听器的信息  
    #可以看出只有实例 RAC1A 注册到监听器 LISTENER_RACDBP   
    oracle@racdbp:/u01/oracle/db/network/admin> lsnrctl status LISTENER_RACDBP  
      
    LSNRCTL for Linux: Version 10.2.0.3.0 - Production on 25-FER-2016 21:12:04  二月
      
    Copyright (c) 1991, 2006, Oracle.  All rights reserved.  
      
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=racdbp-vip.yeung.com)(PORT=1521)(IP=FIRST)))  
    STATUS of the LISTENER  
    ------------------------  
    ..............  
    Listener Parameter File   /u01/oracle/db/network/admin/listener.ora  
    Listener Log File         /u01/oracle/db/network/log/listener_racdbp.log  
    Listening Endpoints Summary...  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.61)(PORT=1521)))  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.51)(PORT=1521)))  
    Services Summary...  
    Service "+ASM" has 1 instance(s).  
      Instance "+ASM1", status BLOCKED, has 1 handler(s) for this service...  
    Service "+ASM_XPT" has 1 instance(s).  
      Instance "+ASM1", status BLOCKED, has 1 handler(s) for this service...  
    Service "RAC1" has 1 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
    Service "RAC1XDB" has 1 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
    Service "RAC1_XPT" has 1 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
    Service "PLSExtProc" has 1 instance(s).  
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...  
    The command completed successfully  
  
5、节点racdbs上的listener.ora  
    oracle@racdbs:/u01/oracle/db/network/admin> more listener.ora  
    # listener.ora.racdbs Network Configuration File: /u01/oracle/db/network/admin/listener.ora.racdbs   
    # Generated by Oracle configuration tools.   
      
    LISTENER_RACDBS =  
      (DESCRIPTION_LIST =  
        (DESCRIPTION =  
          (ADDRESS = (PROTOCOL = TCP)(HOST = racdbs-vip.yeung.com)(PORT = 1521)(IP = FIRST))  
          (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.52)(PORT = 1521)(IP = FIRST))  
        )  
      )  
      
    SID_LIST_LISTENER_RACDBS =  
      (SID_LIST =  
        (SID_DESC =  
          (SID_NAME = PLSExtProc)  
          (ORACLE_HOME = /u01/oracle/db)  
          (PROGRAM = extproc)  
        )  
      )    
    #由于节点racdbs上的tnsnames.ora与节点racdbp内容相同,不再列出   
  
6、节点racdbs上的监听器状态  
    #同样可以看到只有一个 instance,即RAC1B注册到了监听器 LISTENER_RACDBS   
    oracle@racdbs:/u01/oracle/db/network/admin> lsnrctl status LISTENER_RACDBS  
      
    LSNRCTL for Linux: Version 10.2.0.3.0 - Production on 25-fFER-2012 19:24:37 
      
    Copyright (c) 1991, 2006, Oracle.  All rights reserved.  
      
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=racdbs-vip.yeung.com)(PORT=1521)(IP=FIRST)))  
    STATUS of the LISTENER  
    ------------------------  
    .......................  
    Listening Endpoints Summary...  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.62)(PORT=1521)))  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.52)(PORT=1521)))  
    Services Summary...  
    Service "+ASM" has 1 instance(s).  
      Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...  
    Service "+ASM_XPT" has 1 instance(s).  
      Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...  
    Service "RAC1" has 1 instance(s).  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1XDB" has 1 instance(s).  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1_XPT" has 1 instance(s).  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "PLSExtProc" has 1 instance(s).  
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...  
    The command completed successfully    
      
    #通过上面的观察可知,当前的两个实例都是在各自所在主机上的监听器进行了注册。

二、设置remote_listener参数

1、在节点racdbp上执行下列的命令  
    SQL> show parameter instance_name  
      
    NAME                                 TYPE        VALUE  
    ------------------------------------ ----------- ------------------------------  
    instance_name                        string      RAC1A  
      
    -->为节点racdbp设置远程监听器  
    -->这意味着可以将实例RAC1A上提供的服务可以注册到LISTENER_RACDBS定义的监听器中  
    SQL> alter system set remote_listener='LISTENER_RACDBS' sid='RAC1A';  
      
    System altered.  
      
    -->执行 register 实现注册  
    SQL> alter system register;  
      
    System altered.  
      
    #再次查看节点racdbs监听器状态,实例RAC1A已经注册到racdbs节点   
    Oracle@racdbs:/u01/oracle/db/network/admin> lsnrctl status LISTENER_RACDBS  
      
    LSNRCTL for Linux: Version 10.2.0.3.0 - Production on 25-FER-2016 20:11:06  
      
    Copyright (c) 1991, 2006, Oracle.  All rights reserved.  
      
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=racdbs-vip.yeung.com)(PORT=1521)(IP=FIRST)))  
    STATUS of the LISTENER  
    ------------------------  
    ..............  
    Listener Parameter File   /u01/oracle/db/network/admin/listener.ora  
    Listener Log File         /u01/oracle/db/network/log/listener_racdbs.log  
    Listening Endpoints Summary...  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.62)(PORT=1521)))  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.52)(PORT=1521)))  
    Services Summary...  
    Service "+ASM" has 1 instance(s).  
      Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...  
    Service "+ASM_XPT" has 1 instance(s).  
      Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...  
    Service "RAC1" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1XDB" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1_XPT" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "PLSExtProc" has 1 instance(s).  
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...  
    The command completed successfully  
  
2、节点racdbs上设置local_listener,remote_listener  
    SQL> select instance_name from v$instance;  
      
    INSTANCE_NAME  
    ----------------  
    RAC1B  
      
    SQL> show parameter listener  
      
    NAME                                 TYPE        VALUE  
    ------------------------------------ ----------- ------------------------------  
    local_listener                       string  
    remote_listener                      string  
      
    -->按照节点racdbp上的操作方式将节点racdbs上的remote_listener只向节点racdbp  
    SQL> alter system set remote_listener='LISTENER_RACDBP' sid='RAC1B';  
      
    System altered.  
      
    SQL> alter system register;  
      
    System altered.  
      
    -->在racdbp节点上也可以看到实例RAC1B也注册到了第一个节点上  
    oracle@racdbp:/u01/oracle/db/network/admin> lsnrctl status LISTENER_RACDBP  
      
    LSNRCTL for Linux: Version 10.2.0.3.0 - Production on 25-FER-2016 21:37:11 
      
    Copyright (c) 1991, 2006, Oracle.  All rights reserved.  
      
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=racdbp-vip.yeung.com)(PORT=1521)(IP=FIRST)))  
    STATUS of the LISTENER  
    ------------------------  
    ............  
    Listener Parameter File   /u01/oracle/db/network/admin/listener.ora  
    Listener Log File         /u01/oracle/db/network/log/listener_racdbp.log  
    Listening Endpoints Summary...  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.61)(PORT=1521)))  
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.51)(PORT=1521)))  
    Services Summary...  
    Service "+ASM" has 1 instance(s).  
      Instance "+ASM1", status BLOCKED, has 1 handler(s) for this service...  
    Service "+ASM_XPT" has 1 instance(s).  
      Instance "+ASM1", status BLOCKED, has 1 handler(s) for this service...  
    Service "RAC1" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1XDB" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "RAC1_XPT" has 2 instance(s).  
      Instance "RAC1A", status READY, has 1 handler(s) for this service...  
      Instance "RAC1B", status READY, has 1 handler(s) for this service...  
    Service "PLSExtProc" has 1 instance(s).  
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...  
    The command completed successfully  
三、总结(缺省1521端口)
1、RAC 监听的配置当使用缺省的监听器时则监听器名字为 LISTENER_${NODE}
2、如未设置remote_listener,本地实例只在本地的监听器注册。而当设置了正确的remote_listener,则本地实例可以实现远程注册
3、缺省情况下,PMON进程自动将instance_name和service_names等信息注册到已启动的缺省侦听器
4、可以使用alter system register 实现快速注册

Important:

Do not set the GLOBAL_DBNAME parameter in the SID_LIST_listener_name section of the listener.ora.
A statically configured global database name disables connect-time failover.