I’ve been to more than one RAC customer site and seen several different ways to misconfigure the listeners for a RAC cluster. This post describes how I usually configure the listeners and their associated instance parameters normally. This really has nothing to do with TAF or connection load balancing, those those features may not work as expected unless the underlying configuration is performed properly.
First, some background on how these items work is necessary. The TNS listener (tnslsnr process on *nix) process listens on a specific network address for connection requests to one of the services from one of the database instances that it services. When requested, it either spawns a server process (dedicated server environment) and connects the user to that process or forwards the connection request to a dispatcher (shared server environment) for service to the database service requested. Alternatively, if the listener knows of more than one instance providing the requested service, it may direct the client to an alternate listener (usually on a different node) that will service the request.
In any Oracle database configuration, listeners define the instances as local or remote (in single-instance environments, normally everything is local). You can see this behavior when examining the “lsnrctl services
” output (lsnrctl syntax reference here). A listener’s services are those services that have been registered with it by instances. A listener will accept registration from any instance (this may be a weak point of security, but that’s another topic) and listeners have no outbound communication with any other entity in the Oracle environment (or beyond).
The remote_listener
parameter specifies a list of listening endpoints that the local instance should contact to register its services. This list is usually defined in a TNS entry in the tnsnames.ora file and then the TNS alias set as the value of the remote_listener
parameter. Here’s a sample of what that entry might look like:
LISTENERS_CLUSTERNAME=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=node3-vip)(PORT=1521))
)
The local_listener
parameter is sometimes confusing. It defines where to connect to the local instance, but its most important function is related to remote listeners. The contents of the local_listener parameter are passed along to the remote listeners during remote registration so that when those remote listeners wish to refer a connection request to the local instance, they refer the client (requestor) to the proper listening endpoint so it can get connected. The local_listener
should contain the ADDRESS
section of the TNS entry and the HOST
portion should reference the VIP address, like this: (ADDRESS=(PROTOCOL=TCP)(HOST=node3-vip)(PORT=1521))
To properly (manually) configure listeners in a RAC environment, I follow the steps like the ones below. Note that in most cases, the Oracle Net Configuration Assistant (netca) will do this for you as part of the database creation process.
HOST=
lines in the listener.ora definition reference the VIP addresses (and only the VIP address). I prefer to specify IP addresses instead of hostnames or DNS names here to avoid possible lookup issues and/or confusion.HOST=
parts reference the VIP addresses of each node (I used names instead of IP addresses here to avoid reader confusion–I’d put in IP addresses in the HOST=
attributes when using this for a real configuration.).
<>3.4.5.6.7.Set the remote_listener
parameter in the instances (a global parameter, not an instance-specific parameter) to be the name of the TNS entry you created in the previous step. This is done with “alter system set remote_listener = 'LISTENERS_CLUSTERNAME';
“
Set the local_listener
parameter to be the ADDRESS
string for the local instance. This parameter must be an instance-specific parameter with each instance having a similar, but unique value since each instance runs on a different HOST
. If the local instance (called inst1 in the example here) runs on a node with the node VIP of 10.3.121.54, then set the local_listener
parameter accordingly for each instance (it is instance-specific, so use the sid=
syntax): alter system set local_listener = '(ADDRESS=(PROTOCOL=TCP)(HOST=10.3.121.54)(PORT=1521))' sid='inst1';
On each instance, you can run “alter system register;
” to force immediate registration with the listeners. If you don’t do this, the listener registration will usually be updated within a minute or two anyway (automatically), but this command can help shorten debugging cycles when necessary.
One final tip is to use the lsnrctl program to get information about the current state of the listener. I find it helpful sometimes to get verbose information about the services and here’s how I do that. In this example, the listener name is
LISTENER_NODE1
(listeners usually get named as LISTENER_
).
LSNRCTL> set curr listener_node1
Current Listener is listener_node1
LSNRCTL> set display verbose
Service display mode is VERBOSE
LSNRCTL> servic
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip)(PORT=1521)(IP=FIRST)))
Services Summary...
Service "myservice.world" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:blocked
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip.dannorris.net)(PORT=1521))
Instance "rac2", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:ready
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip.dannorris.net)(PORT=1521))
Service "rac.world" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:blocked
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip.dannorris.net)(PORT=1521))
Instance "rac2", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:ready
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip.dannorris.net)(PORT=1521))
Service "racXDB.world" has 2 instance(s).
Instance "rac1", status READY, has 0 handler(s) for this service...
Instance "rac2", status READY, has 0 handler(s) for this service...
Service "rac_XPT.world" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:blocked
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip.dannorris.net)(PORT=1521))
Instance "rac2", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:ready
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip.dannorris.net)(PORT=1521))
The command completed successfully
https://www.dannorris.com/blog/2008/07/21/tns-listener-configuration-for-oracle-rac/#comment-353