Mac OS X: how to enable ODBC log? - macos

I have installed some ODBC drivers in Mac OS X. One of them works incorrectly, i.e. my app cannot connect to PostgreSQL database via the ODBC driver.
I'd like to enable logging for it and check what is the reason.
How I can do it?

If you were using the iODBC driver manager that ships with macOS, tracing would be controlled through the iODBC Administrator.app, found in /Applications/iODBC/, and the standard configuration file (odbc.ini) found in the standard locations (/Library/ODBC/ for system-level config; /Users/*/Library/ODBC/ for user-level).
You can also manually edit (or create) a stanza like the one below in that file.
[ODBC]
Trace = 1
TraceFile = iodbc.$U.$p.$T.log
TraceAutoStop = 0
;TraceDLL =
Note the $u, $p, $t, and/or $h tokens may be used to automatically insert UserID, ProcessID, Timestamp, and/or $HOME in the log filename.
With UnixODBC as an after-market, third-party add-on, the configuration files may be located anywhere. UnixODBC tracing is enabled/disabled via this stanza of the odbcinst.ini (not odbc.ini) file.
[ODBC]
Trace = yes
TraceFile = trace_file_path

Related

How to install tnsping?

How do I have to install tnsping?
I tried to install oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm and I'm able to use some client commands but nog tnsping.
Oracle Instance Client does not include tsnping application. You must run "Oracle Universal Installer" and enable the option for it.
I don't' remember exactly which option you have to set, either it was "Oracle Database Utilities" or "Oracle Net"
Also see McTnsping [link broken] "a Windows stand-alone program which requires no Oracle client". It's portable and doesn't need to be installed.
Usage 1: McTnsping.exe { <tns entry> | <host>:<port> } [<count>]
<tns entry> the net service name in the tnsnames.ora file.
<host>:<port> server name or IP and port (mandatory)
<count> number of times to check target, default is 1.
If whoever will reach the place like me... This is what worked for me:
Instant client Version 12.2.0.1 + sqlplus + tnsping (copied from another server of the same version)
Directory structure and env (as in bash profile):
export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=${ORACLE_BASE}/instant_client122
export PATH=$ORACLE_HOME:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME #since all binaries are in $ORACLE_HOME - no bin or lib are present
export TNS_ADMIN=$ORACLE_HOME/network/admin
copy from another server to target:
'tnsping' to $ORACLE_HOME
'$ORACLE_HOME/network/mesg/tnsus.msb' to $ORACLE_HOME/network/mesg
Then put proper values to $TNS_ADMIN/tnsnames.ora and load env variables. After this it should be able to perform 'tnsping' and show proper message as a response.
Here's what I did to copy tnsping over to another machine. In my case, the oracle client is installed at C:\Oracle\product\12.1.0\client_1.
This assumes there's already an Instant Client or similar installed on the destination machine; and that the oracle path and registry keys are set.
(1) Copy tnsping.exe from the source to the destination machine, into client_1\bin.
(2) Copy the following files from client_1\bin to client_1\bin:
oraasmclnt12.dll
oracell12.dll
oraclient12.dll
oraclsce12.dll
oracommon12.dll
oracore12.dll
orageneric12.dll
orahasgen12.dll
oraldapclnt12.dll
oran12.dll
orancds12.dll
orancrypt12.dll
oranhost12.dll
oranl12.dll
oranldap12.dll
oranls12.dll
oranro12.dll
orantcp12.dll
orantns12.dll
oraocr12.dll
oraocrb12.dll
oraocrutl12.dll
oraplp12.dll
orapls12.dll
ORASLAX12.DLL
orasnls12.dll
oraunls12.dll
orauts.dll
oravsn12.dll
oraxml12.dll
orazt12.dll
oraztkg12.dll
This should be about 84.6 MB.
(3) In the client_1 on the destination machine, make a backup of the following files:
oci.dll
orannzsbb12.dll
oraons.dll
orasql12.dll
orawsec12.dll
Now on the source machine, find those files in client_1\bin and copy them to client_1\ (no bin) on the destination machine, overwriting the existing files. (Note: oci.dll is ~330 kb smaller, orasql12.dll is ~300 kb smaller. I'm not sure what's lost, hence the backup).
(4) On the destination machine, create the directory mesg in client_1\Network. Now copy the following file from the source to the destination:
client_1\Network\mesg\tnsus.msb
(5) Open up regedit. Create the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\KEY_OraClient12Home1_32bit
(From another machine, it looks like the x64 version is named HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\KEY_OraClient12Home1, but the tnsping program I'm using says it's 64 bit, so ...)
Under the key, create a string named ORACLE_HOME with the value C:\Oracle\product\12.1.0\client_1.
You should be done now ($$$ = redacted):
C:\Users\$$$>tnsping $$$
TNS Ping Utility for 64-bit Windows: Version 12.1.0.2.0 - Production on 03-APR-2
019 08:47:37
Copyright (c) 1997, 2014, Oracle. All rights reserved.
Used parameter files:
C:\Oracle\product\12.1.0\client_1\network\admin\sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = $$$)(PORT = $$$))) (CONNECT_DATA = (SERVICE_NAME = $$$
$$$) (SERVER = DEDICATED)))
OK (30 msec)
Troubleshooting
Here's the process I followed, sharing for when these steps invariably fail to work on a later version.
First off, I just copied the tnsping.exe over.
I didn't haphazardly pick the above dlls, as far as I can tell everyone is required. I ran the exe, and it would popup an error, I would copy the dll over and try again:
After a few dlls, you'll run into a different kind of error:
If that happens, fire up process monitor and put a filter in for the ProcessName to contain tnsping and try to run the program again. You should see something like the following. The main thing to notice is that it tries to load (in this example) orawsec12.dll, which succeeds, but then it continues to try to load the dll looking in different paths, and then at the end it triggers werfault and the program ends. I guess it realizes there's some kind of version mismatch and keeps looking for the right version.
The missing registry key will show up like the following in process monitor (operation RegOpenKey, result NAME NOT FOUND):
If the tnsus.msb file is missing, you should see something like the following in process monitor (operation CreateFile, result NAME NOT FOUND):

Connect to Oracle database using ROracle with tnsnames.ora on Mac OS 10.10

Followup to Installation of RODBC/ROracle packages on OS X Mavericks...
First of all, I have installed ROracle on Mac OS 10.10.3 (Yosemite) using the answer provided by #joran. Additionally, using the start-up plist file to set DYLD_LIBRARY_PATH, I can run library(ROracle), and it loads just fine. However, I am unable to connect to my database with a tnsnames.ora file. I have added the TNS_ADMIN variable to the .Renviron file, which RStudio seems to pick up:
> Sys.getenv("TNS_ADMIN")
[1] "opt/oracle/instantclient_11_2/network/admin"
When I run the following, for example
con <- dbConnect(drv = dbDriver("Oracle"), dbname = "db", username = "user", password = "pw")
, I get the error
Error in .oci.Connect(.oci.drv(), username = username, password = password, :
ORA-12154: TNS:could not resolve the connect identifier specified
In addition, I have also added the TNS_ADMIN environment variables to .bash_profile, but that didn't help.
NOTE 1: I have already used the tnsnames.ora file to connect to the database with SQL Developer, so I'm fairly confident the issue is something external to the content of the file.
NOTE 2: I can in fact connect using ROracle with something like:
# see example at http://www.oralytics.com/2015/05/loading-json-data-into-oracle-using.html
host <- "localhost"
port <- 1521
service <- "pdb12c"
drv <- dbDriver("Oracle")
connect.string <- paste(
"(DESCRIPTION=",
"(ADDRESS=(PROTOCOL=tcp)(HOST=", host, ")(PORT=", port, "))",
"(CONNECT_DATA=(SERVICE_NAME=", service, ")))", sep = "")
con <- dbConnect(drv, username = "dmuser", password = "dmuser", dbname = connect.string)
I double checked my tnsnames.ora file and it's in the exact same format as connect.string, so I'm thinking it's just not actually being seen by RStudio, even though Sys.getenv("TNS_ADMIN") gives me the correct path. Alternatively, it could be that the name required by the dbname argument on Mac is different than Windows.
Any help would be greatly appreciated! Thanks!
I've seen many recommendations online for adding environment variables on Yosemite to be accessed by RStudio. The only one that has fully worked for me, at least so far, is to add all environment variables to the plist file. You can add as many variables as you want, which is described by #MortimorGoro in Setting environment variables via launchd.conf no longer works in OS X Yosemite/El Capitan/macOS Sierra?.
So my solution here was to just add TNS_ADMIN to plist!
For those of you that got here but are on Windows 7, on my workstation I have to use a TNSnames.ora file (also utilizing TNS_ADMIN environment variable)(Located in: C:\app - see 2nd screenshot), I got the following to work:
library(RODBC)
channel <- odbcConnect("PERMIT_DEV_odbc",
uid = "POWDERED_TOAST_MAN",
pwd = "dev_NONE_OF_YOUR_BEEZNEEZ",
believeNRows = FALSE)
testsql <- "select sysdate from dual;"
query <- sqlQuery(channel = channel,
query = testsql)
1 Click on the Start button (in windows 7)
2 Start typing, "odbc" and look for "set up data sources (ODBC)" or something like that.
3 Add your connection based off your TNS file.
4 there's also a "test connection" button you should use to verify connectivity!
Hope this helps!

JDBC type-2 behavior with multiple DB2 Client versions installed

Our J2EE based application is run on Websphere Applicaiton Server- AIX server with 2 versions of DB2 Client installed (Db2v9.5, Db2v9.7).
I have a db SAMPLE which is remotely cataloged in both the two DB2 client versions with the same alias name SAMPLE.
If I uncatalog the DB from DB2v9.5 , the application goes down. However if I drop it from DB2v9.7 client the application is not impacted.
From this above test , we understand that some how DB2v9.5 is being used by default.
My objective now is to make the SAMPLE be pointed to only DB2v9.7 and the App must work without the sample DB in DB2v9.5.
Any suggestions on how to do it ?
The JDBC string used is "jdbc:db2:sample" (Note: there is no port for DB2 Client)
I have already tried to point $LIBPATH & $LD_LIBRARY_PATH to DB2v9.7 native lib32 path,
and also pointed the AIX user ID's .profile to DB2v9.7/sqllib/db2profile ,But no luck.
Regards,
Chandru
You have to check the default environment where Java is running, you will detect which Client is using. You could do that by executing "env" via Runtime, and see the defaults.
For example, with a small app like this:
import java.lang.*;
import java.io.*;
public class Test {
public static void main (String[] args) throws Exception {
Process p = Runtime.getRuntime().exec("env");
String line;
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
System.out.println("library " + System.getProperty("java.library.path"));
}
}
You call it with the same parameters you call your other application (JDBC driver included), and then check the output.
java <your params, classpath to db2java.zip> Test
Check the parameters like DB2INSTANCE, PATH, CLASSPATH.
More information in http://www.ibm.com/developerworks/data/library/techarticle/dm-0512kokkat/
List the files in /usr/lib and /usr/include. Do you see any file that points to DB2?
ls -l /usr/lib
ls -l /usr/include
Probably, you executed a db2ln, and that created links to a specific DB2 Client (9.5). Each time you execute the Java application, the LIBPATH takes precedence over /usr/lib, than the specified DB2 version
LIBPATH=/usr/lib:/lib:/opt/IBM/db2/V9.7/lib32
You can run the db2rmln command to remove the links.
Take a look at this page: http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.qb.server.doc/doc/t0006747.html
This issue was resolved by completely killing all the JVM that is running from the same version and path of java and starting them back. (In our case an AIX JVM pConsole was running behind even after putting Dmgr,Node & CL down. Both pConsole and WAS uses the same java)
That was the reason that the updated shared native libraries didn't reflect in the WAS. But after killing&starting back each instance of java, including the ones apart from WAS the native libraries got reflected in the logs .
Sorry about updating the answer after so long.

Turning off iODBC tracing

I'm using iODBC on OS X 10.6.8 agains MySQL (mysql-connector-odbc-5.1.8) from a C program that I'm writing, but tracing of all ODBC library calls, which is supposed to be turned off by default, is turned on.
I have found a set of odbc.ini and odbcinst.ini files in /etc and in /Library/ODBC/, but none of them contains "Trace = yes", and adding an [ODBC] section with "Tracing = no" to any of these files doesn't seem to do anything. I also do not have any private .odbc.ini or .odbcinst.ini files in the working directory nor in my home directory nor anywhere else.
The only way I can turn tracing off is to call SQLSetConnectAttr() to set SQL_ATTR_TRACE to SQL_OPT_TRACE_OFF after allocating a connection handle, but at that point, the trace file, sql.log, has already been created in the working directory.
Any help with tracking down where tracing is turned on (it's supposed to be off by default), alternatively, how to turn it off so that the log file never gets created, would be appreciated.
I'm not sure why you would be using odbc instead of the standard connector, but have you tried setting the option for the TraceFile to /dev/null in odbc.ini. This may at least remove the file if you can't get the Trace = OFF to work by itself.
[ODBC]
Trace = OFF
TraceFile = /dev/null
Don't have my Mac at the office to test this, but seems like it should work.
The default settings files for ODBC on Mac OS X are found at --
/Library/ODBC/odbc.ini
/Library/ODBC/odbcinst.ini
/Users/*/Library/ODBC/odbc.ini
/Users/*/Library/ODBC/odbcinst.ini
The first two are for system-level settings and DSNs; the latter are for user-level.
Some buggy installers and libraries create files at --
/Users/*/.odbc.ini
/Users/*/.odbcinst.ini
/etc[/*]/.odbc.ini
/etc[/*]/.odbcinst.ini
/etc[/*]/odbc.ini
/etc[/*]/odbcinst.ini
These can lead to trouble. This command will reveal all potentially trouble-making files --
sudo find / \( -name '.odbc*.ini' -or -name 'odbc*.ini' \) -ls
Best is to --
blend the content of existing non-default files into the default locations, and drop the non-default files
create symlinks from the buggy .odbc[inst].ini locations to the default files
update the iODBC components on your Mac
enjoy trouble free ODBC use
(ObDisclaimer: I am an employee of OpenLink Software, who maintain and support the iODBC project, which is the ODBC Driver Manager chosen by Apple for Mac OS X, bundled since Jaguar (10.2.x).)

Haskell, HDBC, ODBC, MySQL and Mac OS X

I'm trying to use Haskell (version 6.10.3) and HDBC to connect to a MySQL Database. I've chosen to do it with Haskell ODBC. I've used cabal to install HDBC (2.1.1) and HDBC-ODBC (2.1.0.0). I've downloaded and installed the MySQL ODBC driver (5.1.5). I used macports to install unixODBC (2.2.14_1). All of this on top of Mac OS X (10.5.8).
I've mostly been using the instructions on this page http://en.wikibooks.org/wiki/Haskell/Database. At around this point:
"# Add the mysql driver to odbcinst.ini file (under $ODBC_HOME/etc/) and your data source in $HOME/.odbc.ini."
It looks like the macports version of unixODBC installs everything under /opt/local/. I've put an odbcinst.ini into /opt/local/etc/ and I've created a .odbc.ini in my home directory which looks something like this (note that I've experimented with UID vs. USERNAME and PWD vs PASSWORD):
[ODBC Data Sources]
myodbc = MySQL ODBC 5.1 Driver
[ODBC]
Trace = 0
TraceAutoStop = 0
TraceFile =
TraceLibrary =
[myodbc]
Driver = /usr/local/lib/libmyodbc5.so
DATABASE = [hidden]
DESCRIPTION = [hidden]
SERVER = localhost
PORT = 3306
UID = [hidden]
PWD = [hidden]
PASSWORD = [hidden]
USER = [hidden]
And I've written and compiled this Haskell Program:
import Database.HDBC.ODBC
import Database.HDBC
import System
main = do
args <- getArgs
c <- connectODBC (args!!0)
tables <- getTables c
mapM_ putStrLn $ tables
When I try a DSN of "DSN=myodbc" it errors out with:
Database: SqlError
{seState = "[\"HY000\"]",
seNativeError = -1,
seErrorMsg = "connectODBC/sqlDriverConnect:
[\"1045: [unixODBC][MySQL][ODBC 5.1 Driver]Access
denied for user 'jamie'#'localhost' (using password: YES)\"]"}
However, when I try a DSN of "DSN=myodbc;UID=[hidden];PWD=[hidden]", it lists all the tables in the database.
This may be a unixODBC problem rather than a Haskell / HDBC / HDBC-ODBC problem. Running "isql myodbc" results in a "Bus Error". Running "isql -v myodbc" doesn't give any more information. Running isql [uid] [pwd] connects just fine.
iODBC, maintained and supported by my employer, has shipped as part of Mac OS X since Jaguar (10.2.x).
You'll be better off updating iODBC with all the latest patches (Apple tends to be a bit behind on these), than shifting to UnixODBC.
It's generally best to keep all your ODBC configuration in the default file locations for Mac OS X --
/Library/ODBC/odbc.ini
/Library/ODBC/odbcinst.ini
/Users/*/Library/ODBC/odbc.ini
/Users/*/Library/ODBC/odbcinst.ini
You can create symlinks from anywhere else you may want to have these files, e.g. --
ln -s ~/Library/ODBC/odbc.ini ~/.odbc.ini
Last, you may benefit from testing with a commercial ODBC driver for MySQL, such as one of my employer's offerings (two week free trial provided as part of download).

Resources