使用Oracle客户端跟踪和tkprof查看提交的SQL查询

时间:2016-08-29 21:21:34

标签: oracle oracle12c tracing

我想学习如何跟踪Oracle客户端并查看提交的SQL查询。

我首先将这些行添加到客户端的sqlnet.ora文件中:

TRACE_LEVEL_CLIENT=16
TRACE_FILE_CLIENT=sqlnet.trc
TRACE_DIRECTORY_CLIENT=c:\temp
LOG_DIRECTORY_CLIENT=c:\temp
TRACE_UNIQUE_CLIENT=TRUE
TRACE_TIMESTAMP_CLIENT=TRUE
DIAG_ADR_ENABLED=OFF

然后我使用SQL * Plus登录到同一客户端上的数据库。我提交了两个查询:

select * from all_tables where table_name = 'ADDRESS';
select * from all_users where username like 'AB%';

然后我退出了SQL * Plus。跟踪文件是在c:\temp中创建的。该文件大约有4000行。我当然可以看到我的两个SQL语句。虽然这种格式很难阅读,因为它们只是十六进制转储:

(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 00 00 31 73 65 6C 65 63  |..1selec|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 74 20 2A 20 66 72 6F 6D  |t.*.from|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 20 61 6C 6C 5F 75 73 65  |.all_use|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 72 73 20 77 68 65 72 65  |rs.where|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 20 75 73 65 72 6E 61 6D  |.usernam|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 65 20 6C 69 6B 65 20 27  |e.like.'|
(10632) [29-AUG-2016 17:08:40:240] nsbasic_bsd: 41 42 25 27 01 00 00 00  |AB%'....|

我的研究让我相信tkprof是获取我的跟踪文件的可读报告的方法。我尝试了以下方法:

tkprof c:\temp\sqlnet_10632.trc report.txt

但这给了我一个非常无意义的文件:

   0  session in tracefile
   0  user  SQL statements in trace file.
   0  internal SQL statements in trace file.
   0  SQL statements in trace file.
   0  unique SQL statements in trace file.
4361  lines in trace file.
   0  elapsed seconds in trace file.

理想情况下,我希望看到一份报告,针对这种情况,我会按照提交的顺序向我显示客户端提交的易于阅读的SQL文本(包括我手动输入的两个)。我是在正确的轨道上吗?我错过了什么?如果我没有走上正轨,我该怎么做才能跟踪客户提交的SQL?

注意:我使用的是12c客户端。我无法访问数据库服务器。

3 个答案:

答案 0 :(得分:1)

tkprof实用程序用于从10046跟踪文件生成报告。

这些跟踪文件显示了数据库操作。

这是一篇很好的文章,可帮助您入门: sql trace 10046

tkprof对于sqlnet跟踪文件根本没有用。

对于sqlnet跟踪文件,您需要使用trcasst实用程序。

虽然trcasst很有用,但是如果您真的想了解发生了什么,则需要对文件本身有一定的了解。

这里有一些很好的参考,可以帮助您开始了解sqlnet跟踪文件:

Tracing Error Information for Oracle Net Services

如果您有权访问My Oracle Support,以下说明将非常宝贵:

  

SQL NET数据包结构:NS数据包头(文档ID 1007807.6)   检查Oracle Net,Net8,SQL Net跟踪文件(文档ID 156485.1)

第二篇文章附带PDF,其中有很多解释。

11g-19c中的文档都将声明您应在sqlnet.ora中设置以下内容:

diag_adr_enabled=off

如果您想要准确的时间戳,请改为执行此操作:

diag_adr_enabled=on

这是我希望在Oracle 20c发行时看到的错误。

答案 1 :(得分:0)

这不是我希望的答案,但我需要完成并继续前进,所以我写了一个快速而肮脏的Windows控制台应用程序(C#):

    static void Main(string[] args)
    {
        using (var sr = new StreamReader(args[0]))
        {
            var line = string.Empty;
            var parsingSqlHex = false;
            var timestamp = string.Empty;
            var parsedSql = string.Empty;
            var patternStart = @"nsbasic_bsd\: packet dump";
            var patternTimeStamp = @"\[\d{2}-[A-Z]{3}-\d{4} (\d\d\:){3}\d{3}\]";
            var patternHex = @"nsbasic_bsd\: ([0-9A-F][0-9A-F] ){8}";
            var patternEnd = @"nsbasic_bsd\: exit \(0\)$";

            while (line != null)
            {
                if (Regex.IsMatch(line, patternStart))
                {
                    timestamp = Regex.Match(line, patternTimeStamp).Value;
                    parsingSqlHex = true;
                }
                else if (parsingSqlHex)
                {
                    if (Regex.IsMatch(line, patternEnd))
                    {
                        if (!string.IsNullOrEmpty(parsedSql))
                        {
                            Console.WriteLine(timestamp);
                            Console.WriteLine(parsedSql + "\r\n");
                        }
                        parsedSql = string.Empty;
                        parsingSqlHex = false;
                    }
                    else if (Regex.IsMatch(line, patternHex))
                    {
                        parsedSql += HexToString(line.Substring(line.Length - 35, 23));
                    }
                }

                line = sr.ReadLine();
            }
        }
    }


    static string HexToString(string hexValues)
    {
        var hexCodeArray = hexValues.Split(" ".ToCharArray());
        var n = 0;
        var s = string.Empty;

        for (var i = 0; i < hexCodeArray.Length; i++)
        {
            n = Convert.ToInt32(hexCodeArray[i], 16);
            if (n > 31 && n < 127) s += Convert.ToChar(Convert.ToUInt32(hexCodeArray[i], 16));
        }

        return s;
    }

我正在使用它来解析我的跟踪文件,如下所示:

OracleTraceParser.exe c:\temp\trace.txt > report.txt

然后我的report.txt文件在这里和那里有一些奇怪的字符,但仍然给了我我想要的东西:

[30-AUG-2016 13:50:51:534]
i^qx(SELECT DECODE('A','A','1','2') FROM DUAL

[30-AUG-2016 13:50:51:534]
i

[30-AUG-2016 13:51:05:003]
^a5select * from all_tables where table_name = 'ADDRESS'

[30-AUG-2016 13:51:21:081]
i^a1select * from all_users where username like 'AB%'

答案 2 :(得分:0)

仅供参考,Oracle提供了trcasst实用程序来执行此操作:

$ORACLE_HOME/bin/trcasst client_Tract_file.trc > client_Tract_file.txt