ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 在Oracle10g中诊断性能问题

在Oracle10g中诊断性能问题

原创 Linux操作系统 作者:oracle_ace 时间:2008-01-19 14:05:08 0 删除 编辑

Oracle10g为我们提供了,诊断和跟踪性能问题的绝佳方法。这些方法相比以前有了一些改进,新引入了9i中没有的新视图,比如
v$sess_time_model,v$session_wait_class,同时v$session视图的功能更加强大了。现在就来学习一下。呵呵:)

比如我做个实验造成一个锁等待

sess 1:
*********

SQL> select sid from v$mystat where rownum = 1;

       SID
----------
       525

SQL> select * from t;

        ID NAME
---------- ----------
         1 A
         2 B
         3 C
         4 D
         5 E

SQL> update t set name='e' where id=5;

1 row updated.


sess 2:
*********
SQL> select sid from v$mystat where rownum = 1;

       SID
----------
       532

SQL> update t set name='EE' where id=5;

此时这个session 532被hang住了。


在另外一个session我们来trace这个事件:

sess3:
**********
在Oracle 10g中v$session视图得到了极大的改进,引入了v$session_wait视图的一些功能。同时新增加了blocking_session这个column,表示某个session正在阻塞别人, 而且我们还可以根据wait_class这个列来对等待类别进行过滤

SQL> select sid,username,
     event,
     blocking_session,
     seconds_in_wait,
     wait_time
     from v$session where state in ('WAITING')
     and wait_class != 'Idle';

       SID USERNAME
---------- ------------------------------
EVENT                                                            SECONDS_IN_WAIT
---------------------------------------------------------------- ---------------
 WAIT_TIME
----------
       532 SYS
enq: TX - row lock contention                                              71536
         0

sess1的sid是525,sess2的sid是532,那么结果表明,sid 532被blocking_session 525给blocked住了,以一种TX事务锁的方式block

也就是说SID 525会话正在等待一个表上的事务锁的释放,而这个锁正由532会话(BLOCKING_SESSION)占用。

现在我又想知道是那个SQL语句导致了这个锁的占用也就是说,525这个session在执行什么SQL,hold住了我们的事务锁,那么我们可以通过连接V$SESSION和V$SQL这两个视图执行下面的查询很容易地找到答案:

SQL> select sid, sql_text
     from v$session s, v$sql q
     where sid in (532,525)
     and (q.sql_id = s.sql_id or q.sql_id = s.prev_sql_id);

这里我们用到了sql_id这是10g推出的一种唯一标识SQL语句的列,通过他我们可以唯一标识我们的sql

       SID
----------
SQL_TEXT
---------------------------------------------
       525
update t set name='e' where id=5

       532
update t set name='EE' where id=5

       532
select sid from v$mystat where rownum = 1

我们看到两个会话都试图更新同一行。除非会话525提交或回滚,否则会话532将一直等待这个锁。
 
以上就是我们的会话等待的检索方法。

在10g之后还提出了等待类的概念:
并且推出了新的视图v$session_wait_class
我们来看一下session 532的等待类

SQL> select wait_class_id,wait_class,total_waits,time_waited
     from v$session_wait_class
     where sid=532;

WAIT_CLASS_ID WAIT_CLASS
------------- ---------------------
TOTAL_WAITS TIME_WAITED
----------- -----------
   4217450380 Application
      23863     6986631

   2723168908 Idle
          6       38227

   2000153315 Network
          6           0

还是继续上面的测试,我们知道sid=532一直在等待sid=525的会话,在这个结果中,显示了每个类中会话的等待事件的次数,还有等待的时间,我们看到application这一级别中,的等待次数是876,而time_waited时间是69866.31秒(原来的6986631单位是厘秒单位,百分之一秒).那么这个时候我们还可以从application等待类中寻找引起等待的原因。

v$system_event视图中我们可以获得每种等待的出现次数。我们这里的application的id为4217450380

SQL> select event,total_waits,time_waited
  2  from v$system_event e,v$event_name n
  3  where n.event_id=e.event_id
  4  and n.wait_class_id=4217450380;

EVENT                                                            TOTAL_WAITS
---------------------------------------------------------------- -----------
TIME_WAITED
-----------
enq: RO - fast object reuse                                               51
          1

enq: TX - row lock contention                                          23891
    6994835

SQL*Net break/reset to client                                             34
          0

我们可以看到在这个application等待类中锁的争用占了大部分的时间。

假如我们并不知道是什么原因,导致了这个锁的争用,那我们该怎么去定位这个TX-row lock contention的问题呢?这些数据仅仅告诉了我们ok,用户经历了23891次的锁的竞争,共花费了6994835厘秒,有可能大多数的等待只有1到2厘秒,那么如何在进行进一步的诊断呢?

Oracle 10g还为我们提供了另外一个视图叫v$event_histogram
它标市了等待时间的周期以及会话等待某一特定时间周期的频度

select wait_time_milli,wait_count
from v$event_histogram
where event='enq: TX - row lock contention';

WAIT_TIME_MILLI WAIT_COUNT
--------------- ----------
              1          0
              2          0
              4          0
              8          0
             16          0
             32          0
             64          0
            128          0
            256          4
            512         13
           1024          0
           2048          0
           4096      23896

v$event_histogram视图显示等待时间段以及在这期间会话等待某一特定事件--在这个例子中就是事务锁争用--的次数。例如,会话等待少于4096毫秒(ms)的事件共23532次,等等。WAIT_COUNT列值之和为23904.v$event_histogram视图显示,大多数等待发生在256毫秒、512毫秒和4096毫秒的事件上,这就充分证明了该应用程序正在经历锁的争用问题,如果视图显示等待发生在1毫秒的范围内,我们就不应该认为这是锁争用的问题,因为这样短时间的等待似乎是正常的。

Oracle 10g还推出了一种时间模型的概念:

比如我们经常会遇到有人抱怨某某sid的会话非常的慢.这个时候,我们首先可以通过v$session来查看。
首先我们可以监控出当前的活动session
SQL> select sid,username,status from v$session
     where status='ACTIVE' and username is not null;

       SID USERNAME                       STATUS
---------- ------------------------------ --------
       526 SYS                            ACTIVE
       532 SYS                            ACTIVE
       538 IRMADMIN                       ACTIVE

那么我的业务session就是536了,通过 v$session视图查看

select event,seconds_in_wait,wait_time
from v$session
where sid= 538

EVENT                                                            SECONDS_IN_WAIT
---------------------------------------------------------------- ---------------
 WAIT_TIME
----------
db file sequential read                                                        0
         1

我们看到sid=538有个等待事件,这样我们再来通过v$sess_time_model来估量一下,这个会话对资源的利用是否格外的高
SQL> select stat_name,value
  2  from v$sess_time_model
  3  where sid=538;

注意这些单位都是微秒一级的(1/1000000)
STAT_NAME                                                             VALUE
---------------------------------------------------------------- ----------
DB time                                                          2950266754
DB CPU                                                           2766530454
background elapsed time                                                   0
background cpu time                                                       0
sequence load elapsed time                                             8898
parse time elapsed                                                 32700260
hard parse elapsed time                                            31590611
sql execute elapsed time                                         2908768149
connection management call elapsed time                                2428
failed parse elapsed time                                                 0
failed parse (out of shared memory) elapsed time                          0
hard parse (sharing criteria) elapsed time                            63296
hard parse (bind mismatch) elapsed time                               63296
PL/SQL execution elapsed time                                      24049473
inbound PL/SQL rpc elapsed time                                           0
PL/SQL compilation elapsed time                                    21250121
Java execution elapsed time                                          902194
repeated bind elapsed time                                            18060
RMAN cpu time (backup/restore)                                            0

那么在检查数据库性能的时候,有的时候我们还需要检查操作系统一级的状态,那么在Oracle 10g之前呢,操作系统的工具比如OS,vmstat等工具,通过他们来确定一些争用问题的度量指标,在Oracle 10g中,我们可以在数据库中自动采集OS级别的度量指标,可以查看主机的一些潜在的主机争用问题

SQL> select stat_name,value from v$osstat;

这些单位都是厘秒一级的(1/100)

STAT_NAME                                                             VALUE
---------------------------------------------------------------- ----------
NUM_CPUS                                                                  4
IDLE_TIME                                                          34370136
BUSY_TIME                                                           1427854
USER_TIME                                                           1349492
SYS_TIME                                                              78323
IOWAIT_TIME                                                          209146
AVG_IDLE_TIME                                                       8591041
AVG_BUSY_TIME                                                        355613
AVG_USER_TIME                                                        336469
AVG_SYS_TIME                                                          18334
AVG_IOWAIT_TIME                                                       50465
OS_CPU_WAIT_TIME                                                    1446100
RSRC_MGR_CPU_WAIT_TIME                                                    0
LOAD                                                             .005859375
NUM_CPU_CORES                                                             2
NUM_VCPUS                                                                 2
NUM_LCPUS                                                                 4
PHYSICAL_MEMORY_BYTES                                            4026531840

系统的一个CPU有34370136厘秒空闲(IDLE_TIME)、1427854厘秒繁忙(BUSY_TIME),这表明CPU有大约4%的时间繁忙。可以得出结论,在主机中CPU不是瓶颈。请注意,如果主机系统有多于1个的CPU,则标头中有AVG_前缀的列,如AVG_IDLE_TIME将显示所有CPU的这些度量指标的平均值。

有一种情况,当我们查询v$session视图的时候,会话是空闲的,可能没有正在等待的事件,那么我们如何来诊断这个会话 出现问题的时候是在等待什么会话呢?

Oracle 10g在内存的缓冲区中每秒采集一次我们活动会话的信息,这个缓冲区被称为活动会话历史(Active session history,ASH),我们可以在v$active_session_history这样一个动态性能视图中查看他,其中的数据可以保留30分钟,那么我们在得到了sid和serial#后就可以查询v$active_session_history来找到我们会话过去的等待事件。

SQL> select sample_time,event,wait_time
  2  from v$active_session_history
  3  where session_id=538 and session_serial#=11197 and event is not null;

SAMPLE_TIME
---------------------------------------------------------------------------
EVENT                                                             WAIT_TIME
---------------------------------------------------------------- ----------
19-JAN-08 12.46.42.757 PM
direct path read temp                                                     0

19-JAN-08 12.46.23.746 PM
db file sequential read                                                   0

19-JAN-08 12.46.22.745 PM
db file sequential read                                                   0

这样我们就跟踪出历史的等待事件信息:
通过联合查询v$sql视图我们可以查看到具体时间等待事件的sql语句:
 这里我们查看direct path read temp等待事件的sql信息
select sql_text ,application_wait_time
from v$sql
where sql_id in
(select sql_id from v$active_session_history
where sample_time='19-JAN-08 12.46.42.757 PM' and session_id=538
and session_serial#=11197);

那么其中application_wait_time表示执行这个SQL的会话等待了多长时间的application的等待类。

如果ash的内容30分钟后被清除了,那么这些数据并没有丢失而是送到了AWR这样一个工作负载库中去了。这个库的内容可以从dba_hist_active_session_hist中看到。在默认的情况下这个视图的内容也只保留7天。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12361284/viewspace-153354/,如需转载,请注明出处,否则将追究法律责任。

上一篇: ELAPSED_TIME的单位
请登录后发表评论 登录
全部评论

注册时间:2007-12-10

  • 博文量
    284
  • 访问量
    787229