Troubleshooting UnixODBC Connector Problems

This section describes the steps that we take to troubleshoot problems with UnixODBC connectors, regardless of which connector is being used. UnixODBC is not big on reporting the actual cause of an error so we are all reduced to acting like Hercule Poirot to figure out what's going on.

If, for example, you receive this error:

     Can't open lib '/usr/local/lib/xxx.so': file not found

It doesn't really mean that the file can't be found. This is UnixODBC's way of telling you that there is something wrong with the database connector. Or, you included a spurious carriage return on the end of the name. Or, the resources that database connector needs are missing.

There's not much we can do about the database connector being broken. It comes from the database vendor. Check that you have the correct shim. Make sure that you aren't trying to use the 64-bit shim on a 32-bit OS or with the 32-bit version of UnixODBC, and vice versa. If you built the database from source, check that the build was done correctly and that the properly-built shim was installed where you think it was. Verify that a vestigial shim (from a prior build or install) isn't lurking about, playing havoc.

Make sure that the name that you used for the database connector doesn't have any secret, hidden characters in it. Many people have noted that, when cutting and pasting connector names from sources on the Internet, it is possible that a spurious carriage return or some other invisible, evil character can get included in the name, where you can't see it but where UnixODBC can use it to go screaming off into the weeds.

For resource problems, the ldd command is your friend. Use it to display the resources that the database connector needs and resolve any missing ones. For example, when you display the MySQL connector like this:

     ldd /usr/local/lib/libmyodbc5w.so

You should see something like this:

     linux-gate.so.1 =>  (0x00bb1000)
     libodbc.so.2 => not found
     libodbcinst.so.2 => not found
     libmysqlclient.so.18 => not found
     libpthread.so.0 => /lib/libpthread.so.0 (0x00547000)
     libm.so.6 => /lib/libm.so.6 (0x001d6000)
     libdl.so.2 => /lib/libdl.so.2 (0x003d2000)
     libc.so.6 => /lib/libc.so.6 (0x00d57000)
     /lib/ld-linux.so.2 (0x00711000)

Well, actually, you shouldn't see something like this. The part where "libobbc.so.2" and "libodbcinst.so.2" and "libmysqlclient.so.18" aren't found? That's not good.

If its resources aren't found, the database connector isn't going to work. The fix for this problem is to either add symlinks for the missing resources, in an obvious location such as /usr/lib, or to modify ld.so.conf or ld.so.conf.d to point the loader at the locations where these resources can be found. Typically, the libodbc resources can be found in /usr/local/unixODBC/lib or, if an RPM was used to install UnixODBC, /usr/lib.

Additionally, you may need to add symlinks from generic module names, such as libodbc.so.2, which should point to the actual module such as libodbc.so.2.0.0, in the appropriate place. Usually, the install for UnixODBC and your database connector takes care of these symlinks but you never know.

If you get an error message that looks something like this (from isql, your program or a Web application such as a PHP program):

     [IM002][unixODBC][Driver Manager]Data source name not found, and no
       default driver specified

It may or may not mean what it says. It is possible that the DSN is missing or that the driver is not correct. You should first check that there is a valid DSN entry for the database that you are trying to open in the odbc.ini file (well, first you should check that the odbc.ini file is where UnixODBC expects it, i.e. where you told it to look when you built UnixODBC -- in a pinch you should put it in /usr/local/unixODBC/etc and then you can symlink to it from other places like /etc/odbc.ini).

The database that you are trying to open should have a separate section with its name in square brackets. In that section, it should mention the driver (e.g. "MySQL").

The next thing to check is that there is an odbcinst.ini file in the same place as odbc.ini. Once again /usr/local/unixODBC/etc or maybe /usr/unixODBC/etc are good spots and symlinks are a good way to cover all of the bases.

The odbcinst.ini file should have a separate section with the driver name that was used in odbc.ini, in brackets. The driver should be pointed to in this section (e.g. /usr/local/lib/libmyodbc5w.so).

Finally, the database (and all of its associated files) should be accessible by the user executing the program that is failing. If you did something like setting the ownership of the database files to mysql:mysql or informix:informix, you need to set the group permissions of these files to "rw" and add the primary group that the user belongs to /etc/group under the mysql or informix group. Note that, if you are running a PHP program under a Web server such as httpd, the user accessing the database is probably apache. So, in /etc/group one might expect to find:

     mysql:x:27:apache,jschmoe

Also, a word to the wise. If you can't get:

     /usr/local/unixODBC/bin/isql -v DSN

To work against the database, you might as well figure that out before you go any further, since it eliminates of lot of middlemen during debugging.