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

如何获取长事务的运行情况

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2009-01-07 14:53:02

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

在一个系统中,往往会出现一些长事务进行大批量的数据处理,这些事务往往占据大量系统资源,而且运行时间长。如果我们不能有效的监控这些事务,可能会影响到其他事务的运行,甚至可能会由于事务没有在预期时间内完成作业,到了业务高峰时期仍然在运行而导致系统被hung

实际上,oracle提供了一个视图让DBA来监控长事务的运行状况及历史信息。下面介绍如何使用这个视图来查看长事务信息——v$session_longops

oracle中,运行时间超过6秒的事务就被视为长事务。确切地说,这个视图显示的就是时间超过6秒的一些操作,包括备份和恢复、统计数据收集、查询中的各种操作。在视图的各个字段中,totalwork表示该操作要完成所需要做的总的工作单位数;sofar则是目前已经完成的工作单位数;unit则表明工作单位是什么,例如,全表扫描操作中,是以数据块为单位;eplapsed_seconds是操作已经完成的时间,time_remaining是操作的剩余时间。另外,如果操作涉及到的是sql语句,则可以通过sql_addresssql_hash_value查询到相关语句。

对于sql查询,如果要使该视图可以查询到相关记录,还需要满足以下2个条件:

1、 设置TIMED_STATISTICSTRUE或者设置SQL_TRACETRUE

2、 相关对象需要已经被分析过。

 

下面的例子演示如何使用该视图:

SQL> create table t_test2 as select a.* from user_objects a, user_objects b;
 
Table created.
 
SQL> analyze table t_test2 compute statistics;
 
Table analyzed.
 
SQL> show parameter timed_statistics
 
NAME                TYPE                     VALUE
------------------- ------------------------ ---------------------
timed_statistics    boolean                  TRUE
 
SQL> select count(1) from t_test2;
 

 

查询运行6秒后,没有结束,在另一个会话中查询视图:

SQL> select opname, target, round(sofar/totalwork*100,2) as progress,  
     time_remaining, elapsed_seconds from v$session_longops
  2  where sofar < totalwork;
 
OPNAME         TARGET           PROGRESS     TIME_REMAINING   ELAPSED_SECONDS
-------------- ---------------- ------------ ---------------- -----------------
Table Scan     DEMO.TEST2       6.34         635              43

 

但是,使用该视图查询长事务操作,也是有一些限制的。例如,对于语句,需要满足以上两个条件,否则不能从视图中查询到相关操作。另外一个限制就是,这个视图只能能查询到如单对象操作,full table scanfast full index scansort等,而不能查到多对象操作,如join。看以下例子:

 

SQL> create table t_test as select * from all_objects;
 
Table created.
 
SQL> analyze table t_test compute statistics;
 
Table analyzed.
 
SQL> select count(*) from t_test a, t_test b;
 

 

运行时间超过10秒后,我们在另外会话中查询视图:

 

SQL> select opname, target, round(sofar/totalwork*100,2) as progress,  
     time_remaining, elapsed_seconds from v$session_longops
  2  where sofar < totalwork;
 
no rows selected

 

我们看下以上语句的查询计划:

 

SELECT STATEMENT, GOAL = CHOOSE             Cost=1288140     Cardinality=1        
 SORT AGGREGATE                             Cardinality=1                      
  MERGE JOIN CARTESIAN                      Cost=1288140     Cardinality=940587561              IO cost=1288140
   TABLE ACCESS FULL      Object owner=CSSOWNER     Object name=T_TEST        Cost=42  Cardinality=30669             
   BUFFER SORT                     Cost=1288098     Cardinality=30669 
    TABLE ACCESS FULL     Object owner=CSSOWNER     Object name=T_TEST        Cost=42  Cardinality=30669             

 

可以看到,该语句的主要消耗的操作是MERGE JOIN CARTESIAN,即笛卡尔乘积。尽管查询计划中也存在表扫描,但是由于表本身的数据量不大,因此表扫描的代价并不大,cpu时间消耗不大,因此没有被记录:

 

SQL> set timing on
SQL>
SQL> select count(*) from t_test;
 
  COUNT(*)
----------
     30669
 
Elapsed: 00:00:00.11

 

Top

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

申明
by fuyuncat