Locating Oracle’s Network Configuration Files

(This is a revised version of an earlier article. At that time I was using Oracle 10g client on Windows XP. While we have since moved on to newer versions of Oracle and Windows, the demonstrations using 10g are equally applicable to 11g and 12c installations.)

Basic Client TNS (sqlnet) configuration

Continuing the discussion of “Why can’t I connect to my database?”, I want to dig deeper into each of the potential errors in order of their possible occurrence. That will be a rather lengthy journey, so in this article I will focus on locating the configuration files on the client side of the connection. Since the vast majority of connection problems are presented by people using Windows as the client, all examples here will be from a Windows perspective. What a shame! Unix is actually much simpler.

Before discussing the actual configuration files involved, I’d like to take a short side road for background. In my previous article (“Help, I Can’t Connect to My Database”) I tried to drive home the distinction between client and server processes. Here, I want you to clearly understand that the networking component of Oracle is separate and distinct from both the database itself and the client. The Oracle Transparent Network Substrate (TNS) is a group of executables that occupy the session layer of the standard OSI network model. As such, all network communication between a client and an Oracle database ultimately rely on the standard network stack.

In this article I want to discuss the key configuration files used by TNS on the client, and how to locate them – or more accurately, how TNS locates them! There are two of these files, named “sqlnet.ora” and “tnsnames.ora”. Technically, sqlnet.ora is not required, because every essential parameter it can contain has a default value. So sqlnet.ora may not even exist on your system, but I consider it best practice to create it with key information – even if it is default values – just to remove any ambiguity when troubleshooting a problem. Full documentation of every parameter in sqlnet.ora can be found in the Database Net Services Reference. While there are no significant version dependencies, the 11g version is here, and the 12c version is here. One would also be well advised to spend some time in the Net Services Administrator’s Guide (11g) or Net Services Adminstrator’s Guide (12c), paying attention to how the sqlnet architecture relates to the standard network OSI stack.

Of course, the TNS software needs to know how to locate these files, and has two methods of doing so. The first is to look in the default location, which is %ORACLE_HOME%\network\admin. So if you have

ORACLE_HOME=C:\oracle\product\10.2.0\client_1

your sqlnet config files will be located in C:\app\oracle\product\11.2.0\client_1\network\admin. If you have performed multiple installations of Oracle, you have probably created multiple ORACLE_HOME directories and so would have multiple copies of the sqlnet config files – one for each ORACLE_HOME.

This default location of ORACLE_HOME\network\admin can be overridden by use of the environment variable TNS_ADMIN. For example, if you have

TNS_ADMIN=c:\oranet

TNS will try to find the configuration files in c:\oranet. Only if they are not found there will it look in the default location.

So how does TNS even determine the value of ORACLE_HOME and/or TNS_ADMIN? In a proper operating system (any *nix system) it would simply check the environment variables assigned to that process. But since we’re dealing here with Windows, we also have to check the registry. So let’s look at some examples to see the effect of various settings. We can check the result by using the Oracle utility ‘tnsping’. I won’t go into the details of tnsping here. Suffice it to say that one of the things it does (almost as an aside) is report where it found sqlnet.ora. It also shows the address information it got from tnsnames.ora. We can use those two bits of information to see exactly which copy of a file it is using.

Here’s the setup. I have a laptop running Windows XP-Pro. On it I have installed a standard Oracle 10.2 client, with ORACLE_HOME established at C:\oracle\product\10.2.0\client_1. This is my working client setup that I use every day at the office. For this demo, I’m going to simulate a second ORACLE_HOME by creating C:\oracle\product\10.2.0\client_2\network\, and two directories outside of ORACLE_HOME, c:\oranet\admin_3 and c:\oranet\admin_4.

First, let’s look at my current setup. Checking the registry (HKLM\software\oracle) we see that ORACLE_HOME is set to c:\oracle\product\10.2\client_1

And checking the environment at the command line, we see there is NOT a setting for ORACLE_HOME, leaving the registry as the only influencing factor.

C:\> echo %ORACLE_HOME%
%ORACLE_HOME%

Now, let’s see what tnsping says about where it finds the config files:

C:\>tnsping vlnxora1

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 15-FEB-2
011 18:27:09

Copyright (c) 1997,  2007, Oracle.  All rights reserved.

Used parameter files:
C:\oracle\product\10.2.0\client_1\network\admin\sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = vmlnx01)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = vlnxora1)))
OK (40 msec)

C:\>

The key thing to observe here are lines 8 and 9

Used parameter files:
C:\oracle\product\10.2.0\client_1\network\admin\sqlnet.ora

This tells us which sqlnet.ora file was found and used. We see that in this case, TNS was looking for its configuration files exactly where we expected – %ORACLE_HOME%\network\admin. Also notice in line 13, “SERVICE_NAME = vlnxora1”. This information comes from the tnsnames.ora file, and in my setup, that service name is unique to the tnsnames file at that location. So we can know that both the sqlnet.ora and tnsnames.ora files were located at the same place.

Now let’s try some overrides. We’ll set ORACLE_HOME as an environment variable at the command prompt and try it:

C:\>set ORACLE_HOME=C:\oracle\product\10.2.0\client_2

C:\>echo %ORACLE_HOME%
C:\oracle\product\10.2.0\client_2

C:\>tnsping vlnxora1

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 16-FEB-2
011 10:40:52

Copyright (c) 1997,  2007, Oracle.  All rights reserved.

Used parameter files:
C:\oracle\product\10.2.0\client_2\network\admin\sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = vmlnx01)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = vlnxora2)))
TNS-12557: TNS:protocol adapter not loadable

C:\>

Now we see in lines 13-14 that sqlnet.ora was found at the ORACLE_HOME we just specified in the environment variable, overriding the specification from the registry.

We also see a new value for SERVICE_NAME at line 18, indicating the location of tnsnames.ora is also dependent on the new ORACLE_HOME.

Don’t worry about the TNS-12557 error. That is a result of the fact that ORACLE_HOME now points to a directory that has no binaries — remember I just set it up as a test for locating sqlnet.ora and tnsnames.ora. It is not a fully functional ORACLE_HOME.

TNS_ADMIN

Next let’s introduce the TNS_ADMIN variable. Just like ORACLE_HOME, it can be set in the registry, or in the command processor environment. For our next test, we’ll use the registry. Here I’ve added TNS_ADMIN to HKLM\software\oracle

Testing again:

C:\>tnsping vlnxora1

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 16-FEB-
011 10:53:31

Copyright (c) 1997,  2007, Oracle.  All rights reserved.

Used parameter files:
c:\oranet\admin_3\sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP
(HOST = vmlnx01)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = vlnxora3)))
TNS-12557: TNS:protocol adapter not loadable

C:\>

We see that the setting of TNS_ADMIN in the registry overrides ORACLE_HOME in both the registry and the command processor environment.

As one last test, we will add TNS_ADMIN to the command processor environment. This is on top of all of our previous settings:

C:\>set TNS_ADMIN=C:\oranet\admin_4

C:\>echo %TNS_ADMIN%
C:\oranet\admin_4

C:\>tnsping vlnxora1

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 16-FEB-2
011 10:57:12

Copyright (c) 1997,  2007, Oracle.  All rights reserved.

Used parameter files:
C:\oranet\admin_4\sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = vmlnx01)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = vlnxora4)))
TNS-12557: TNS:protocol adapter not loadable

C:\>

And we see that once again the environment setting overrides the registry, and TNS_ADMIN overrides ORACLE_HOME.

Conclusion

The above demonstrations reveal the various settings that control how TNS locates its configuration file (sqlnet.ora) and name resolution file (tnsnames.ora) on a Windows client. It should also be noted that the same rules apply in a *nix environment, except that there is no registry; in a unix environment, all of the settings are controlled by the environment variables. So unix will have far fewer variables to consider when trying to troubleshoot a connection problem.

I started to do some further testing to see how TNS would handle a situation where one of the files was not in the preferred location. Needless to say, with two files to be located, two variables to indicate the location (ORACLE_HOME and TNS_ADMIN) and two places those variables could be defined (registry and session environment), the possible combinations explode geometrically. Life is too short.

At this point you may be asking if you should use the TNS_ADMIN setting or not. The answer, like most everything is …. “it depends”. If you have a simple client installation with a single ORACLE_HOME, there is no reason to set TNS_ADMIN. However, if you have multiple client products, each with its own ORACLE_HOME (say, you require both 32-bit and 64-bit clients) you are faced with maintaining two separate sets of files. There are various ways to approach this problem, but the simplest is to simply pick one location, and set TNS_ADMIN to point to it. As I demonstrated above, if using TNS_ADMIN, the files don’t even have to be in any ORACLE_HOME directory. I’d even argue that this is preferable, as it makes it very clear to anyone examining the system that there is no implied linkage between your TNS config files and any particular ORACLE_HOME.

Further reading

I would urge the reader to spend some time with Google to read up on “OSI Network Model”, keeping in mind that the TNS modules occupy the session layer of the model. One should also spend some time getting familiar with Part One of the Database Net Services Administrator’s Guide. The 11.2 version of that document is here, and the 12.1 version is here.

Charles Hooper has a nice blog article that relates. See Finding a New Home for a Client on Windows.

Postscript:

In reviewing and editing this article for re-publication, I realized that all of the demonstrations were dealing with starting sqlplus from the command line at an already started cmd.exe. I never addressed starting sqlplus or any other client from the context of the Windows “start” menu. Doing so would simply add several more multiplying factors of complexity which, even in review, I see no point in trying to unravel. This just comes back to one of my basic philosophies: “Live by the GUI, die by the GUI”. Perhaps some day when I’m bored and out of ideas I’ll explore this.

Next up: ora-12154 and tns-03505

Film at eleven.

Troubleshooting ora-12154

This is a revised version of an article I originally created using  Oracle 10g client on Windows XP. While we have since moved on to newer versions of Oracle and Windows, the demonstrations using 10g are equally applicable to 11g and 12c installations.

Continuing the discussion of “why can’t I connect to my database?”, I’d like to focus on one particular error – ora-12154. For this discussion and demonstration we will use Oracle’s sqlplus command processor as our client, but the principles apply to any client program that uses sqlnet to connect to the database.

Hardly a day goes by that someone doesn’t post a problem on OTN, reporting they are getting an ora-12154 trying to connect to their database. And invariably they are sent on a wild goose chase, checking everything that can go wrong anywhere along the network stack. And yet, ora-12154 means one thing, and one thing only: The client side of sqlnet could not find the specified connect identifier. Period. And the official description of the error, returned by the Oracle utility “oerr” spells it out:

[oracle@vmlnx01 ~]$ oerr ora 12154
12154, 00000, "TNS:could not resolve the connect identifier specified"
// *Cause: A connection to a database or other service was requested using
// a connect identifier, and the connect identifier specified could not
// be resolved into a connect descriptor using one of the naming methods
// configured. For example, if the type of connect identifier used was a
// net service name then the net service name could not be found in a
// naming method repository, or the repository could not be
// located or reached.

Or more succinctly: “A connection … was requested using a connect identifier (which) could not be resolved into a connect descriptor.” So what is the connect identifier, and how does it get resolved to a connect descriptor? Let’s take the classic, textbook example of a simple client connection request:

c:> sqlplus scott/tiger@orcl

By the rules Oracle uses to parse the command line, the “@” symbol is used to mark the beginning of the connect identifier. So in this example, the connect identifier is “orcl”, and an ora-12154 means an entry for “orcl” could not be resolved to a “connect descriptor” – the IP address, port number, and service name necessary to properly route the request across the network to the Oracle listener. There are several methods available to make this name resolution, but by far the most common is the use of “local naming” – the tnsnames.ora file. This file serves no other purpose, so you should have it fixed firmly in your mind that it is used only by the client process. It is the client’s “telephone directory”. You may see a tnsnames.ora file on the machine hosting your database, but it is still only used by client processes that happen to run on that machine.

With this preliminary information out of the way, let’s dig in and see how many ways we can create (and conversely, fix) an ora-12154. We will first look at a good configuration, then we’ll start taking it apart. My database is running on an Oracle Enterprise Linux server, while my client is running on my laptop, under Windows XP-Pro. My tnsnames.ora looks like this:

# tnsnames.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\net
work\admin\tnsnames.ora
# Generated by Oracle configuration tools.
#===========================
mytestdb =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmlnx01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vlnxora1)
    )
  )

Make a connection to the database, just to show that everything is in order.

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:14:38 2011

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Right out of the textbook! So what could go wrong, to generate an ora-12154?

Wrong naming method

The first thing sqlnet has to do is determine what naming method is being used – exactly how it is to resolve the connect identifier to an IP address, port, and service name. To do this, it looks in the file ‘sqlnet.ora’ (on the client machine, of course!) for the parameter NAMES.DIRECTORY_PATH. If we intend to use local naming, we must set this parameter appropriately:

NAMES.DIRECTORY_PATH=(TNSNAMES)

(Note: the string ‘TNSNAMES’ as a value for this parameter is not the name of the file. It is the name of the method to be used for name resolution. The name of the file used for this method is always tnsnames.ora. )

Let’s set it to some other value (albeit a potentially valid one) . . .

C:>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (LDAP)

. . . and observe the behavior

C:>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:27:46 2011

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

In this example, we told sqlnet to use LDAP naming services to resolve the connect identifier. However, LDAP is not available in my test environment, thus it was not able to resolve “mytestdb”. Lesson: If you want to use local naming, you must specify such in the SQLNET.AUTHENTICATION_SERVICES parameter in the client’s sqlnet.ora file. Let’s fix the problem, then move on:

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES)

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:52:33 2011

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Can’t locate tnsames.ora

The entire subject of locating tnsnames.ora was covered in “Locating Oracle’s Network Configuration Files” . For now, I will create the simplest means of not being able to locate the file – I’ll rename it to something else . . .

C:\>cd C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>ren tnsnames.ora tnsnames.sav

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>dir tnsnames.ora
 Volume in drive C has no label.
 Volume Serial Number is 04C2-AD70

 Directory of C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN

File Not Found

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>

. . . and observe the result:

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:57:14 2011

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

Of course, we fix it by providing a (valid) tnsnames.ora file:

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>ren tnsnames.sav tnsnames.ora

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:58:37 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Can’t find connect descriptor in tnsnames.ora

We’ve told sqlnet to use tnsnames, and we’ve made sure sqlnet can find tnsnames.ora. But what if the connect identifier we provide cannot be found in tnsnames.ora? And more importantly, what can cause it to not be found?

Of course, the simplest reason would be that we just gave it the wrong string. In our example file (shown above), we had a single entry, with the connect identifier of ‘mytestdb’. If we provide a different connect identifier it will, of course fail – again with ora-12154:

C:\>sqlplus scott/tiger@fubar

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:05:48 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

But there is another factor that comes into play at this point. There is an optional configuration parameter that we have not yet discussed. Before looking in tnsnames.ora, sqlnet will check sqlnet.ora to see if the parameter NAMES.DEFAULT_DOMAIN has been set. If it has, it’s value will be appended to the connect descriptor supplied by the user – before searching tnsames.ora for the result. Let’s add that parameter to our existing sqlnet.ora . . .

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES)
NAMES.DEFAULT_DOMAIN=acme.com

. . . and observe the result

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:13:42 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

There are two ways to fix this error. Obviously, we can revert back to our previous configuration by removing the NAMES.DEFAULT_DOMAIN parameter from sqlnet.ora. The other would be to add the domain name to the entry in tnsnames.ora.

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\tnsnames.ora
# tnsnames.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\net
work\admin\tnsnames.ora
#===========================
mytestdb.acme.com =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmlnx01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vlnxora1)
    )
  )

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:30:57 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

tns-03505

That pretty well covers every means of creating an ora-12154 when using local naming. What about the tns-03505 error? Actually, tns-3505 is exactly the same error as ora-12154, with all the same causes and resolutions. The only difference I’ve been able to discover is that tns-03505 is produced when using the ‘tnsping’ utility. Why Oracle chose to code tnsping this way I don’t know, and I’ve been unable to find definitive documentation on this difference but my own testing bears it out.

Using sqlplus . . .

C:\>sqlplus scott/tiger@fubar

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:44:33 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

Enter user-name:

And using tnsping . . .

C:\>tnsping fubar

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 26-FEB-2
011 16:44:42

Copyright (c) 1997, 2007, Oracle.  All rights reserved.

Used parameter files:
C:\oracle\product\10.2.0\client_1\network\admin\sqlnet.ora

tns-03505: Failed to resolve name

C:\>

(Thanks to Sybrand Bakker for pointing out this distinction).

I will discuss uses and mis-uses of ‘tnsping’ in another post.

This’n’that

There is one often overlooked ‘gotcha’ in all this. Remember that when sqlnet is parsing out the connect string, it uses the ‘@’ sign as a meta-character to mark the beginning of the connect descriptor. So if we have this:

c:>sqlplus scott/tiger@orcl

everything is just fine. But suppose there is an ‘@’ sign someplace unexpected. What happens if someone constructs a complex password that includes it?

c:> sqlplus scott/P@ssW0rd@orcl

In this case, sqlnet will take the ‘P’ as the password, and take ‘ssW0rd@orcl’ as the connect descriptor. By now, you can guess the result.

Conclusion

In this article I have attempted to demonstrate every possible cause of an ora-12154 error, as relates to use of tnsnames.ora, for address resolution of a connect descriptor. There is one overriding factor here that should be obvious from the very description of the error, regardless of the naming method used: ora-12154 is a client problem. It has absolutely nothing to do with anything on the server. It has nothing to do with the listener. It has nothing to do with the database. If you are faced with a ora-12154, you can monkey around with your database and/or listener “until the cows come home” and you will not solve your problem. With ORA-12154 your request never left the client process.

Stay tuned for more discussion of sqlnet connection problems.

Dissecting ORA-12545 errors

This is a revised version of an article about ORA-12545 that I originally published while using Oracle 10g client on Windows XP. While we have since moved on to newer versions of Oracle and Windows, the demonstrations using 10g are equally applicable to 11g and 12c installations.

Introduction to ORA-12545

Continuing our discussion of “Why can’t I connect to my database”, I want to focus on “ORA-12545: Connect failed because target host or object does not exist”.

To recap what we’ve covered so far, when an oracle client requests a connection to a database, it has to provide a “connect identifier”, which sqlnet then translates to a “connect descriptor”. The connect descriptor specifies the transport protocol (usually tcp), the ip address of the database server, the port being used by the listener, and the service name the database has registered with the listener. This name resolution is usually done by looking up the connect identifier in the client’s tnsnames.ora file, though there are other methods available as well. Failure to find an entry from which to derive the connect descriptor will result in an ORA-12154: TNS:could not resolve the connect identifier specified, which I explained here.

Once the connect descriptor is determined, that information becomes part of the packet that is passed to the transport layer of the standard OSI network stack and is thus used for standard network routing. This is important to understand. At this point, the routing of the packet to its destination is handled entirely by standard network transport layers.

The Setup

For this demonstration, I am using an Oracle 10.2.0.4 client on Windows XP, connecting to an Oracle 10.2.0.4 database on Oracle Enterprise Linux 5. Name resolution is through tnsames.ora, which looks like this:

fred =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmlnx01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vlnxora1)
    )
  )
Listing 1.

(By the way, I like to use “fred” as an alias name in demonstrations because it should be obvious that it is a totally artificial name that doesn’t have any inherent relationship to anything. As in the above tnsnames example, in a production system I would use the service name (vlnxora1) as the connect identifier, but in demonstrations I want the distinction to be crystal clear.)

The key information we are focusing on is the “HOST = vmlnx01” on line 4.

First, let’s make a good connection to prove that everything is working correctly, then we will break it.

C:\>sqlplus scott/tiger@fred

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Mar 5 09:45:17 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>
Listing 2.

The Demonstration

We know that in order for a message to be routed across a network, we need an ip address. This is like placing a telephone call. If I want to call Moe, I can’t just pick up my phone and dial “Moe”. The telephone company switchboards don’t know anything about Moe. There has to be some mechanism to translate “Moe” to 1-555-123-4567. Likewise the network routers don’t know anything about “vmlnx01”. For your telephone you would have some sort of directory to tell you (or your smart phone!) what Moe’s number is. In a corporate environment, you probably have a DNS server to tell the network stack that “vmlnx01” is 192.168.160.101. The other mechanism, and the one that trumps a DNS lookup, is a file on the client, named simply “hosts”. On unix, this will be at /etc/hosts. On my Windows XP machine it is at C:\WINDOWS\system32\drivers\etc\hosts. Given Microsoft’s propensity for reshuffling the deck with each new release of Windows, I can’t promise that is where the file should be located on your machine!

My hosts file looks like this:

127.0.0.1 localhost
192.168.160.101 vmlnx01 vmlnx01.vmdomain
Listing 3.

For those not familiar with this file, the format is

ipaddress alias1 alias2 .... aliasN
Listing 4.

All hosts files should have the same first line, equating ip address 127.0.0.1 to the alias “localhost”. All other entries typically have two aliases, one with the unqualified server name, the other with the fully qualified servername.domain. That is by convention and for everyone’s convenience, but the fact is these are just aliases for the ip address, and like any alias can actually be anything you want. I will demonstrate that after taking care of the business at hand.

At this point, we know that we told the network to route our request to ‘vmlnx01’, and by using the local hosts file, it was able to translate ‘vmlnx01’ to ‘192.168.160.101’. Let’s set it so that it can’t make that translation, and see what results. We will do that by removing the entry for vmlnx01 from the hosts file:

127.0.0.1 localhost
192.168.160.101 fubar.vmdomain fubar
Listing 5.

Then test:

C:\>sqlplus scott/tiger@fred

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Mar 5 10:13:45 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ORA-12545: Connect failed because target host or object does not exist
Listing 6.

And we have our error. Please notice that we did NOT touch our tnsnames.ora file, which we’ve already proven to be good. This error is simply oracle reporting what the OS network returned. Of course, since it resulted from a mis-match between the HOST parameter in tnsnames and the entries in the hosts file, the proper fix is could be in either file. It is often suggested to avoid this problem by hard-coding the IP address in the tnsnames (HOST=192.168.160.101), but I consider that to be a hack taken by those who do not understand how net name resolution works. It is certainly poor practice to hard-code an IP address any place an alias can be used. Just think of the problems caused by hard-coded IP addresses when the network administrator restructures the net.

Conclusion

This particular error is exactly analogous to “ORA-12154: TNS:could not resolve the connect identifier specified”. With ORA-12154, sqlnet couldn’t find a way to translate “fred” to a complete connect descriptor. With ORA-12545, the OS network layer couldn’t find a way to translate ‘vmlnx01’ to an ip address.

“Film at eleven . . .”

Registering the Oracle database with the listener

In my previous article, ORA-12514: TNS:listener does not currently know of service, I demonstrated the relationships between a client requesting a connection to a database, and the database services known to the listener. In that article I focused only on the immediate cause of the error, deferring the discussion of exactly how databases get registered with the listener. In this article we will take up that discussion and try to clarify the means by which databases come to be known by the listener.

While the examples and documentation references in this article are using Oracle 12c, the same information applies equally to all versions of Oracle at least back to 9i.

The Oracle database listener

The Oracle listener is a process that runs on the database host server – the same machine that hosts the database itself. It serves as a connection broker, and all connection requests that come across the network must first be handled by the listener. If the listener is not up, or if it is up but does not know about the requested database, the connection request will be rejected by the listener without getting anywhere near an actual database.

Before going any further, let me make one point crystal clear. Please burn this into your brain:

One single listener, with the default name of LISTENER, using the default port of 1521, is quite capable of — indeed, was designed to — service multiple databases of multiple versions running from multiple homes.

I often see people trying to create and manage a separate listener for each database on a server. This does nothing to increase performance or security. It only serves to complicate administration and troubleshooting.

You also need to very clearly understand that the database instance and the listener are two completely separate and distinct processes. Creating a database does not create a listener. Neither one (database nor listener) is a sub-process of the other. Just yesterday I had to explain this to a developer in my shop.

Whew! Glad to get that off my chest! Let’s get back to the business at hand.

Database registration

When the listener knows about a database, it is said that the database is “registered” with the listener. Think of the listener as the front desk clerk at a hotel, taking messages for guests. There are two ways he can know who he needs to take messages for. First, he can be given a list of guests. He has no idea how accurate the list is. He doesn’t know if the listed guests actually exist or if they are in the rooms listed. All he can do is say “ok, if someone asks to contact a guest on this list I’ll do my best to connect them.” The other method is for the guests themselves to tell the clerk who they are and what room they are in.

Likewise, there are two methods by which databases are registered with the listener – “static” and “dynamic”. We’ll discuss each in turn.

Static registration

Static registration is like our desk clerk being given a list of guests. In the case of the listener, this “guest list” is the SID_LIST section of the listener.ora file. The listing for each individual, specific SID begins with the SID_DESC identifier under the SID_LIST section.

# listener.ora Network Configuration File: /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/listener.ora
# Generated by Oracle configuration tools.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vblnxsrv02.localdomain)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME=myfubardb)
      (ORACLE_HOME = /u01/app/oracle/product/12.1.0/dbhome_1)
      (SID_NAME = fubar)
    )
    (SID_DESC =
      (GLOBAL_DBNAME=tulsa)
      (ORACLE_HOME = /u01/app/oracle/product/12.1.0/dbhome_1)
      (SID_NAME = tulsa)
    )
  )
Fig. 1

In Fig. 1 we see two SIDs listed: “fubar” and “tulsa” (lines 17 and 22). Checking the status of the listener, we see

oracle:tulsa$ lsnrctl status

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 21-JAN-2016 18:09:42

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                21-JAN-2016 18:09:22
Uptime                    0 days 0 hr. 0 min. 19 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "myfubardb" has 1 instance(s).
  Instance "fubar", status UNKNOWN, has 1 handler(s) for this service...
Service "tulsa" has 2 instance(s).
  Instance "tulsa", status UNKNOWN, has 1 handler(s) for this service...
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsaXDB" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
The command completed successfully

Fig. 2

Notice the entry for service “myfubardb” (Fig. 2, line 23) maps back to “GLOBAL_DBNAME=myfubardb” in the listener.ora file (Fig. 1, line 15) and is related to instance “fubar”, which maps to “SID_NAME=fubar” in listener.ora (fig, 1, line 17). Further, notice that its status is UNKNOWN. This status of UNKNOWN is the indication that this registration came from the SID_LIST section of listener.ora. It is “unknown” because the listener does not make a check to see if there really is an instance named “fubar” broadcasting a service name of “myfubardb”. The listener, like our imaginary hotel clerk, is just saying “if you ask for a connection to myfubardb, I’ll see what I can do to service it.” In fact, I have no database named “fubar” or “myfubardb”.

Notice also that service “tulsa” has two instances, one UNKNOWN and one READY (Fig.2, lines 26 and 27). Like myfubardb, the UNKNOWN tulsa comes from listener.ora (Fig. 1, line 22); the READY instance comes from the database having registered itself with the listener. This is known as “dynamic registration”, and we will delve into that in just a minute.

Again, for our current discussion, we can ignore the service tulsaXDB. This has special internal use for Oracle.

For the remainder of the discussion, I am going to completely remove listener.ora, then restart the listener so that it has no static registrations and is running with all default values:

oracle:tulsa$ pwd
/u01/app/oracle/product/12.1.0/dbhome_1/network/admin

oracle:tulsa$ mv listener.ora listener.save

oracle:tulsa$ ls listener.ora
ls: cannot access listener.ora: No such file or directory

oracle:tulsa$ lsnrctl stop

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 21-JAN-2016 18:21:55

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
The command completed successfully

oracle:tulsa$ lsnrctl start

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 21-JAN-2016 18:22:26

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Starting /u01/app/oracle/product/12.1.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Log messages written to /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                21-JAN-2016 18:22:27
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
The listener supports no services
The command completed successfully

oracle:tulsa$
Fig. 3

With no listener.ora file, the listener will start with all default values and support no services (Fig. 3, line 43) until a database process registers itself. Obviously there is no static registration without listener.ora.

Dynamic registration

Dynamic registration is accomplished when the pmon process of the database instance contacts the listener and requests registration. This occurs at instance startup, and every few minutes during the life of the instance. In our hotel clerk analogy, this is a guest periodically dropping by the front desk to inform the clerk of his availability.

There are three database initialization parameters that affect what service name(s) pmon will register with the listener:

DB_NAME

SERVICE_NAMES

DB_DOMAIN

You should look up each one in the Reference Manual and read the descriptions. (Click on the links) Notice particularly in the description of SERVICE_NAMES the following:

If you do not qualify the names in this parameter with a domain, Oracle qualifies them with the value of the DB_DOMAIN parameter. If DB_DOMAIN is not specified, then no domain will be applied to the non-qualified SERVICE_NAMES values.

There is another interaction that is not spelled out in the Reference Manual, but mentioned in the Net Services Administrator’s Guide:

The service name defaults to the global database name, a name comprising the database name (DB_NAME parameter) and domain name (DB_DOMAIN parameter)

Since neither DB_DOMAIN nor SERVICE_NAMES are required parameters, let’s start with an instance with neither of those set, then start observing how service names get constructed with various settings. For each iteration I will do the following:

  1. Alter an initialization parameter.
  2. Bounce the database (Some of the parameters require it. To keep things clean and consistent, I’ll do it for all of them.)
  3. Restart the listener. (To flush the old registrations.)
  4. Force a new registration. (The database will register on its own, but that may take up to a minute. Here we force it simply to avoid the wait.)
  5. Show the listener status, with the results of the new registration.
  6. Show the values of all three parameters, for comparison.

On the first iteration I will show the entire sequence. On subsequent iterations I will show only the key parts.

(Note that in all of the demonstrations, I take the convenience of stopping and starting the listener from within my sqlplus session. If you are not familiar with it, sqlplus has the ability to have the host operating system execute commands. This is done with the ‘host’ directive, implemented with the ‘!’ symbol. See the SQL*Plus User’s Guide and Reference for more information.)

oracle:tulsa$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.2.0 Production on Sat Jan 23 13:24:14 2016

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> alter system set service_names='' scope=spfile;

System altered.

SQL> alter system set db_domain='' scope=spfile;

System altered.

SQL> startup force;
ORACLE instance started.

Total System Global Area  713031680 bytes
Fixed Size    2928488 bytes
Variable Size  520093848 bytes
Database Buffers  184549376 bytes
Redo Buffers    5459968 bytes
Database mounted.
Database opened.
SQL> !lsnrctl stop

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:25:57

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
The command completed successfully

SQL> !lsnrctl start

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:26:03

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Starting /u01/app/oracle/product/12.1.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Log messages written to /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                23-JAN-2016 13:26:03
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
The listener supports no services
The command completed successfully

SQL> alter system register;

System altered.

SQL> !lsnrctl status

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:26:25

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                23-JAN-2016 13:26:03
Uptime                    0 days 0 hr. 0 min. 21 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
Services Summary...
Service "tulsa" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsaXDB" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
The command completed successfully

SQL> show parameter db_name;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name      string tulsa
SQL> show parameter service_names;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names     string
SQL> show parameter db_domain;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain     string
SQL>
Fig. 4

In Fig. 4, at lines 91 and 93, we see two service names. Both are associated with the instance “tulsa” and derived their name from the initialization parameter “db_name”.

Next, we add a simple service name. While normal practice might be to make it the same as the db_name, I’ll make it different so that we can trace it to the end result. Remember, it is quite acceptable to have multiple service_names, which we will get to in a moment.

SQL> alter system set service_names='edstevens' scope=spfile;

System altered.

SQL> startup force
ORACLE instance started.

SQL> alter system register;

System altered.

SQL> !lsnrctl status

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:34:25

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                23-JAN-2016 13:33:59
Uptime                    0 days 0 hr. 0 min. 26 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
Services Summary...
Service "edstevens" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsa" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsaXDB" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
The command completed successfully

SQL> show parameter db_name;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name      string tulsa
SQL> show parameter service_names;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names     string edstevens
SQL> show pra  arameter db_domain;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain     string
SQL>
Fig. 5

Now we see that all of the service names derived from db_name are still in place, but we have also added one derived from service_names (Fig. 5, lines 34 and 51).

Next we set db_domain

SQL> alter system set db_domain='acme.com' scope=spfile;

System altered.

SQL> startup force
ORACLE instance started.

SQL> alter system register;

System altered.

SQL> !lsnrctl status

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:39:17

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                23-JAN-2016 13:39:17
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
Services Summary...
Service "edstevens.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsa.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsaXDB.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
The command completed successfully

SQL> show parameter db_name;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name      string tulsa
SQL> show parameter service_names;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names     string edstevens
SQL> show parameter db_domain;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain     string acme.com
SQL>
Fig. 6

Notice that all service names – those derived from db_name as well as the one derived from service_names – have the value of db_domain appended to them (Fig. 6, lines 34, 36, 38, and 56).

Next we add a second service name, this one qualified with a second domain name. Not something you’d normally do, but useful for demonstrating the interaction of the parameters

SQL> alter system set service_names='edstevens,wiley.coyote.com' scope=spfile;

System altered.

SQL> startup force
ORACLE instance started.

SQL> alter system register;

System altered.

SQL> !lsnrctl status

LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 23-JAN-2016 13:42:21

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production
Start Date                23-JAN-2016 13:42:20
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/vblnxsrv02/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vblnxsrv02.localdomain)(PORT=1521)))
Services Summary...
Service "edstevens.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsa.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "tulsaXDB.acme.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
Service "wiley.coyote.com" has 1 instance(s).
  Instance "tulsa", status READY, has 1 handler(s) for this service...
The command completed successfully

SQL> show parameter db_name;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name      string tulsa
SQL> show parameter service_names;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names     string edstevens,wiley.coyote.com
SQL> show parameter db_domain;

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain     string acme.com
SQL>
Fig. 7

As before, all of the unqualified service names derived from db_name and service_names have been qualified with the value of db_domain. But notice that we have a new service name (Fig. 7, line 40) from the second value supplied from service_names (line 53). Since this was fully qualified in the service_names initialization parameter, the value of db_domain was not applied.

Conclusion

We have explored the relationship between the connect descriptor issued by the client and the services supported by the listener, as well as the factors that control what services the listener supports.

There is one question I’ve not addressed but hopefully is bouncing around in the back of your mind. Every process (like a database instance) that needs to communicate with another process (like a listener) must have some means of locating that process and delivering the message. Have you asked yourself how it is the database instance actually locates the listener? Especially since the listener is specifically expecting to receive messages from the network? I will take up that issue in my next article, discussing the LOCAL_LISTENER initialization parameter.

Film at eleven …

 

Losing institutional memory

In a recent exchange on the Oracle Technology Network forums, one of the participants asked “What was the Y2K problem ? Please describe in details.” And a few years ago a younger co-worker told me point-blank that he had “read about Y2K” and concluded the whole thing was a hoax.

These comments disturbed me in two different ways.

As one of the legions of programmers who busted their a** for two years to prevent an Apocalypse on 1 Jan 2000, I find this question coming from a member of the IT profession to be truly frightening. Not in the ignorance of the person posing the question. No, I understand that it has been 16+ years and much of the current IT community was in early adolescence (or earlier) at the time. It came to light that the questioner was only eight years old. What is disturbing at how fast we lose ‘institutional memory’. And we see the results of that almost daily on the various forums. Hardly a week goes by that someone doesn’t present a question about one thing or another, and in looking at their table designs we see two critical mistakes in dealing with dates. First, they fail to use the proper data type, either DATE or TIMESTAMP. Instead, they use either NUMBER or VARCHAR2. And to compound the problem, they repeat the same mistake that caused the Y2K crises: they only use the last two digits of the year.

The second thing I find disturbing about the question is the attitude of the questioner. I can understand millennials not having personal memory of Y2K. But I can’t understand millennials not instinctively looking to their favorite search engine to answer such a question. That is the generation that grew up on ‘search technology’. Not only do they (legitimately) not remember Y2k, but they (legitimately) don’t remember a world without ‘search’. And yet it’s the dinosaurs like me, who many consider ‘too old be be in tech’, who constantly have to remind the millennials that “google is your friend, but only if you actually use it.”

And if, at this point you are scratching your head and saying “what’s he talking about? What was the Y2k issue?” … well, “Google is your friend, but only if you use it”.

Think this is brilliant insight? Or that I’m a curmudgeon who is losing it? Either way, let’s hear what you have to say.

The Oracle Transparent Gateway

In this article I will trace the chain of events in establishing a link from an Oracle database to a non-Oracle database, using the Oracle Transparent Gateway. We will see how each configuration point in the chain points to the next, establishing all the links in the chain for an Oracle database to act as a client to a non-Oracle database. I will also show a high-level comparison of how the same functionality is implemented in the reverse situation, where SQL Server is connecting to Oracle.

I first developed this presentation as a response to a statement made by a colleague, regarding the supposed complexity of Oracle. He insisted that Oracle “has too many parts” whereas SQL Server “just automatically connects”. I had to show that regardless of database product, heterogeneous connectivity comes down to the same fundamentals. It is just that various RDBMS products package those functions differently. Before getting into the specifics, let’s take a look at those fundamentals.

Fundamental Number 1: Every database product has its own unique call interface.

This is much deeper than just implementation of the SQL language. It involves the program calls at the binary executable level. Any connection between any two disparate database products must pass through a process to make the necessary translation, to meet the specifications of the receiving binary API. This is the reason ODBC was developed in the first place. If database “A” attempts to connect to database “B”, database “A” is no different than any other client program attempting to connect to database “B”. As far as “B” is concerned, “A” is “just another client” and must be able to communicate with “B”s API.

  • Oracle provides the Transparent Gateway to allow its databases to connect to non-Oracle databases.
  • Microsoft provides OLE DB Providers to allow its databases to connect to non-MSSQL databases.

Fundamental Number 2: All communication relies on established network protocols

All network communication conforms to the Open Systems Interconnection (OSI) model. In the OSI model, communication between separate computers occurs in a stack-like fashion with information passing from one node to the other through several layers of code. These layers are as follows:

  1. Physical layer
  2. Data link layer
  3. Network layer
  4. Transport layer
  5. Session layer
  6. Presentation layer
  7. Application layer

On the client side the communication request enters the OSI stack at the application layer and leaves the client computer at the physical layer. The request arrives at the target (server) computer at the physical layer and works its way back up the stack to the application layer. Further discussion of the relationship between Oracle’s networking components and their place in the OSI model can be found in the Oracle Database Net Services Administrator’s Guide.

Oracle / MSSQL Database Communication Overview

  • Oracle provides translation to MSSQL via the Oracle Transparent Gateway.
  • MSSQL provides translation to Oracle via OLE DB providers.
  • Oracle Gateway and OLE DB Provider serve the exact same purpose. Both come with either a direct host-to-target version, or a generic version that uses ODBC as an intermediary.

database_communication_overview

For the remainder of this article I will show how each link of the configuration points to the next. While I will be demonstrating with an Oracle database connecting to a Microsoft SQL Server database (MSSQL), you can just as easily substitute any other non-Oracle database for the MSSQL references.

SQL statement references a database link

In Oracle’s implementation of the SQL language, the “@” symbol following a table name reference indicates that the table is in another database. The string following the “@” symbol is the name of a database link (db_link). That link provides the first step from the current Oracle database to the MSSQL database.

sql_to_dblink

Database link to tnsnames.ora

When the SQL engine locates the referenced db_link, the value of the ‘hosts’ column is used as the SQL*Net connection string. This can be either a fully formed network address description or a SQL*Net Net Service Name. If the latter (recommended) it will be resolved just like any other client connection request – usually by looking it up in the tnsnames.ora file. It is important to note that the Oracle database itself is acting as a client, so it will be the tnsnames.ora located on the Oracle host server.

dblink_to_tnsnames

Network Transmission

When sqlnet receives the request from the client, it resolves the actual addressing information from tnsnames.ora, creates an IP packet, and hands it off to the protocol layer of the OSI stack.

prep_for_transmission.jpg

Listener Receives IP Transmission

When the listener receives the packet, it sees that the specified SID matches an entry in its SID_LIST configuration – the SID_LIST section of listener.ora. And in that SID_DESC specification, there is a specified program to be launched – dg4odbc. Instead of attempting to spawn a server process to connect the client to a database, the listener will launch the executable db4odbc and pass the name of the requested SID.

listener_receives_packet.jpg

Oracle Gateway Bridges to ODBC

When the program otg4odbc receives the request, it uses the specified SID as the basis for identifying the necessary configuration file. In our example, the SID was specified as ‘northwind’, so the name of the configuration file is ‘initnorthwind.ora’. This file, in turn, provides the ODBC Data Source Name (DSN) used to actually access the target database.

otg_to_odbc.jpg

At this point the final leg of the journey is made by the ODBC driver specified when defining the DSN ‘northwind’. Configuration of the ODBC DSN is as appropriate for the target database.

Once these connections are made, the final communications path is as follows. The originating database, through its db link, communicates with the Oracle Transparent Gateway for ODBC, via a sqlnet link. The gateway communicates with the ODBC driver. And the ODBC drive communicates with the target database.

OTG_complete_chain.jpg

Conclusion

If you have followed this carefully, you should have a much better understanding of how the pieces fit together. There are a few points that bear highlighting:

  1. We used the database name ‘northwind’ throughout. While it is nice to have the same name at every point, you need to be aware of where the same name is required between two points and where one usage is just an alias for the next. For instance, at the very beginning we had a database link named ‘northwind’ that referenced net service name (tnsnames.ora entry) named ‘northwind’. Technically, we could have made the net service name something else. Oracle would not care. It is just for our own sanity as humans that we keep the same name throughout.
  2. The listener is only involved in getting the server process (otg4odbc) started and informing the calling client what port to use for continued communications. Once that is done, the listener is out of the picture. The listener’s port (1521, by default) is only used to contact the listener. It is not used for continuing communication between the client database (Oracle) and the target database.
  3. The Oracle Transparent Gateway can reside on any server. It is not required that it be on the same server as the originating Oracle database. Nor is it required that it be on the same server as the target non-Oracle database. In my shop, we have multiple Oracle databases residing on multiple servers. Each database is subject to having links to multiple MSSQL databases, also residing on any of several different servers. To simplify administration, I selected one server to host the Oracle Transparent Gateway for all combinations. This could be one of the Oracle servers. Or it could be one of the MSSQL servers. Or it could be another server that hosts no database at all.

Questions? Feel free to ask. My next article will explain the same process in reverse – when an MSSQL database uses its linked server mechanism to act as a client to an Oracle database.

Film at eleven . . .

Solving the Non-Problem

Sometimes the solution to a problem is not technology.

Many years ago I read a column in PC Magazine, written by by John Dvorak. In the article, Mr. Dvorak was questioning the growing popularity of digital pagers. That alone gives a clue as to how long ago the article was published. In the article, Mr. Dvorak made the case that very few people using pagers really needed them. After all, he asked, what business decision can’t wait until normal business hours the next work day? He went on to talk about people wearing pagers on their belt as a way to advertise their own self-importance. I witnessed that first-hand with a co-worker at the time who was always offering to take other people’s pagers while they were on vacation. And he always managed to work into any conversation the subject of how many pagers he was wearing.

I was reminded of this while reading a question posed on the Oracle Technology Network user forums. The person was asking how to implement a database trigger to notify the HR manager — on his smart phone — whenever a new employee record is inserted into the database.

Seriously?

The absurdity should be blindingly obvious. Think about the chain of events leading up to a new employee joining a company. Especially a company that is big enough to have an HR manager and a high-powered RDBMS like Oracle. Regardless of the specific mechanics of each step, we reach a point where a job offer is made. Then the offer is accepted. Then a report date is agreed upon. Then the new hire shows up and reports to the HR department for in-processing. Even in a utopian “paperless” office he is probably going to have to apply ink to cellulose to fill out some forms — some internal to the company and some dealing with government regulations and/or taxation.

So at what point in this sequence of events should the HR manager be notified? And why (and this is the crux of the matter) is it so all-fired important that the manger be notified on his smart-phone the instant any particular new-hire event happens? What is he going to do with that information that can’t wait until the next time he happens to check his e-mail? What is he going to do with that information that can’t wait until the next business day? To repeat a question that is often asked on the OTN forums, “What is the business problem you are trying to solve?” In this particular case, what is the business problem that is solved by notifying the HR manager the instant the process of acquiring a new employee has reached to point of entering them into the database?

And that brings us back to my opening statement. Sometimes, the solution to a problem is not technology. Quite often, the solution is to re-define the problem. Or (as in this case) to simply question the problem iteself. Far too often we see DBA’s simply rolling over for every hair-brained idea the “Pointy Haired Boss” can dream up, and trying to implement a convoluted technical solution to problem that is not really a problem at all. The solution in searchof a problem. The solution to the non-problem..

What about you? What’s the most absurd non-problem you’ve ever been asked to solve?

By the way, I was unsuccessful in finding an archive of the PC Magazine article. If anyone can locate it and post the link, I’d be happy to share it.

Create a private Oracle test lab – for free

I often see people afraid to try even the simplest of tasks on their Oracle databases, asking “Can I <fill in the blank>?” When it is suggested they try for themselves and see what happens, the common excuse is “I don’t have a test system.”

Every oracle professional (or student) should have their own private computer lab. I’m assuming in this day and age anyone in this category already has their own computer, and that is all the financial investment you need. Starting from there, you should do the following:

  1. Download and install Oracle VM Virtual Box on your personal computer. This is a virtualization product that allows you create complete virtual machines on your desktop/laptop computer. Total cost: $0.00.
  2. Download Oracle Linux. Oracle freely distributes this, only charging if you want a support contract. Total cost: $0.00.
  3. Using your downloaded linux, create a virtual linux machine.
  4. Go to oracle.com and download whatever database or related product you want. The terms of the oracle license agreement allow you the full use of any product for personal study. Total cost: $0.00

By doing the above I have a full computer lab running on my Windows laptop, for a total cost of … (drum roll, please) …. zero dollars, US.

By building such a private lab I am able to create multiple virtual systems that communicate over a private virtual network and so are totally isolated from my corporate network and/or my ISP. This is how I worked out the details for my first Data Guard configuration before committing to my organization’s live databases. People have also used this type of private lab to get their first hands-on with RAC.

Each vm is a task to the host operating system, running in its own window with represents the machine’s console. However, I treat that console like I do the consoles of my physical servers that live behind a locked door in a lights-out data center. With my various virtual machines up and running, I access them with tools on the host desktop, exactly the same as the servers in my data center. I use PuTTY for command line ssh connections and sqlplus and SQL Developer for database access. If I have a virtual machine running Windows, I access it with Windows Remote Desktop.

The number of virtual machines you can have created will be limited by your available disk space, and the number you can have up and running at one time will be limited by the amount of memory available on the host system. Most consumer class systems these days seem to come with a minimum of 500gb of disk, which is more than sufficient for three or more virtual servers. You will want a minimum of 4gb of RAM for a single VM, and 8gb of RAM to have 2 or 3 vm’s running at once.

Don’t expect blazing performance but that is not the purpose. What is the purpose is to have your own test system available at any time to test whatever you want to test, with zero risk of damaging a production system. (And don’t forget that for your developers, the “test” system is production!)

I have deliberately not provided any details on locating, downloading, installing, etc. I leave that as a valuable learning exercise. Oracle does provide some completely configured “appliance” virtual machines, but I strongly feel that using them cuts out a valuable learning experience for the aspiring DBA. My understanding of networks and operating system administration benefited greatly by working through all the detail myself, with the assistance of various subject-matter user forums and other assets on the internet.

So quit complaining about not having a test system and go build your own! No excuses!

VirtualBox Computer Lab Framework

In my article, Create a Private Oracle Test Lab I expressed my opinion that every serious student of Oracle databases should have their own private computer lab. In Configuring the Oracle Virtual Box Network, I detailed the specifics of configuring the network adapters in virtual machines running under VirtualBox. In the time since I wrote those articles I have observed many people on the Oracle Technology Network forums attempt to create a test setup, but with no real thought going into creating a coherent framework in which to build a useful and flexible laboratory.

Now I would like to “connect the dots” and detail the framework within which I have created scores of virtual machines on either my personal laptop or my company-issued desktop. Within this framework, I have had a full suite of virtual machines running Oracle Linux, Suse, Ubuntu, Solaris and Windows, with as many as three different machines running simultaneously. All of these virtual machines communicate with each other using standard network protocols, exactly as if they were physical servers in my company’s data center.

In this article, I will detail exactly what goes into creating that framework. In reality, the actual framework is little more than a few standard directories and the installation and configuration of the virtualization software, which will be detailed at the end of the article. Before getting there, I will explain the thought process that went into the creation of my virtual test labs and the standards I set for myself. It is my hope that the reader will be able to use that to develop a framework that works for him.

I will not be discussing the actual creation of a VM or the installation of any software on that VM. Once you have a consistent framework, there are is any number of resources on the web to help with the creation of specific VMs. And who knows? I may add my own contributions to that body of work, in later articles.
Rational

Before getting into the details, I would like to recap and expand my original rational for building a private virtual computer lab, and add some additional points based on my observations since publishing the original article.

For the working professional, even systems designated as ‘test’ or ‘development’ have certain up-time and stability requirements. Loss of a “test” system can have a severe impact on the developers. For the student, access to a live system may be non-existent. For these reasons, it is imperative that every professional or student leverage the power of their personal computers and the availability of virtualization products to create a private (or “sandbox”) computer laboratory consisting of one or more virtual computers. Such an environment allows testing of almost any aspect of the system without concern for damaging a system that others rely on. There is simply no excuse for anyone to say, “I don’t have a system to test that on.”

Another advantage of the private virtual laboratory is that it allows the operation of a test system on an operating system other than that of the host system. The vast majority of personal computers are a “Home” edition of Windows, with a lesser number of Macs. A virtual machine can run any operating system supported by the virtualization software. The database software is concerned only with the operating system on which it is installed, not the host operating system behind the virtual machine. So even if the only computer you actually have administrative access to is your personal Windows 7 Home Edition you can still have a Unix or Windows Server test machine.

A third advantage of the virtual laboratory is that it allows the test system run with its own network identity. This allows it to be dealt with exactly as if it were a live system in the corporate data center instead of something grafted into the desktop system. I often help people on OTN who are installing Oracle database software directly on their desktop OS. Quite often, their problems stem from being blissfully unaware of the networking implications of true client-server architecture. They are then flummoxed when faced with a real system and the network considerations that entails.
Preliminaries

Before getting into the configuration of your PC, let’s consider a few items.
Terminology

Before anything else, we need to clarify some terms

Host. Within the context of this article, the term “host” refers to the physical computer and its own operating system.

Server. Within the IT industry, the term “server” is used in two ways. First and foremost, it refers to a process that provides services to one or more other processes running on the same or other computers. Second, it may to refer to a computer whose primary purpose is to run server processes.

Client. In general, a “client” is any process that requests services from a server process. However, in the context of creating virtual machines that run as a task under a host operating system, it is common to refer to those virtual machines as “client machines”. This can be rather confusing since we also commonly refer to them as “servers”. However, in the context of the relationship of the VM to the host it is technically correct. The virtual machine itself is requesting hardware services from the host OS. As far as the host is concerned, the VM itself is a client. On the other hand, the purpose of these virtual machines is to act as a server – usually a database server. Within the framework of our lab, the client process requesting services from the virtual machine server will often be running on the host OS.

The better you understand “client” and “server” in terms of processes instead of machines, the better you will understand this article. In fact, the better you understand “client” and “server” in terms of processes instead of machines, the better you will understand many other things about computer technology.

Unix. While I make frequent reference to the Unix operating system, it should be understood that what is said can apply equally to any Unix-based system, such FreeBSD, AIX, Solaris, Linux, etc.
Hardware Selection

You probably already own your own personal computer. If it is relatively new, it will most likely meet your needs for at least one VM. However, if you are considering buying a new one, or are a bit unsure of the suitability of your current PC, here are some things to consider.
Processor

You will want a machine with a 64-bit processor. As of this writing, it appears that all available consumer-class desktop/laptop computers are built with 64-bit Intel or AMD processors. 32-bit processors are a thing of the past, so this may no longer be a point of real concern.
Memory

RAM (Random Access Memory) will be the limiting factor on how many VMs you can have running simultaneously. If you are planning to run only one VM at a time, 4 GB may be sufficient. However, if you will need to run multiple VMs at one time (as in an Oracle RAC environment) you really should get 8 GB, which as of this writing seems to be the maximum available for most laptops. True desktop machines can easily accommodate up to 16 GB. While most desktop class machines are pre-configured with 2 GB to 4 GB, an upgrade to as much as 16 GB can be well worth the incremental additional expense.

When you create the virtual machine, the memory that you specify for it will be allocated out of the real memory of the host system. If you specify the VM has 2 GB of memory, when you start that VM it will require 2 GB of real memory from the host. One must keep in mind how much memory the host OS requires for its own operations. For example, on a minimally configured 4 GB host running Windows, the host Windows OS will require 2 GB for itself, leaving only 2 GB for any and all other processes, including any VMs.
Disk Space

Disk space will be the limiting factor for how many VMs you create, irrespective of how many are running simultaneously. As of this writing, most entry-level desktop class machines come standard with 500 GB hard drives, and one terabyte drives are becoming increasingly common. Plan on 30 GB to 50 GB per VM. The purpose of these VMs is not to have fully populated application databases, but to have a system on which to test features and techniques.
Host Operating System

The host OS can be any OS capable of running the selected virtualization product. Given the proper hardware support in the CPU, it is possible to run a 64-bit virtual machine on a 32-bit host. However, given that virtually all consumer-class computers are built on 64-bit hardware there is simply no reason to be running a 32-bit host OS.

NOTE: Since Windows is by far the most prevalent desktop OS, all procedures in this and related documents will assume the host OS is Windows. It should be very easy to adopt the principles to other desktop systems such as Apple or Linux.
Virtualization Software

When I started building my first VMs I used VMware’s VMplayer. It was a very capable product and was free. While it was fully capable of meeting my needs, it did lack some nice management features, so I soon shelled out $180 to purchase the full-featured VMworkstation. After a few years, I became aware of a product called VirtualBox. That product had all of the features of VMworkstation and was available at no cost. It was increasingly becoming the product of choice in the Oracle community so I made the switch. As I write this, it appears that VMware no longer has a free offering, and VMware Worksation Pro now costs $250.

Oracle VM VirtualBox was created by Innotek GmbH, purchased in 2008 by Sun Microsystems, and acquired by Oracle in 2010 as part of their purchase of Sun. VirtualBox (aka “VBox”) provides the same full feature set as VMworkstation, but is available as a free download from Oracle. There is no official support, but there are two user forums, one at the Oracle Technology Network forums and forums.virtualbox.org. It has come to be the de facto standard among the Oracle community for creating personal virtual environments. For that reason, it is the product that will be used in this and related documents.
Naming Standards

Before beginning to create the infrastructure, it is best to think through some standards. While the specific standards may be considered somewhat arbitrary, experience has shown that systems are much easier to manage when standards are well thought out and detailed. A good standard will provide names that are meaningful and a structure that is predictable and allows for future growth. It will be extensible and flexible, yet not overly complex – not too restrictive, yet not so broad as to be meaningless.

In the end, the existence and use of a well thought out standard is more important than the details of a specific standard. The naming standards really are at the heart of creating the virtual laboratory framework.

For my laboratory framework, I start with standards for naming the virtual machines and for a directory structure that will be created on the host system.
Server Names

The naming standard for VMs presented here is only an example. The reader is encouraged to develop their own, especially in light of any standard used in their corporate environment. If building a virtual server to mimic a live server in a corporate environment, one should adopt a naming convention that will both distinguish the virtual server from its live counterpart and at the same time make it clear which live system the virtual system is replicating. For instance, if the organization has a naming convention in the format

‘ITxxxxxx’, where:

IT – fixed literal

xxxxx – variable identifying information

One might replace the corporate fixed literal of “IT” with literal of “VB” for “Virtual Box”. For example, if the corporate machine were named ITORASRV, then the name of the VM running under VirtualBox would be VBORASERV.

In the infrastructure detailed in this series of documents, virtual machines are named as follows.

Sever name = aabbbcccnn where

aa – Virtualization Product

vb – the VM runs under VirtualBox

vm – the VM runs under VMware

bbb – Operating system

olx – Oracle Linux

ubn – Ubuntu Linux

sus – Suse Linux

sol – Solaris

win – Windows

ccc – user defined

Within the overall naming standard set forth here, this lends itself to whatever makes sense in the user’s own experience. One might use this to differentiate between database and application servers, or between server and desktop systems, or to designate the application associated with it. Just determine for yourself how it will be used, then stick with it.

nn – Sequence to create a unique name within the previous indicators. Number from 01 to 99. Always use two digits
Configuring the host system

Finally! Now that we’ve gotten all the preliminaries out of the way, let’s start configuring the host system.

Configuring the host system consists of the following steps

Create a common directory structure on the host
Install and configure VirtualBox
Install ssh client
Install x-windows server

Create a Common Directory Structure

While the virtualization products themselves can be installed into whatever default directory they normally use, it is helpful to keep all files and directories created to support the VMs under a common directory, with sub-directories for the various support files

Create the following directories.
C:\VMLab Parent directory for the entire VM infrastructure.
C:\VMLab\VBMachines

Parent directory of VMs created under VirtualBox. (If using VMware products, the directory would be C:\VMLab\VMMachines.

NOTE: The virtualization products have a default location in relation to their software installation location. In keeping with our objectives, we will modify this default to use the directories we create for this purpose.
C:\VMLab\VBMachines\backups Directory where you will keep backups of the virtual machines. More on that later.
C:\VMLab\VBShared Virtual disks that are shared across VMs under VirtualBox. Used when creating Oracle RAC setups.
C:\VMLab\hostshare Shared across all VMs; holds files that are shared across VMs or persisted across changes to a VM. Will be mounted to each VM through the VirtualBox “shared folders” facility.
C:\VMLab\hostshare\setup Shared across all VMs; holds the scripts that I use specifically for the initial setup of the VM once the OS is installed.
C:\VMLab\media Staging area for software installed on the VMs. You may find it useful to create product-specific sub-directories below this.
C:\VMLab\media\OracleDatabase_112010_linux_x64

Example of a product-specific subdirectory under the media directory. Under this directory, I would place the downloaded distribution files for Oracle Database, version 11.2.0.1.0, for 64-bit Linux. I have a further naming standard for these directories of

___
Install and Configure VirtualBox

VirtualBox is an open source product distributed by Oracle Corp. It is freely available in the “Downloads” section at http://www.oracle.com. Download and installation instructions are available at that point.

Once installed, start VirtualBox and set the default directory in accordance with our standards, as detailed in the following procedure.

1. Open the “File” menu

After starting the VirtualBox Manger, open the “File” menu

Select VirtualBox Manager File Menu
Select VBox Manager File Menu

2. Select “Preferences”

In the File sub-menu, select “Preferences

Setting VirtualBox preferences’
Select ‘Preferences’

3. Set the default machine folder

In the “VirtualBox – Settings” window, select the “General” tab in the options list, then set the “Default Machine Folder” to the host system folder created for this purpose.

Setting VirtualBox default machine folder
Enter then name of the default machine folder

NOTE: The drop-down for this field will lead to a dialog that will allow you to navigate and drill down to the selected folder, eliminating the need to type in the specification.

4. Save the settings

Click “OK” to save the settings, then exit VirtualBox

Confirming the VirtualBox preferences
Accept the changes

5. Note the address of the VirtualBox network adapter

Installing VirtualBox created a network adapter on the host system. You will need to know the IP address of this adapter when you create your virtual machines.

On the host desktop, open a command prompt and enter the “ipconfig” command

C:\>ipconfig
Windows IP Configuration Wireless LAN adapter Wireless
Network Connection 2:
Media State . . . . . . . . . . . :
Media disconnected Connection-specific DNS Suffix . :

Make a note of the IP address assigned to the VirtualBox host network adapter. In this example, the address is 192.168.56.1.

Ethernet adapter VirtualBox Host-Only Network:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::70fb:5067:d2c5:6586%29
   IPv4 Address. . . . . . . . . . . : 192.168.56.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

Install ssh client

The standard interface to Unix systems is a simple command-line ssh client. There are several products available, but my favorite is the simple, lightweight PuTTY. The official download page is at chiark.greenend.org.uk.

The architectures of Unix and Windows are vastly different. One place this becomes apparent is in their implementation of a graphical interface. With Unix you can install any number of different products to provide a graphical desktop. The most common are Gnome and KDE. I’ve played around with them a bit, but I still prefer the speed and simplicity of the simple command line shell. If you insist on using a graphical desktop with a Unix system, Google will be your friend.
Install X-server

Any time a *nix system executes a program with a graphical interface (such one of the aforementioned graphical desktops, or the Oracle Universal Installer) the program redirects it’s graphical interface to a specified network address and port, where it expects to find an x-server process capable of handling it. Therefore, we must install an x-server on our host desktop. I recommend a product known as ‘xming’. It is free, has a small footprint and simple installation. X-ming can be downloaded from the Sourceforge.net site.
Conclusion

If you have followed this article carefully, you should now have the following:

A clear directory structure for placing your virtual machines and installation software to be used on those machines
An installation of Oracle Virtual Box, configured to place any virtual machines within the custom directory structure.
The “client” programs necessary to interface with any Unix virtual machines you create.
A workable naming standard to bring some consistency and sanity to naming your virtual machines.

A Few Points About Dynamic Registration

In a recent thread on OTN, the OP was having a difficult time understanding dynamic registration. They were confused about the interactions of settings in listener.ora, tnsnames.ora, and the local_listener parameter. After responding to the thread with a summary, I thought it might be worth repeating here, along with a few more references. I actually covered all of these points in earlier articles, “Registering the Oracle Database With the Listener” and “Exploring the Local Listener Parameter“, but sometimes a simply restating key points can help clarify things for some people.

In short, the summary of important points are as follows:

1) The listener itself doesn’t give a flying fig about what is in tnsnames.ora. That file (tnsnames.ora) is used ONLY by client processes. In the case of dynamic registration, the database IS the client process.

2) The listener is quite capable of starting with no listener.ora file at all. In this case it will start with all default values, including the default name of LISTENER and default port of 1521. For most people, most of the time, this is sufficient.

3) If the local_listener parameter is not set (null) the database will send the registration request to port 1521. Notice that 1521 is also the default port of of the listener.

4) If you choose to set local_listener, you can either use a full connect string ((ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1421))) or simply reference an entry in tnsnames.ora, to resolve to the address (server name and port) of the listener.

5) The SID_LIST section of listener.ora has nothing to do with dynamic registration. Quite the opposite. The SID_LIST section is how you implement static registration.

The original thread on OTN may be found here: “Oracle Net Service Configuration“. In that thread, there was also a link to a very nice explanation by Martin Beach on his blog “Martin’s Blog”, “Little things worth knowing-static and dynamic listener registration