Connect
Oracle to another DB
This document describe one of the most troblesome configuration I have
ever set up.
It took me almost two days to figure out how to properly set everything
to make it works so I'm writing this documentation to spare a headache
to other sysadmins/DBA who wish to achieve the same.
I divided the process in three steps:
- DB2 client configuration,
- odbc configuration,
- heterogeneous connectivity configuration.
First and third points have been the hardest since my knowledge of DB2
is limited.
DB2connect configuration
First of all install the DB2 client (for me it was DB2connect 7.1) and
register it with the proper license (using db2licm).
Now you are ready to register your remote database.
I'll need to provide:
hostname,
port,
database name,
authentication method.
For every DB I need three registrations: tcp/ip node, database and DCS.
Let's start from the tcp/ip node.
Connect to your db2 user (by default db2inst1):
db2inst1@brepredbls01:~> db2
(c) Copyright IBM Corporation 1993,2001
Command Line Processor for DB2 SDK 7.2.0
db2 =>
Now from the db2 client command prompt:
catalog tcpip node <nodename> remote <hostaname> server
<port>
where nodename is an alias you choose, hostname is the DB2 remote
hostname and the port is the DB2 listening port.
example:
catalog tcpip node RIHEP remote rihep.rit server 5023
to unregister it:
uncatalog node RIHEP
and to list the register nodes:
db2 => list node directory
Node Directory
Number of entries in the directory = 3
Node 1 entry:
Node
name
= AMDSPT
Comment
=
Protocol
= TCPIP
Hostname
= amdahlsvil.ras
Service
name
= 5023
Node 2 entry:
Node
name
= AMSVIL
Comment
=
Protocol
= TCPIP
Hostname
= amdahlsvil.ras
Service
name
= 6021
Node 3 entry:
Node
name
= RIHEP
Comment
=
Protocol
= TCPIP
Hostname
= rihep.rit
Service
name
= 5023
Now you need to catalog your remote DB2 database:
catalog database <DBname> as <DBalias> at node
<nodename> authentication DCS
Where DBname is the name of the remote database, DBalias
is the name you are going to use in your connection and nodename is the
node alias you registered above.
The chosen authentication has been DCS for my environment.
Example:
catalog database ITFINDB2 as ITFINDB2 at node RIHEP
authentication DCS
If you wish to unregister the DB:
uncatalog database ITFINDB2
for the list:
db2 => list db directory
System Database Directory
Number of entries in the directory = 3
Database 1 entry:
Database
alias
= ITFINDB2
Database
name
= ITFINDB2
Node
name
= RIHEP
Database release
level = 9.00
Comment
=
Directory entry
type
= Remote
Authentication
= DCS
Catalog node
number
= -1
Database 2 entry:
Database
alias
= DB2PROD
Database
name
= DB2PROD
Node
name
= AMSVIL
Database release
level = 9.00
Comment
=
Directory entry
type
= Remote
Authentication
= DCS
Catalog node
number
= -1
Database 3 entry:
Database
alias
= DB2DSPT
Database
name
= DB2DSPT
Node
name
= AMDSPT
Database release
level = 9.00
Comment
=
Directory entry
type
= Remote
Authentication
= DCS
Catalog node
number
= -1
Last registration step: the DCS.
catalog dcs database <DBname> as <DBalias>
example:
catalog dcs database ITFINDB2 as ITFINDB2
to unregister:
unregister dcs ITFINDB2
For the list:
db2 => list dcs directory
Database Connection Services (DCS) Directory
Number of entries in the directory = 3
DCS 1 entry:
Local database
name
= DB2DSPT
Target database
name
= DB2DSPT
Application requestor
name =
DCS
parameters
=
Comment
=
DCS directory release
level = 0x0100
DCS 2 entry:
Local database
name
= DB2PROD
Target database
name
= DB2PROD
Application requestor
name =
DCS
parameters
=
Comment
=
DCS directory release
level = 0x0100
DCS 3 entry:
Local database
name
= ITFINDB2
Target database
name
= ITFINDB2
Application requestor
name =
DCS
parameters
=
Comment
=
DCS directory release
level = 0x0100
Now you can check if your configuration is correct:
db2 => connect to ITFINDB2 user sisbanc
Enter current password for sisbanc:
Database Connection Information
Database server = DB2
OS/390 7.1.1
SQL authorization ID = SISBANC
Local database alias = ITFINDB2
This indicate a succesful connection.
An error or a command prompt without output indicates a failure.
ex:
db2 => connect to ITFINDB2 user sisbanc
Enter current password for sisbanc:
db2 => db2 =>
unixODBC configuration
If the DB2 client is set correctly you can step forward.
Now you need to configure your odbc.
I installed on my SLES9 the unixODBC package using yast (the operation
is really simple).
Now in /etc/unixODBC I'm going to store all my configuration files
(basically odbcinst.ini and odbc.ini).
This is my odbcinst.ini
db2inst1@brepredbls01:~> cat /etc/unixODBC/odbcinst.ini
[DB2]
Description = ODBC for DB2
Driver =
/usr/IBMdb2/V7.1/lib/libdb2.so
FileUsage = 1
DontDLClose = 1
Here I simply configured a generic entry called DB2 which uses the
driver (library) of the DB2 client installed and set above.
The important part is the driver. Make sure the location of the
libdb2.so is correct on your system.
For the odbc.ini:
db2inst1@brepredbls01:~> cat /etc/unixODBC/odbc.ini
[DB2PROD]
Description = DB2PROD for
Prevint
Driver
= DB2
Database =
DB2PROD
#DMEnvAttr =
SQL_ATTR_UNIXODBC_ENVATTR={DB2INSTANCE=db2inst1}
[ITFINDB2]
Description = ITFINDB2 for
Prevint
Driver
= DB2
Database =
ITFINDB2
[DB2DSPT]
Description = DB2DSPT for
Prevint
Driver
= DB2
Database =
DB2DSPT
I have three entries like the three databases I configured in my
systems.
All has the driver set to DB2 which indicates they have to take the
entry in your odbcinst.ini and using the settings there (so the
libdb2.so).
I'm going to discuss the SQL_ATTR_UNIXODBC_ENVATTR later.
To check if the configuration is working properly use the unixODBC
client: isql.
brepredbls01:/etc/unixODBC # isql ITFINDB2 SISBANC SISBANC
+---------------------------------------+
|
Connected!
|
|
|
|
sql-statement
|
| help
[tablename]
|
|
quit
|
|
|
+---------------------------------------+
SQL> select count(*) FROM TRAS.POL_ELEN_ELET
+------------+
| |
+------------+
| 493318 |
+------------+
SQLRowCount returns -1
1 rows fetched
Oracle Generic Connectivity
configuration
This is the last step. You are going to configure oracle HS in order to
be able to access a DB2 via DB link.
Three are the files used for the configuration: listener.ora,
tnsnames.ora and initDBNAME.ora.
Let's start from the latter.
In $ORACLE_HOME/hs/admin you need a init file for the HS service you
are creating.
The information inside this file are related to the ODBC DSN you
configured in setp 2.
Here is the content of a file of mine:
oracle@brepredbls01:/u01/app/oracle/product/10.1/db_1/hs/admin> cat
initITFINDB2.ora
# This is a sample agent init file that contains the HS parameters that
are
# needed for an ODBC Agent.
set ODBCINI=/etc/unixODBC/odbc.ini
HS_FDS_SHAREABLE_NAME=/usr/lib/libodbc.so
HS_FDS_CONNECT_INFO = ITFINDB2
HS_FDS_TRACE_LEVEL = 0
HS_FDS_TRACE_FILE_NAME = ITFINDB2.trc
HS_DB_NAME = ITFINDB2
HS_LANGUAGE= ITALIAN_ITALY.WE8MSWIN1252
Two entries are imports:
set ODBCINI=/etc/unixODBC/odbc.ini tells which odbc.ini
files needs to be used in this way you can go for a non-global one (for
example one editable from your oracle user).
HS_FDS_SHAREABLE_NAME=/usr/lib/libodbc.so indicates which
ODBC (library) to use.
The one I pointed is the unixODBC basic library.
Later you needs to configure your listener.ora. Here is mine:
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL =
TCP)(HOST = brepredbls01.ras)(PORT = 1521))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL =
IPC)(KEY = EXTPROC))
)
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME =
/u01/app/oracle/product/10.1/db_1)
(PROGRAM = extproc)
)
(SID_DESC=
(SID_NAME=DB2PROD)
(ORACLE_HOME=
/u01/app/oracle/product/10.1/db_1)
(PROGRAM=hsodbc)
(ENVS=DB2INSTANCE=db2inst1)
)
(SID_DESC=
(SID_NAME=DB2DSPT)
(ORACLE_HOME=
/u01/app/oracle/product/10.1/db_1)
(PROGRAM=hsodbc)
(ENVS=DB2INSTANCE=db2inst1)
)
(SID_DESC=
(SID_NAME=ITFINDB2)
(ORACLE_HOME=
/u01/app/oracle/product/10.1/db_1)
(PROGRAM=hsodbc)
(ENVS=DB2INSTANCE=db2inst1)
)
(SID_DESC=
(SID_NAME=UNS)
(ORACLE_HOME=
/u01/app/oracle/product/10.1/db_1)
)
)
The entry:
(SID_DESC=
(SID_NAME=ITFINDB2)
(ORACLE_HOME=
/u01/app/oracle/product/10.1/db_1)
(PROGRAM=hsodbc)
(ENVS=DB2INSTANCE=db2inst1)
Indicates which service to look for. In this case an HOODBC calles ITFINDB2
(so looking for $ORACLE_HOME/hs/admin/initITFINDB2.ora).
The (ENVS=DB2INSTANCE=db2inst1) is discussed later.
The listener is listening for the HS services:
lsnrctl status
LSNRCTL for Linux: Version 10.1.0.4.0 - Production on 13-OCT-2005
10:25:46
Copyright (c) 1991, 2004, Oracle. All rights reserved.
Connecting to
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=brepredbls01.ras)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias
LISTENER
Version
TNSLSNR for Linux: Version 10.1.0.4.0 - Production
Start
Date
12-OCT-2005 16:27:11
Uptime
0 days 17 hr. 58 min. 34 sec
Trace
Level
off
Security
ON: Local OS Authentication
SNMP
OFF
Listener Parameter File
/u01/app/oracle/product/10.1/db_1/network/admin/listener.ora
Listener Log File
/u01/app/oracle/product/10.1/db_1/network/log/listener.log
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=brepredbls01.ras)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=brepredbls01.ras)(PORT=8080))(Presentation=HTTP)(Session=RAW))
Services Summary...
Service "DB2DSPT" has 1 instance(s).
Instance "DB2DSPT", status UNKNOWN, has 1 handler(s) for this
service...
Service "DB2PROD" has 1 instance(s).
Instance "DB2PROD", status UNKNOWN, has 1 handler(s) for this
service...
Service "ITFINDB2" has 1 instance(s).
Instance "ITFINDB2", status UNKNOWN, has 1 handler(s) for this
service...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this
service...
Service "UNS" has 2 instance(s).
Instance "UNS", status UNKNOWN, has 1 handler(s) for this
service...
Instance "UNS", status READY, has 1 handler(s) for this
service...
Service "UNSXDB" has 1 instance(s).
Instance "UNS", status READY, has 1 handler(s) for this
service...
The command completed successfully
Last file:
DB2PROD =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=tcp)
(HOST= brepredbls01.ras)
(PORT=1521))
(CONNECT_DATA=(SID=DB2PROD))
(HS=OK)
)
DB2DSPT =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=tcp)
(HOST= brepredbls01.ras)
(PORT=1521))
(CONNECT_DATA=(SID=DB2DSPT))
(HS=OK)
)
ITFINDB2 =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=tcp)
(HOST= brepredbls01.ras)
(PORT=1521))
(CONNECT_DATA=(SID=ITFINDB2))
(HS=OK)
)
To make the oracle client able to point toward your listener.
Create a DBlink inside your database:
CREATE PUBLIC DATABASE LINK "ITFINDB2" CONNECT TO SISBANC IDENTIFIED by
PASSWORD USING 'ITFINDB2';
and you are done... almost...
My main problem has been with this error:
[unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV
failed
Googling I found that the possible reason was that the env variable
DB2INSTANCE was not set.
And it was so.
But how to do it?
1.
I found four different ways (and I applied two).
Insert into odbc.ini the line:
DMEnvAttr =
SQL_ATTR_UNIXODBC_ENVATTR={DB2INSTANCE=db2inst1}
This didn't worked for me and prevented even the connections with isql.
2.
Set it directly in your oracle environemt.
Since I'm using suse and the package orarun I simply added the line:
export DB2INSTANCE=db2inst1
in my /etc/profile.d/oracle.sh
3.
Place the line:
set DB2INSTANCE=db2inst1
in your $ORACLE_HOME/hs/admin/initITFINDB2.ora
4.
in your listener.ora insert:
(ENVS=DB2INSTANCE=db2inst1)
for the SID_DESC of your DB2 service.
Personally I used the solutions 2 and 4.
After this last configuration my DBlinks where fully operational and my
datawarehouse where able to retrieve data directly from DB2.
(What a hard day...)
Ok, I met another error on one of my dblink.
I started debugging from the db2 client (the lower layer) and found
this error:
db2 => select * from portaf.alcommin
SQL0332N There is no available conversion for the source code
page "1140" to
the target code page "1208". Reason Code "1". SQLSTATE=57017
This was due to codepage incompatibility.
I solved it by changing my LANG (locale) env variable in the oracle
user shell.
I did it by editing the file:
/etc/SuSEconfig/profile
switching from UTF8 to iso8859-15.
Contact information:
fabrizio.magni _at_ gmail.com