我有一个使用 Oracle 11g 进行持久化的 J2EE Spring/Hibernate webapp,在生产中,Oracle CPU 使用率偶尔会飙升至 100%,重新启动 Tomcat 会导致 Oracle CPU 下降。我无法在测试中复制此情况,即使使用从生产中导出的数据也是如此。有没有办法让 Oracle 向我显示导致峰值的 SQL 语句?或者我可以采取其他方法来帮助我找出问题所在?
附加信息:Webapp 和 Oracle 位于不同的框中(两个窗口)。通过 SSL 使用 JDBC
谢谢。
答案1
当生产达到 100% CPU 时,您(或您的 DBA)可以运行“top”命令,获取对 CPU 贡献最大的进程 ID(假设您只有其中几个),然后使用以下查询来捕获会话以及它当时正在做什么:
从 gv$session s 左外连接 gv$process p on p.ADDR = s.PADDR 和 s.inst_id=p.inst_id 左外连接 gv$sqlarea sa on sa.ADDRESS = s.SQL_ADDRESS 和 s.inst_id=sa.inst_id 其中 p.spid=
答案2
您可以启用数据库的性能跟踪并使用一些内置实用程序监视查询的执行。
我个人还没有在 Oracle 上做过这个,但他们确实有在线文档为您指明正确的方向。
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/sqltrace.htm#sthref2019
答案3
您确实应该检查 servlet 生命周期中是否正确关闭了 DB 连接,以及 servlet 上使用的对象是否被正确地进行了垃圾收集。有时 servlet 上可能会出现一些非常棘手的内存泄漏,如果您使用某种 DI 框架,则情况会更加严重。
我的一个 servlet 发生了内存泄漏,当时正在进行垃圾收集,但是当对另一个应用程序执行某些 RMI 时,代理对象并未被收集,因此,这会占用我所有的可用内存。
请参阅此篇文章,了解有关对 servlet 进行性能测试和内存检查的技巧。
http://www.ibm.com/developerworks/rational/library/2820.html