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



我想学习如何跟踪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:tempsqlnet_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客户端。我不能访问数据库服务器

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

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

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

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

这里有一篇很好的文章可以让你开始:SQL trace 10046

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

对于sqlnet跟踪文件,您可能希望使用transast实用程序。

虽然传输很有用,但是如果您真的想知道发生了什么,您需要对文件本身有一些了解。

下面是一些很好的参考资料,可以帮助您开始理解sqlnet跟踪文件:

Oracle Net Services的跟踪错误信息

如果您可以访问My Oracle Support,下面的注释将是非常宝贵的:

SQLNET PACKET STRUCTURE: NS PACKET HEADER (Doc ID 1007807.6)检查Oracle Net, Net8, SQLNet跟踪文件(Doc ID 156485.1)

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

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

diag_adr_enabled=off

如果你想要精确的时间戳,那么这样做:

diag_adr_enabled=on

这是一个错误,我希望看到在Oracle 20c发布时修复。

这不是我希望得到的答案,但我需要完成并继续前进,所以我编写了一个快速而肮脏的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} (dd:){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 + "rn");
                        }
                        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:temptrace.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%'

最新更新