Monthly Archives: October 2017

Are you fishing or catching? – Server-side SQL*Net tracing for specific clients

SQL*Net tracing on the database server is all or nothing (sqlnet.ora):
TRACE_LEVEL_SERVER=support

On a busy system this quickly gets out of hand. More often than not I find myself in need of enabling SQL*Net trace on the server for a particular database client.
The first step is to setup a separate TNS_ADMIN location that we want the sever process for our client connections to pick up:

$ mkdir /u01/app/oracle/network/admin-trc
$ copy /u01/app/oracle/network/admin/sqlnet.ora /u01/app/oracle/network/admin-trc/.

Then enable SQL*Net tracing in the new TNS_ADMIN location:

vi /u01/app/oracle/network/admin-trc/sqlnet.ora

...
TRACE_LEVEL_SERVER=support

If you can modify the client’s connection string things are easy. All we need is a separate service on the existing listener that the client then connects to:
vi /u01/app/oracle/network/admin/listener.ora

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = pdbdev1_trc.localdomain)
      (ORACLE_HOME = /u01/app/oracle/product/ora12201)
      (SID_NAME = DEV1)
      (ENVS="TNS_ADMIN=/u01/app/oracle/network/admin-trc")
    )
  )

Line 4: Defines our new service name
Line 7: This makes server processes for connections through that service read our sqlnet.ora in the “admin-trc” directory and, therefore enable SQL*Net tracing.

Now, change the client’s connection string to use “pdbdev_trc” service and we’re done.
But, what if for some reason you cannot easily change the client’s connect string. That’s when I like to resort to port-forwarding using firewalld.

First, we spin up an additional listener on another port. Let’s assume our original listener runs on port 1521.
vi /u01/app/oracle/network/admin/listener.ora

LISTENER_TRC =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = ol7ora122dev1.localdomain)(PORT = 1522))
    )
  )

SID_LIST_LISTENER_TRC =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = pdbdev1.localdomain)
      (ORACLE_HOME = /u01/app/oracle/product/ora12201)
      (SID_NAME = DEV1)
      (ENVS="TNS_ADMIN=/u01/app/oracle/network/admin-trc")
    )
  )

Line 4: listening on new port
Line 11: the service name is the same as on the original listener (where the client connects to)
Line 14: Again, this sets the TNS_ADMIN location for the server process to pick up our sqlnet.ora with SQL*Net tracing enabled.

Secondly, add the port forwarding rule:

firewall-cmd --zone=oradb-server \
  --add-rich-rule='rule family="ipv4" source address="<client-IP>" forward-port port=1521 protocol=tcp to-port=1522'

Now, every connection request from the client we want to have a server-side SQL*Net trace from gets forwarded to our new listener and picks up our modified sqlnet.ora.
Obviously, this is assuming you have firewalld configured and running already. If not, await my next blog post on basic firewalld configuration for Oracle database servers.

Enjoy!

P.s. when you have all the traces you need you can remove the port forwading rule like this:

firewall-cmd --zone=oradb-server \
  --remove-rich-rule='rule family="ipv4" source address="<client-IP>" forward-port port=1521 protocol=tcp to-port=1522'