Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19269179
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: Oracle

2008-03-21 11:00:18

Oracle Database 10 g : 为 DBA 提供的最佳前 20 位的特性(十一)

作者 Arup Nanda 来源: OTN

lign=left>第 11 周
等待界面

10 g 等待界面为还没有被 ADDM 捕获的即时性能问题提供了有价值的诊断数据

“ 数据库太慢了! ”

这句话通常出自一位严格的用户之口。如果您和我一样,那么在您的 DBA 生涯中您肯定无数次听到过这句话。

那么,您又怎样解决该问题呢?除了对用户置之不理之外(这是我们大多数人都不敢奢望的想法),您可能要做的第一件事就是查看是否有任何会话在等待数据库内部或外部的任何事件。

Oracle 提供了一个简单但一流的机制来达到此目的: V$SESSION_WAIT 视图。该视图显示了有助于您的诊断的各种信息,如一个会话正在等待或已经等待的事件,以及等待了多长时间和多少次。例如,如果会话在等待事件 "db file sequential read" ,列 P1 和 P2 将显示会话正在等待的块的 file_id 和 block_id 。

对于大多数等待事件而言,这个视图足够了,但它还不是一个强健的调整工具,之所以如此说,至少是因为以下两个重要原因:

  • 该视图是当前情况的一个快照。当等待不再存在时,会话先前出现的那些等待的历史也将消失,从而使得事后诊断非常困难。 V$SESSION_EVENT 提供了累积的但不是非常详细的数据。
  • V$SESSION_WAIT 包含了只与等待事件相关的信息;要获得所有其它的相关信息(如用户 ID 和终端),您必须将它和 V$SESSION 视图结合使用。

在 Oracle 数据库 10 g 中,等待界面经过了彻底的重 新设计,从而只需更少的 DBA 干预即可提供更多的信息。在本文中,我们将浏览这些新的特性,并了解它们如何帮助我们诊断性能问题。对于大多数性能问题,您可以从自动数据库诊断管理器 (ADDM) 中获得扩展分析,但对于还没有被 ADDM 捕获的即时问题,等待界面将提供有价值的诊断数据。

增强的会话等待

第一个增强涉及到 V$SESSION_WAIT 本身。这一点通过示例可以很好地说明。

假定您的用户抱怨会话挂起了。您查明了该会话的 SID ,并在 V$SESSION_WAIT 视图中选中了该 SID 的记录。输出显示如下。

SID          : 269

SEQ#         : 56

EVENT         :enq:TX - row lock contention

P1TEXT        :name|mode

P1          : 1415053318

P1RAW         : 54580006

P2TEXT        :usn<<16 | slot

P2          : 327681

P2RAW         : 00050001

P3TEXT        :sequence

P3          : 43

P3RAW         :0000002B

WAIT_CLASS_ID   : 4217450380

WAIT_CLASS#    : 1

WAIT_CLASS     : Application

WAIT_TIME      : -2

SECONDS_IN_WAIT  : 0

STATE        :WAITED UNKNOWN TIME

注意以黑体显示的列;在这些列中, WAIT_CLASS_ID 、 WAIT_CLASS# 和 WAIT_CLASS 是 10 g 中新增的列。列 WAIT_CLASS 指示等待的类型,必须将其作为有效的等待事件解决或者作为空闲的等待事件退出。在上面的例子中,等待类显示为 Application ,这表示它是一个需要您注意的等待。

该列突出显示那些能够证明与您的调整最相关的少数几条记录。例如,您可以使用如下查询来获取事件的等待会话。

select wait_class, event, sid, state, wait_time, seconds_in_wait

from v$session_wait

order by wait_class, event, sid

/

下面是一个样例输出:

WAIT_CLASS EVENT            SID      STATE    WAIT_TIME  SECONDS_IN_WAIT

---------- -------------------- ---------- ------------------- ---------- ---------------

Application enq:TX -          269   WAITING          0        73

row lock contention

Idle     Queue Monitor Wait     270   WAITING           0        40

Idle    SQL*Net message from client 265   WAITING          0        73

Idle    jobq slave wait       259   WAITING          0       8485

Idle    pmon timer          280   WAITING          0        73

Idle    rdbms ipc message      267   WAITING          0      184770

Idle    wakeup time manager     268   WAITING          0        40

Network  SQL*Net message to client   272   WAITED SHORT TIME     -1         0

在这,您可以看到几个事件(如 Queue Monitor Wait 和 JobQueue Slave )被明确地归为 Idle 事件。您可以将它们作为非阻塞等待消除掉;不过,有时这些 “ 空闲 ” 事件可能指示一个内在的问题。例如,与 SQL*Net 相关的事件可能指示高网络延迟(除其他因素外)。

另一件要注意的重要的事情是, WAIT_TIME 的值为 -2 。某些平台(如 Windows )不支持快速计时机制。如果在这些平台上没有设定初始化参数 TIMED_STATISTICS ,那么将无法获得准确的计时统计数据。在这种情况下,在 Oracle9 i 中,该列将显示一个非常大的数字,这使问题变得更加不清晰。在 10 g 中,值 -2 指示这种情况 — 平台不支持快速定时机制并且没有设定 TIMED_STATISTICS 。(对于本文剩下的部分,我们将假定存在一个快速计时机制。)

会话也显示等待

记得长期以来一直需要将 V$SESSION_WAIT 与 V$SESSION 结合使用以获得有关会话的其他详细信息吗?嗯,这已经成为历史了。在 10 g 中, V$SESSION 视图还显示由 V$SESSION_WAIT 显示的等待。下面是 V$SESSION 视图其余的列,这些列显示了会话当前等待的等待事件。

EVENT#          NUMBER

EVENT          VARCHAR2(64)

P1TEXT          VARCHAR2(64)

P1            NUMBER

P1RAW          RAW(4)

P2TEXT          VARCHAR2(64)

P2            NUMBER

P2RAW          RAW(4)

P3TEXT          VARCHAR2(64)

P3            NUMBER

P3RAW           RAW(4)

WAIT_CLASS_ID      NUMBER

WAIT_CLASS#       NUMBER

WAIT_CLASS        VARCHAR2(64)

WAIT_TIME        NUMBER

SECONDS_IN_WAIT     NUMBER

STATE          VARCHAR2(19)

这些列与 V$SESSION_WAIT 中的那些列相同,且显示相同的信息,从而不再需要在那个视图中查看它们了。因此,对于等待任意事件的任意会话,您仅需要查看一个视图。

让我们回到原来的问题: SID 为 269 的会话正等待事件 enq:TX — row lock contention ,指示它正等待被另一个会话占用的锁。要诊断该问题,您必须识别占用锁的那个会话。但您如何才能做到这一点?

在 Oracle9 i 及更低版本中,您可能得编写复杂(和极耗资源)的查询来获得占用锁的会话的 SID 。而在 10 g 中,您所要做的就是执行以下查询:

select BLOCKING_SESSION_STATUS, BLOCKING_SESSION

from v$session

where sid = 269

BLOCKING_SE BLOCKING_SESSION

----------- ----------------

VALID           265

找到了: SID 为 265 的会话阻塞了会话 269 。还能更容易吗?

有多少等待?

用户仍然在缠着您,因为用户的问题仍然没有得到满意的解答。为什么用户的会话花了这么长时间才完成?您可以执行以下命令来找出原因:

select * from v$session_wait_class where sid = 269;

输出返回为:

SID  SERIAL# WAIT_CLASS_ID WAIT_CLASS#  WAIT_CLASS  TOTAL_WAITS TIME_WAITED

---- ------- ------------- ----------- ------------- ----------- -----------

269   1106  4217450380       1  Application      873    261537

269   1106  3290255840       2  Configuration      4       4

269   1106  3386400367       5  Commit          1       0

269   1106  2723168908       6  Idle          15     148408

269   1106  2000153315       7  Network         15        0

269   1106  1740759767       8  User I/O        26        1

注意这里有关会话等待的大量信息。现在您知道了,该会话已经为与应用程序相关的等待等待了 873 次(共 261,537 厘秒),在与网络相关的事件中等待了 15 次等等。

以此类推,您可以使用以下查询来查看系统范围的等待类的统计数据。同样,时间是以厘秒为单位的。

select * from v$system_wait_class;

WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS TOTAL_WAITS TIME_WAITED

------------- ----------- ------------- ----------- -----------

1893977003        0 Other         2483     18108

4217450380        1 Application      1352     386101

3290255840        2 Configuration      82      230

3875070507        4 Concurrency       80      395

3386400367        5 Commit         2625      1925

2723168908        6 Idle         645527   219397953

2000153315        7 Network         2125       2

1740759767        8 User I/O         5085      3006

4108307767        9 System I/O       127979     18623

大多数问题不是孤立出现的;它们留下了揭示真相的线索,模式可以识别这些线索。可以按如下方式从等待类的一个历史视图中查看模式。

select * from v$waitclassmetric;

这个视图存储了最后一分钟内与等待类相关的统计数据。

select wait_class#, wait_class_id,

average_waiter_count "awc", dbtime_in_wait,

time_waited, wait_count

from v$waitclassmetric

/

WAIT_CLASS# WAIT_CLASS_ID AWC DBTIME_IN_WAIT TIME_WAITED WAIT_COUNT

----------- ------------- ---- -------------- ----------- ----------

     0   1893977003   0        0      0      1

     1   4217450380   2        90     1499      5

     2   3290255840   0        0      4       3

     3   4166625743   0        0      0       0

     4   3875070507   0        0      0       1

     5   3386400367   0        0      0       0

     6   2723168908   59        0    351541      264

     7   2000153315   0        0       0      25

     8   1740759767   0        0       0       0

     9   4108307767   0        0       8      100

     10   2396326234   0        0       0       0

     11   3871361733   0        0       0       0

注意 WAIT_CLASS_ID 和相关的统计数据。对于值 4217450380 ,我们看到 2 个会话在最后一分钟内总共等待了该类 5 次( 1,499 厘秒)。但该等待类是什么?您可以从 V$SYSTEM_WAIT_CLASS 中获取这一信息(如上所示) — 就是 Application 类。

注意名称为 DBTIME_IN_WAIT 的列,这是一个非常有用的列。在我们 关于自动工作负载信息库 (AWR) 的部分中,您可能还记得在 10 g 中是以更细粒化的方式来报告时间的,并且可以确定在数据库中花费的准确时间。 DBTIME_IN_WAIT 显示在数据库中花费的时间。

一切都留有线索

用户终于离开了,您长舒了一口气。但您可能仍然想寻根究底,希望查明主要是哪些等待造成用户会话中的问题。当然,您可以通过查询 V$SESSION_WAIT 而轻易地得到答案 — 但不幸的是,等待事件现在不存在了,因此该视图没有它们的任何记录。您该怎么办?

在 10 g 中,自动保留活动会话最后 10 个事件的会话等待历史。这个历史可通过 V$SESSION_WAIT_HISTORY 视图查看。要找出这些事件,您可以简单地执行:

select event, wait_time, wait_count

from v$session_wait_history

where sid = 265

/

EVENT               WAIT_TIME WAIT_COUNT

------------------------------ ---------- ----------

log file switch completion      2      1

log file switch completion      1      1

log file switch completion      0      1

SQL*Net message from client   49852       1

SQL*Net message to client      0       1

enq:TX - row lock contention    28      1

SQL*Net message from client    131      1

SQL*Net message to client      0      1

log file sync            2       1

log buffer space           1      1

当会话变为非活动状态或断开时,记录从该视图中消失。不过,这些等待的历史保留在 AWR 表中,以便进一步分析。从 AWR 中显示会话等待的视图是 V$ACTIVE_SESSION_HISTORY 。(同样,有关 AWR 的更多信息,请参考本系列的 。)

结论

通过 Oracle 数据库 10 g 中的等待模型的增强,分析性能问题变得非常容易。提供的会话等待历史可以帮助您在会话经历等待后诊断问题。将等待归为各种等待类还有助于您了解每种类型等待所造成的影响,这在研究正确的纠正方法时将带来便利。

有关等待事件动态性能视图和等待事件本身的更多信息,请参考《 Oracle 数据库性能调整指南 10g 第 1 版 (10.1) 》的 第 10 章 。

阅读(408) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~