HelloDBA [English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com   acoug  acoug 

Oracle 10g新特性——等待接口

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2006-04-07 14:47:04

分享到  新浪微博 腾讯微博 人人网 i贴吧 开心网 豆瓣 淘宝 推特 Facebook GMail Blogger Orkut Google Bookmarks

前言

在处理被ADDM捕捉的突发的性能问题中,10g等待接口提供非常有价值的数据用于诊断。作为一个DBA,你可能遇到过很多次用户抱怨“数据库非常慢了”。那么你是如何定位这种问题的呢?你第一步要做的肯定是查看是否有会话在等待数据库内部或外部的什么资源。

Oracle提供了一个简单但是又很有效的机制来获取这些信息:视图V$SESSION_WAIT。这一视图提供了各种信息以帮助诊断如一个会话正在等待和已经等待的事件、及等待了多少、等待时间多长。例如,如果会话正在等待事件“db file sequential read”,字段P1P2就标识会话正在等待的数据块的file_idblock_id

对于大多数等待事件来说,这个视图已经足够了。但由于以下两个原因,它很难成为一个强有力的优化工具:

·         这个视图只是当前状态的一个快照。当等待不存在了,会话早前关于这些等待的历史信息也没有了,使事后诊断分析变得很困难。

V$SESSION_EVENT视图提供了累积的但不够详细的数据。

·         V$SESSION_WAIT视图仅包含了等待事件的信息。要获取其他相关信息如USERID和终端信息就必须和视图V$SESSION连接查询。

Oracle 10g中,等待接口从根本上被重新设计了,提供了更多的信息,而且减少了DBA的干预。在这篇文章中,我们将探索这些特性,看看它们如何帮助我们来诊断性能问题。对于大多数性能问题,你能从ADDM中得到扩展的分析信息,但是ADDM没有捕捉到哪些即时问题的信息。而等待接口提供了非常有用的数据用于诊断。

增强的会话等待

首先一个增强就是对视图V$ESSION_WAIT本身的。这可以从一个例子来解释。加入您的用户抱怨会话被hang住了。你查出这个会话的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_IDWAIT_CLASS#WAIT_CLASS字段是10g中新增的。字段WAIT_CLASS表示这个等待的类型是一个有效的等待事件还是一个可以被忽略的空闲等待事件。在上面的例子中,等待类型是Application,表明它在等待你的干预。

这一字段让你更加明确哪些字段可以用于调优。例如,你可以用以下查询来获取等待这个事件的会话:

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

2    from v$session_wait

3    order by wait_class, event, sid

4 /

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 WaitJobQueue Slave)被明确标注为Idle事件。你可以把它们视为非阻塞等待忽略掉。但是,有时候这些idle事件预示着一个内部问题。例如,与SQL*NET相关的事件可能预示网络可能出现潜在问题。

另外一个需要注意的重要信息就是字段WAIT_TIME的值是-2。一些平台,如Windows,不支持快速计时机制。如果在哪些平台上,初始化参数TIMED_STATISTICS没有设置为on,就无法检测到精确的计时统计。在那样的情况下,在Oracle9i中,这个字段的值是一个非常大的值,它会让以后的问题定位产生混乱。在10g中,值-2就表示是这种情况——平台不支持快速计时机制并且TIME_STATISTICS被设置为off

会话也会显示等待信息

还记得前面说需要将视图V$SESSION_WAITV$SESSION连接查询来获取关于会话的细节信息吗?在10g中,这将成为历史。10g中的视图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中的是一样的,并且显示的信息也相同。这样就无需再查询V$SESSION_WAIT视图了,要获取到会话的等待信息就只需要查询一个视图就行了。

让我们看看前面这个例子:SID269的会话正在等待事件enq: TX ?C row lock contention。这表示它正在等待另外一个会话持有的锁。要诊断这个问题,你就必须定位到另外一个会话。如何做呢?

9i和以下版本中,你可能需要写一个复杂的查询来获取到持有锁的会话的SID。在10g中,你就只需要执行以下查询就可以了:

SQL> select BLOCKING_SESSION_STATUS, BLOCKING_SESSION

2    from v$session

3    where sid = 269;

BLOCKING_SE BLOCKING_SESSION

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

VALID                    265

这个结果说明:SID265的会话阻塞了会话269

有多少等待?

有一个用户的会话一致在保持着,他的问题还没有得到满意的解决。为什么他的会话会保持这么长事件还没有完成呢?你可以通过以下查询来定位:

SQL> 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次、261537厘秒,等待网络相关的事件15次,等等。

用同样方法,你可以通过以下查询获取到整个系统范围的等待事件分类的统计信息,时间单位还是厘秒:

SQL> 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

大多数问题的发生都不是孤立的。在它们背后还存在一些其他问题,这些问题可以通过一种样式来定位。这一样式可以通过以下查询语句来查询一个历史视图来获得:

SQL> select wait_class#, wait_class_id,

2    average_waiter_count "awc", dbtime_in_wait,

3    time_waited,  wait_count

4    from v$waitclassmetric

5 /

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次、1499厘秒。但是这一类型等待是什么等待事件呢?你可以从视图V$SYSTEM_WAIT_CLASS中得到这个信息。如上所示,这是Application类型事件。

再注意DBTIME_IN_WAIT这一非常有用的字段。你也许还记得在10gAWR中会在很细的粒度下记录下数据库的消耗时间。DBTIME_IN_WAIT就表示数据库消耗的等待时间。

跟踪

当用户的问题解决后,你可能还要继续跟踪有什么其他不同的等待事件导致了他的问题。当然,你可以很轻松的通过查询V$SESSION_WAIT视图来获取答案。但是很不幸,这些等待事件都已经不存在了。因此也就没有它们的记录了。这时要如何做?

10g中,视图V$SESSION_WAIT_HISTORY会自动记录下活动会话等待的最近10次的等待事件历史信息。要查找这些事件,只要执行以下语句:

SQL> select event, wait_time, wait_count

2    from v$session_wait_history

3    where sid = 265

4 /

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

总结

由于10g的这些增强特性,分析性能问题变得十分简单。关于会话等待的历史信息帮助你诊断会话结束以后发生的问题。对等待的分类可以帮助你理解每个等待的重要性。

 

Top

Copyright ©2005,HelloDBA.Com 保留一切权利

申明
by fuyuncat