找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3539

积分

0

好友

463

主题
发表于 2 小时前 | 查看: 3| 回复: 0

如何调查数据库“缓慢”或者“挂起”的问题

这篇文章概述了在遇到DB性能缓慢问题时应采取的基本步骤。
数据库性能问题的诱因多种多样,但典型的主要症状是响应迟缓,或者在极端情况下数据库“挂起”。

情况1:数据库缓慢

1)该性能问题是持续发生还是在特定时间段发生?

如果是持续发生

1)收集 ADDM 报告,确认给出的“发现”,并查看相应的“建议”。
2)收集问题发生时间段的 AWR 与 ASH 报告(通常一个小时的就可以了)。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
3)收集一份数据库性能正常时间段的 AWR 报告。
为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段、且持续时间相同的 AWR 报告就够了,但对于大多数性能问题来说,或许需要一份 10-30 分钟的 AWR 报告。

注 1:- 通常收集一个小时的AWR报告就可以了,但对于大多数性能问题来说,或许需要一份10-30分钟的AWR报告
注 2:- 通常使用 ADDM 报告定位主要问题是明智的。由于 ADDM 报告会列出主要的问题点,诊断问题的最初阶段使用 ADDM 报告要比理解 AWR 报告节省很多时间。参考: ADDM
注 3:- 如果怀疑 SQL 性能是造成数据库缓慢的原因,那么收集同一时间段的 ASH 报告。如果怀疑某个特定的 SQL 的导致数据库缓慢,那么以该 SQLID 收集一份ASH报告,同时考虑是否使用sqlhc 来诊断该 SQL 语句,用SQLT也行,只不过SQLT东西太多了,我觉得SQLHC足够了。
如果是特定时间段

收集一份包含问题发生时间段的 ADDM 报告(例如:如果问题发生在 12 点至 3 点之间,那么收集的报告确保涵盖这个时间段或者其中一部分)。确认给出的“发现”,执行相应的“建议”,然后再次检查数据库性能。
收集与上述收集的 ADDM 报告相同时间段(即问题发生时间段)的 AWR 与 ASH 报告。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。

2)当数据库缓慢时,一个或者多个会话的 CPU 使用率很高

收集CPU使用率比预期高的进程的 errorstacks。(如果无法收集 errorstacks,那么收集 pstack 或类似的报告)

SELECT p.pid, p.SPID,s.SID
FROM v$process p, v$session s
WHERE s.paddr = p.addr
AND s.SID = &SID;
connect / as sysdba
ALTER SESSION SET tracefile_identifier = 'STACK_10046';
oradebug setospid 9834
oradebug unlimit

oradebug event 10046 trace name context forever,level 12

oradebug dump errorstack 3
oradebug dump errorstack 3
oradebug dump errorstack 3
oradebug tracefile_name
参考文档:How to Collect Errorstacks for use in Diagnosing Performance Issues. (Doc ID 1364257.1)    

收集CPU使用率高的时间段的 AWR 与 ASH 报告。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。

注 1: 通常收集一个小时的AWR报告就可以了,但对于大多数性能问题来说,或许需要一份10-30分钟的AWR报告
注 2: 通常使用 ADDM 报告定位主要问题是明智的。由于 ADDM 报告会列出主要的问题点,诊断问题的最初阶段使用 ADDM 报告要比理解 AWR 报告节省很多时间。参考: ADDM
注 3: 如果怀疑 SQL 性能是造成数据库缓慢的原因,那么收集同一时间段的 ASH 报告。如果怀疑某个特定的 SQL 的导致数据库缓慢,那么以该 SQLID 收集一份ASH报告,同时考虑是否使用sqlhc 来诊断该 SQL 语句,用SQLT也行,只不过SQLT东西太多了,我觉得SQLHC足够了。

诊断信息收集完成之后,官方文档如下:

Document 352648.1 How to Diagnose high CPU usage problems

3)一个,多个还是所有会话发生了问题?

一个会话: 收集这个会话的 10046 跟踪日志。
其他收集10046的方式,自己搜一下,网上很多。

通过oradebug方式 (建议)
conn / as sysdba
oradebug setmypid
oradebug event 10046 trace name context forever,level 12
oradebug tracefile_name

多个会话: 收集其中的一个或者两个有问题会话的 10046 跟踪日志。

如果是所有会话

收集 ADDM 报告,确认给出的“发现”,执行相应的“建议”,然后再次检查数据库性能。
收集问题发生时间段的 AWR 与 ASH 报告(通常一个小时的就可以了)。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。需要注意的是,对于大多数性能问题来说,或许需要一份 10-30 分钟的 AWR 报告。

注 1: 通常收集一个小时的AWR报告就可以了,但对于大多数性能问题来说,或许需要一份10-30分钟的AWR报告
注 2: 通常使用 ADDM 报告定位主要问题是明智的。由于 ADDM 报告会列出主要的问题点,诊断问题的最初阶段使用 ADDM 报告要比理解 AWR 报告节省很多时间。
注 3: 如果怀疑 SQL 性能是造成数据库缓慢的原因,那么收集同一时间段的 ASH 报告。如果怀疑某个特定的 SQL 的导致数据库缓慢,那么以该 SQLID 收集一份ASH报告,同时考虑是否使用sqlhc 来诊断该 SQL 语句,用SQLT也行,只不过SQLT东西太多了,我觉得SQLHC足够了。

情况2:数据库挂起

一个特定的会话出现挂起,还是几个会话或者所有会话挂起?根据具体的场景收集诊断信息:

1)一个会话出现挂起

收集这个会话的 10046 跟踪日志。
收集这个会话的 errorstacks。

sqlplus / as sysdba
@?/rdbms/admin/addmrpt.sql

收集这个会话出现挂起时间段的 AWR 与 ASH 报告。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。

2)一个 SQL 语句出现挂起

收集这个会话的 10046 跟踪日志。
收集CPU使用率比预期高的进程的 errorstacks。(如果无法收集 errorstacks,那么收集 pstack 或类似的报告)
收集CPU使用率高的时间段的 AWR 与 ASH 报告。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。

参考文档:

Document 1916479.1 How to Investigate Hanging SQL Statements

3)一个以上的会话出现挂起

收集这些会话的 10046 跟踪日志。
收集CPU使用率比预期高的进程的 errorstacks。(如果无法收集 errorstacks,那么收集 pstack 或类似的报告)。
收集CPU使用率高的时间段的 AWR 与 ASH 报告。通过 ASH 可以定位使用高 CPU 的会话和 SQL 语句。
收集一份数据库性能正常时间段的 AWR 报告。为了确保比较更有价值,收集一天中同一时间或同一工作负载时间段,并确保报告的持续时间是相同的。

4)数据库“出现”挂起?

如果数据库出现挂起现象,请参考下面 Hang 文档收集诊断信息。

Document 2293066.1 SRDC – 对于数据库 Hang 的问题如何收集诊断信息
Document 452358.1 Database Hangs: What to collect for support.

有时,数据库实际上没有挂起,但可能发生了与之非常类似的现象,即在CPU上发生了“spinning”。可以使用下面的 Spin 文章来帮助判断遇到的现象是否为真正的挂起,并解决这个问题:

Document 68738.1 No Response from the Server, Does it Hang or Spin?

如果数据库实际上只是缓慢,请参考 数据库缓慢 章节。
每个版本做 hanganalyze 的步骤差不多,供参考:

sqlplus '/ as sysdba'
oradebug setmypid
oradebug unlimit
oradebug hanganalyze 3
-- 等一会,10秒左右
oradebug hanganalyze 3
oradebug tracefile_name
exit

5)大多数会话出现挂起

与数据库挂起处理方式相同。




上一篇:AI大模型缓存揭秘:KV Cache与Prompt Caching到底缓存什么?
下一篇:Redis 7.0 分片发布订阅:告别集群消息风暴,真正实现水平扩展
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-5-23 05:43 , Processed in 0.800786 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表