转:oracle几组重要的常见视图-v$process,v$session,v$session_wait,v$session_event v$process v$session v$session_wait v$session_event

本视图包含当前系统oracle运行的所有进程信息。常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系某些情况下非常有用:

    1 如果数据库瓶颈是系统资源(如:cpu,内存),并且占用资源最多的用户总是停留在某几个服务进程,那么进行如下诸项:

    找出资源进程

    找出它们的session,你必须将进程与会话联系起来。

    找出为什么session占用了如此多的资源

    2 SQL跟踪文件名是基于服务进程的操作系统进程ID。要找出session跟踪文件,你必须将session与服务进程联系起来。

    3 某些事件,如rdbms ipc reply,鉴别session进程的Oracle进程ID在等什么。要发现这些进程在做什么,你必须找出它们的session

你所看到的服务器上的后台进程(DBWR,LGWR,PMON)都是服务进程。要想知道他们在做什么,你必须找到他们的session

V$PROCESS中的常用列

  ADDR:进程对象地址

  PIDoracle进程ID

  SPID:操作系统进程ID

V$PROCESS中的连接列

Column  View    Joined Column(s)

ADDR   V$SESSION   PADDR

示例:

1查找指定系统用户在oracle中的session信息及进程id,假设操作系统用户为:

 select s.sid,s.SERIAL#, s.username,p.spid
  from v$session s, v$process p
 where s.osuser = 'Administrator'
   and s.PADDR = p.ADDR;
osuer   Administrator terminal
USER-20150311PW machine WORKGROUPUSER-20150311PW

2 查看锁和等待

SELECT /*+ rule */
 lpad(' ', decode(l.xidusn, 0, 3, 0)) || l.oracle_username User_name,
 o.owner,o.object_name,o.object_type,s.sid,s.serial#,p.spid
  FROM v$locked_object l, dba_objects o, v$session s, v$process p
 WHERE l.object_id = o.object_id
   AND l.session_id = s.sid and s.paddr = p.addr
 ORDER BY o.object_id, xidusn DESC;

找出锁正在执行的sql语句

SELECT   /*+ ORDERED */
         sql_text
    FROM v$sqltext a
   WHERE (a.hash_value, a.address) IN (
            SELECT DECODE (sql_hash_value,0, prev_hash_value, sql_hash_value   ),
                   DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)
              FROM v$session b
             WHERE b.paddr = (SELECT addr FROM v$process c
                                WHERE c.spid =13780))
ORDER BY piece ASC-------找出指定的pid正在执行的sql语句
.spid------用上面的sql找到
--lock_object
select sess.sid,
   sess.serial#,
   lo.oracle_username,
   lo.os_user_name,
   ao.object_name,
   lo.locked_mode
   from v$locked_object lo,
   dba_objects ao,
   v$session sess
where ao.object_id = lo.object_id and lo.session_id = sess.sid;

附注:

  在linux环境可以通过ps查看进程信息包括pid,windows中任务管理器的PIDv$processpid不能一一对应,这块在oracleDocument中也没有找到介绍,

后来google了一下,有资料介绍说是由于windows是多线程服务器,每个进程包含一系列线程。这点于unix等不同,Unix每个Oralce进程独立存在,在Nt上所有线程由Oralce进程衍生。

  要在windows中显示oracle相关进程pid,我们可以通过一个简单的sql语句来实现。

SELECT s.SID, p.pid, p.spid signaled, s.osuser, s.program
  FROM v$process p, v$session s
 WHERE p.addr = s.paddr;
还可以通过和 v$bgprocess 连接查询到后台进程的名字: 
SELECT s.SID SID, p.spid threadid, p.program processname, bg.NAME NAME
  FROM v$process p, v$session s, v$bgprocess bg
 WHERE p.addr = s.paddr
   AND p.addr = bg.paddr
   AND bg.paddr <> '00';

v$session

在本视图中,每一个连接到数据库实例中的session都拥有一条记录。包括用户session及后台进程如DBWRLGWRarcchiver等等。

V$SESSION中的用列

V$SESSION是基础信息视图,用于找寻用户SIDSADDR。不过,它也有一些列会动态的变化,可用于检查用户。如例:

SQL_HASH_VALUESQL_ADDRESS:这两列用于鉴别默认被session执行的SQL语句。如果为null0,那就说明这个session没有执行任何SQL语句。

PREV_HASH_VALUEPREV_ADDRESS两列用来鉴别被session执行的上一条语句。

STATUS:这列用来判断session状态是:

  Achtive:正执行SQL语句(waiting for/using a resource)

  Inactive:等待操作(即等待需要执行的SQL语句)

Killed:被标注为删除

下列各列提供session的信息,可被用于当一个或多个combination未知时找到session

Session信息

  SIDSESSION标识,常用于连接其它列

  SERIAL#:如果某个SID又被其它的session使用的话则此数值自增加(当一个 SESSION结束,另一个SESSION开始并使用了同一个SID)

  AUDSID:审查session ID唯一性,确认它通常也用于当寻找并行查询模式

  USERNAME:当前sessionoracle中的用户名。

  Client信息

数据库session被一个运行在数据库服务器上或从中间服务器甚至桌面通过SQL*Net连接到数据库的客户端进程启动,下列各列提供这个客户端的信息

  1. OSUSER:客户端操作系统用户名
  2. MACHINE:客户端执行的机器
  3. TERMINAL:客户端运行的终端
  4. PROCESS:客户端进程的ID
  5. PROGRAM:客户端执行的客户端程序

要显示用户连接PC的 TERMINAL、OSUSER,需在该PCORACLE.INIWindows中设置关键字TERMINALUSERNAME

Application信息

调用DBMS_APPLICATION_INFO包以设置一些信息区分用户。这将显示下列各列。

  CLIENT_INFODBMS_APPLICATION_INFO中设置

  ACTIONDBMS_APPLICATION_INFO中设置

  MODULEDBMS_APPLICATION_INFO中设置

下列V$SESSION列同样可能会被用到:

  ROW_WAIT_OBJ#

  ROW_WAIT_FILE#

  ROW_WAIT_BLOCK#

  ROW_WAIT_ROW#

V$SESSION中的连接列

Column     View                                Joined  Column(s)

SID     V$SESSION_WAIT,,V$SESSTAT,,V$LOCK,V$SESSION_EVENT,V$OPEN_CURSOR   SID

(SQL_HASH_VALUE, SQL_ADDRESS) V$SQLTEXT, V$SQLAREA, V$SQL             (HASH_VALUE, ADDRESS)

(PREV_HASH_VALUE, PREV_SQL_ADDRESS) V$SQLTEXT, V$SQLAREA, V$SQL        (HASH_VALUE, ADDRESS)

TADDR V$TRANSACTION                                   ADDR

PADDR V$PROCESS                                     ADDR

示例:

1.查找你的session信息
SELECT SID, OSUSER, USERNAME, MACHINE, PROCESS
FROM V$SESSION WHERE audsid = userenv('SESSIONID');
2.当machine已知的情况下查找session
SELECT SID, OSUSER, USERNAME, MACHINE, TERMINAL
  FROM V$SESSION
 WHERE terminal = 'pts/tl' AND machine = 'rgmdbs1';
3查找当前被某个指定session正在运行的sql语句。假设sessionID为100
 select b.sql_text 
  from v$session a,v$sqlarea b 
where a.sql_hash_value=b.hash_value and a.sid=299

select b.sql_text 
  from v$session a,v$sqlarea b 
  where a.sql_hash_value=b.hash_value
寻找被指定session执行的SQL语句是一个公共需求,如果session是瓶颈的主要原因,那根据其当前在执行的语句可以查看session在做些什么。
Used with SQL_ADDRESS to identify the SQL statement that is currently 
being executed

v$session 表中比较常用的几个字段说明^_^
1. sid,serial#
通过sid我们可以查询与这个session相关的各种统计信息,处理信息.
a. select * from v$sesstat where sid = :sid;
查询用户相关的各种统计信息.
select a.sid,a.statistic#,b.name,a.value
from v$sesstat a,v$statname b
where a.statistic# = b.statistic#
and a.sid = :sid;
b. 查询用户相关的各种io统计信息
select * from v$sess_io where sid = :sid;
c. 查询用户想在正在打开着的游标变量.
select * from v$open_cursor where sid = :sid;
d. 查询用户当前的等待信息. 以查看当前的语句为什么这么慢/在等待什么资源.
select * from v$session_wait where sid = :sid ;
e. 查询用户在一段时间内所等待的各种事件的信息. 以了解这个session所遇到的瓶颈^_^
select * from v$session_event where sid = :sid;
f. 还有, 就是当我们想kill当前session的时候可以通过sid,serial#来处理.
alter system kill session ':sid,:serail#';
2. paddr.字段, process addr, 通过这个字段我们可以查看当前进程的相关信息, 系统进程id,操作系统用户信息等等.
select a.pid,a.spid,b.name,b.description,a.latchwait,a.latchspin,a.pga_used_mem,a.pga_alloc_mem,a.pga_freeable_mem,a.pga_max_mem
from v$process a,v$bgprocess b
where a.addr = b.paddr(+)

and a.addr = :paddr
3. command 字段, 表明当前session正在执行的语句的类型.请参考reference.
4. taddr 当前事务的地址,可以通过这个字段查看当前session正在执行的事务信息, 使用的回滚段信息等^_^
select b.name rollname,a.*
from v$transaction a,v$rollname b
where a.xidusn = b.usn
and a.addr = '585EC18C';
5. lockwait字段, 可以通过这个字段查询出当前正在等待的锁的相关信息.
select *
from v$lock
where (id1,id2) = (
        select id1,id2 from v$lock where kaddr = '57C68C48'
)
6. (sql_address,sql_hash_value) (prev_sql_addr,prev_hash_value) 根据这两组字段, 我们可以查询到当前session正在执行的sql语句的详细信息.
select * from v$sqltext where address = :sql_address and hash_value = :sql_hash_value;
7.ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#
可以通过这几个字段查询现在正在被锁的表的相关信息.^_^
a. 首先得到被锁的的信息
select * from dba_objects where object_id = :row_wait_obj#;
b. 根据row_wait_file#可以找出对应的文件的信息.
select * from v$datafile where file# = :row_wait_file#.
c. 在根据以上四个字段构造出被锁的字段的rowid信息.
select dbms_rowid.ROWID_CREATE(1,:row_wait_obj#,:row_wait_file#,:row_wait_block#,:row_wait_row#) from dual;
8. logon_time 当前session的登录时间.
9. last_call_et session idle的时间, 3秒中更新一次^_^

v$session_wait

这是一个寻找性能瓶颈的关键视图。它提供了任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做,则显示它最后的等待事件)

当系统存在性能问题时,本视图可以做为一个起点指明探寻问题的方向。

V$SESSION_WAIT中,每一个连接到实例session都对应一条记录

V$SESSION_WAIT中的常用列

  SID: session标识

   EVENT: session当前等待的事件,或者最后一次等待事件。

  WAIT_TIME: session等待事件的时间(单位,百分之一秒)如果本列为0,说明session当前session还未有任何等待。

  SEQ#: session等待事件将触发其值自增长

  P1, P2, P3: 等待事件中等待的详细资料

  P1TEXT, P2TEXT, P3TEXT: 解释说明p1,p2,p3事件

附注:

1.State字段有四种含义

  WaitingSESSION正等待这个事件。

  Waited unknown time:由于设置了timed_statistics值为false,导致不能得到时间信息。表示发生了等待,但时间很短。

  Wait short time:表示发生了等待,但由于时间非常短不超过一个时间单位,所以没有记录。

  Waited knnow time:如果session等待然后得到了所需资源,那么将从waiting进入本状态。

2.Wait_time值也有四种含义:

  1. >0:最后一次等待时间(单位:10ms),当前未在等待状态。
  2. =0session正在等待当前的事件。
  3. =-1:最后一次等待时间小于1个统计单位,当前未在等待状态。
  4. =-2:时间统计状态未置为可用,当前未在等待状态。

3.Wait_timeSecond_in_wait字段值与state关:

(1)如果state值为Waiting,那么wait_time值无用。Second_in_wait值是实际的等待时间(单位:秒)

(2)如果state值为Wait unknow time,那么wait_time值和Second_in_wait值都无用。

(3)如果state值为Wait short time,那么wait_time值和Second_in_wait值都无用。

(4)如果state值为Waiting known time,那么wait_time值就是实际等待时间(单位:秒)Second_in_wait值无用

V$SESSION_WAIT中的连接列

Column  View    Joined Column(s)

SID   V$SESSION   SID

示例:

1.列出当前系统的等待事件
SELECT event,
       sum(decode(wait_time,0,1,0)) "Curr",
       sum(decode(wait_time,0,0,1)) "Prev",
       count(*)"Total"
FROM v$session_wait GROUP BY event ORDER BY count(*);

这个按事件和wait_time的分组查询列出下列的信息:

  多数的session都是空闲事件如:SQL*Net message from client, pipe get, PMON timer等。

  sessioncpu占用可以通过上次session的非等待事件大致算出,除此问题外:看起来多数session没有在等待什么事情(难道他们都在干活?)但其最后等待事件都是SQL*Net message from client

2列出指定ID的等待事件
select * from v$session_wait where sid=299
3 应用p1,p2,p3进行等待事件的分析
v$session_wait视图的列代表的缓冲区忙等待事件如下: 
P1—与等待相关的数据文件的全部文件数量。 
P2—P1中的数据文件的块数量。 
P3—描述等待产生原因的代码。
例:select p1 "File #", p2 "Block #", p3 "Reason Code"
  from v$session_wait
  where event = 'buffer busy waits';
如果以上查询的结果显示一个块在忙等待,以下的查询将显示这一块的名称和类型:
select owner, segment_name, segment_type
 from dba_extents
 where file_id = &P1 and &P2 between block_id and block_id + blocks -1;

v$session_event

本视图记录了每个session的每一项等待事件由上文所知V$SESSION_WAIT显示了session当前等待事件,而V$SESSION_EVENT则记录了session自启动起所有的事件。

V$SESSION_EVENT中的常用列

  SID:session标识

  EVENT:session等待的事件

  TOTAL_WAITS:session当前事件的总等待数

  TIME_WAITED:session总等待时间(单位,百分之一秒)

  AVERAGE_WAIT:session当前事件平均等待时间(单位,百分之一秒)

  TOTAL_TIMEOUTS:等待超时次数

其它用法与V$SESSION_WAIT相似,不详述了

附注:

Oracle的等待事件是衡量Oracle运行状况的重要依据及指标。等待事件的概念是在Oracle7.0.1.2中引入的,大致有100个等待事件。

Oracle 8.0中这个数目增加到了大约150个,在Oracle8i中大约有200个事件,Oracle9i中大约有360个等待事件。主要有两种类别的等待事件,即空闲(idle)等待事件和非空闲(non-idle)等待事件。

关于空闲事件和非空闲事件目前通过google可以搜索到非常多详尽的相关信息,同时

Oracle Database Performance Tuning Guide and Reference中关于Wait Events也有非常详尽的描述,在此就不多费口舌了。

不过我在itpub论坛看到有热心人整理的chm格式非空闲事件说明,有兴趣的朋友可以下载,链接如下:

非空闲事件说明

详见:http://www.itpub.net/728733.html.