We want to make sure that when your application requests a connection to your server, it actually works. In detail, we want to know:
FreeTDS™ can find and read freetds.conf
servername
exists in freetds.conf
a host
property exists for servername
host
can be resolved to a network address
the server is listening to the port
or named instance
the user can log in to the server
Each of the above can be confirmed independently with tsql. Once you're sure you can connect and log in, you can run the unit tests to see if the software works as promised.
The tsql utility is provided as part of FreeTDS™ expressly for troubleshooting. tsql is superficially similar to an isql, but uses libtds
directly, bypassing the client libraries (e.g., DB-Library
). It can also report where it looks for freetds.conf
and other compile-time settings (with tsql -C).
Example 3.2. Show compile-time settings with tsql
$
tsql -C
Password:
Compile-time settings (established with the "configure" script) Version: freetds v1.4 freetds.conf directory: /usr/local/etc MS db-lib source compatibility: no Sybase binary compatibility: no Thread safety: yes iconv library: yes TDS version: auto iODBC: no unixodbc: no SSPI "trusted" logins: no Keberos: no OpenSSL: yes GnuTLS: no MARS: yes
For details on the use of tsql, consult its man page.
If all goes well, the first time you fire up tsql it connects and you can issue your first query. More often, though, the result is less joyous. Listed below for your troubleshooting pleasure are a variety of servername
lookup failures and their corresponding messages.
When servername
cannot be converted to an address, up to two messages may result. Successful conversion (by any means) never produces an error message.
Example 3.3. Failure to find servername
in freetds.conf
$
tsql -S
nobox
-Usa
Password:
locale is "C" locale charset is "646" Password: Error 20012 (severity 2): Server name not found in configuration files. Error 20013 (severity 2): Unknown host machine name. There was a problem connecting to the server
$
host nobox
Host not found.
In the above case message 20012 indicates nobox
was not found in freetds.conf
. The library then treated nobox
as a network hostname but found it also not to be valid per DNS, leading to message 20013.
If servername
is found in the configuration files, but refers to an invalid hostname, only message 20013 is returned.
Example 3.4. Failure to resolve hostname for servername
$
tsql -S
nonesuch
-Usa
Password:
locale is "C" locale charset is "646" Error 20013 (severity 2): Unknown host machine name. There was a problem connecting to the server
Unfortunately, the “host machine name” (the right side of the host
line in freetds.conf
) isn't mentioned in the error message. Fortunately, this kind of setup problem is rarely encountered by users.
If name lookup succeeds, FreeTDS™ next attempts to connect to the server. To connect means to form at TCP connection by calling connect(2)
. A valid connection must exist before any information can be exchanged with the server. Specifically, we need a connection before we can log in.
A few things can go wrong at this point. The address returned by DNS may not be that of the machine hosting the server, or indeed of any machine! The machine may be down. The server may not be running. The server may be running but not listening to the port FreeTDS™ is attempting to connect to. In rare cases, both ends are correctly configured, but a firewall stands in the way.
If no server accepts the connection, no connection can be established. It's difficult to know why, and the message is consequently vague.
Example 3.5. Failing to connect with tsql
$
tsql -S
emforester
-Usa
#only connect?Password:
Msg 20009, Level 9, State -1, Server OpenClient, Line -1 Unable to connect: Adaptive Server is unavailable or does not exist There was a problem connecting to the server
If you get message 20009, remember you haven't connected to the machine. It's a configuration or network issue, not a protocol failure. Verify the server is up, has the name and IP address FreeTDS™ is using, and is listening to the configured port.
Named instances provide another way for connections to fail. You can verify the instance name and the port the server is using with tsql -L.
Example 3.6. Getting instance information with tsql
$
tsql -LH
servername
locale is "C" locale charset is "646" ServerName TITAN InstanceName MSSQLSERVER IsClustered No Version 8.00.194 tcp 1433 np \\TITAN\pipe\sql\query
servername
could be configured to use instance MSSQLSERVER
or port 1433
.
After a valid connection is formed, FreeTDS™ sends a login packet. The TDS protocol provides no way to interrogate the server for its TDS version. If you specify the wrong one, you'll get an error.
Example 3.7. Using the wrong protocol for the server
$
tsql -S
servername
Password:
Msg 20017, Level 9, State -1, Server OpenClient, Line -1 Unexpected EOF from the server Msg 20002, Level 9, State -1, Server OpenClient, Line -1 Adaptive Server connection failed There was a problem connecting to the server
“Unexpected EOF from the server” seems to be a fairly common message when the wrong TDS version is used. Note that there's no complaint about the login.
If the right TDS version is used, the server will accept the login packet and examine its contents to authenticate the user. If there's a problem, the server will say so. This is the first time we're receiving a message from the server. [8]
Example 3.8. Login failure
$
tsql -S
servername
-U notmePassword:
Msg 18456, Level 14, State 1, Server [
servername
], Line 0 Login failed for user 'notme'. Msg 20002, Level 9, State -1, Server OpenClient, Line -1 Adaptive Server connection failed There was a problem connecting to the server
freetds.conf
:
tsql
{-H hostname
}
{-p port
}
{-U username
}
[-Ppassword
]
[-C]
Keep in mind that the TDS protocol version normally comes from freetds.conf
. When using tsql this way, the library uses the compiled-in default (set by the configure
script). If that's not what you want, override it using the TDSVER
environment variable.
Example 3.9. Connect with tsql using a hostname and port number
$
TDSVER=auto tsql -H
hillary
-p4100
-Usa
Password:
1>
For details on tsql, see the its man page.
The source code directory of each FreeTDS™ library includes a unittests
directory.
Although the directories are named unittests
they are not unit tests, most of them require a configured database to work.
$
ls -d -1 src/*/unittests
src/ctlib/unittests src/dblib/unittests src/odbc/unittests src/replacements/unittests src/tds/unittests src/utils/unittests
The tests rely on the PWD
file in root of the FreeTDS™ source tree.
PWD
holds a username, password, servername, and database to be used for the unit tests.
We try to make sure to leave nothing behind: any data and objects created are either temporary or removed at the end of the test.
The tests should all work, subject to disclaimers in the directory's README.md
.
To invoke the tests, edit the PWD
file (you can copy from PWD.in
which is a template) and issue the command make check.
In order to execute all tests successfully, you must indicate a working, available servername in PWD
.
Some tests require permission to create stored procedures on server.
In addition, some may require that a database named freetds_test
exists on the server, and the user whose credentials are used during the testing process has sufficient permissions to create and manipulate tables in this database.
To complete successfully, the ODBC tests require some additional setup.
In your PWD
file, add a SRV
entry specifying the DSN entry for your odbc.ini
.
The ODBC tests all build their own odbc.ini
and try to redirect the Driver Manager to it, however this functionality is very DM dependent and may well fail unless you have either iODBC
or unixODBC
.
Tip | |
---|---|
The |
[8] If you'd like to help the project and want to so something fairly easy but still useful, modify tsql to distinguish clearly between errors returned by the library, and those returned by the server. Errors should be marked “error” and don't return state or a line number, but can contain an error code (and message) from the operating system.