六 , 监控当前数据库的活动 session 6.1 监控 session 的执行语句 6.1.1 通过动态性能视图查找活动 session 的执行语句 select a.SID,a.USERNAME,a.machine,a.TERMINAL,b.PIECE,b.SQL_TEXT from v$session a, v$sqltext b where b.ADDRESS = decode(a.SQL_HA
六 , 监控当前数据库的活动 session
6.1 监控 session 的执行语句
6.1.1 通过动态性能视图查找活动 session 的执行语句
select a.SID,a.USERNAME,a.machine,a.TERMINAL,b.PIECE,b.SQL_TEXT
from v$session a,
v$sqltext b
where b.ADDRESS = decode(a.SQL_HASH_VALUE, 0 ,a.PREV_SQL_ADDR,a.SQL_ADDRESS)
and a.status = 'ACTIVE'
and user # > 0
order by a.SQL_ADDRESS,b.PIECE;
6.1.2 通过动态性能视图查找所有 session 的执行语句
select a.SID,b.ADDRESS,b.HASH_VALUE,a.USERNAME,a.machine,b.SADDR,c.PIECE,c.SQL_TEXT
from v$session a,
v$open_cursor b,
v$sqltext c
where a.SID = b.SID
and b.ADDRESS = c.ADDRESS
and b.HASH_VALUE = c.HASH_VALUE
and a.status = 'ACTIVE'
and user # > 0
order by a.SID,b.ADDRESS,b.HASH_VALUE,a.USERNAME,a.machine,b.SADDR,c.PIECE;
6.1.3 通过操作系统查找相关 session 信息
1, 找出最消耗 cpu 的操作系统进程
# ps aux| grep -v grep | grep ora| head -10
oracle 876648 1.9 1.0 57832 82156 - A 16:22:35 7:59 oracleSISDB2 (LO
oracle 594138 1.9 1.0 58808 83132 - A 15:22:46 16:48 oracleSISDB2 (LO
oracle 495712 0.9 1.0 56628 80952 - A 17:04:47 0:43 oracleSISDB2 (LO
oracle 712946 0.5 1.0 55716 80040 - A 17:11:33 0:07 oracleSISDB2 (LO
oracle 966862 0.1 1.0 55144 79468 - A Jul 08 153:01 oracleSISDB2 (LO
oracle 442494 0.1 1.0 58984 83308 - A Feb 16 1751:47 ora_lms1_SISDB2
oracle 581808 0.1 1.0 59140 83464 - A Feb 16 1747:01 ora_lms0_SISDB2
oracle 811254 0.1 1.0 55228 79552 - A 15:51:29 0:31 oracleSISDB2 (LO
oracle 573582 0.0 1.0 57680 82004 - A Feb 16 149:17 ora_lmon_SISDB2
oracle 651300 0.0 1.0 57204 81528 - A Feb 16 125:13 ora_diag_SISDB2
2, 找出给定操作系统 pid 的 session 的执行 sql
V$open_cursor 视图列出 session 打开的所有 cursor, 很多时候都将被用到 , 比如 : 你可以通过这个视图查看各个 session 打开的 cursor 数 .
当诊断系统资源占用时 , v$open_cursor 视图常被用来连接 v$sqlarea 和 v$sql 查询出特定 SQL( 高逻辑或物理 IO). 然后 , 下一步就是找出源头 .
V$sqlarea 中的统计项在语句完全执行后被更新 ( 并且从 v$session.sql_hash_value 中消失 ). 因此 , 我们无法通过 v$sqlarea 跟 v$session 直接关联找到 session, 除非语句被再次执行 . 不过如果 session 的 cursor 仍然打开着 , 用户就可以通过 v$open_cursor 来找出执行这个语句的 session.
SELECT /*+ ORDERED */
address,piece,sql_text
FROM v$sqltext a
WHERE (a.hash_value, a.address) IN (
SELECT d.HASH_VALUE,d.ADDRESS
FROM v$session b,v$open_cursor d
where b.SID = d.SID
and b.paddr = ( SELECT addr
FROM v$process c
WHERE c.spid = '&pid' ))
ORDER BY address,piece;
6.2 session 的资源占用
6.2.1 通过动态性能视图查找相关 session 信息
利用 V_$SQLAREA 视图提供了执行的细节。(执行、读取磁盘和读取缓冲区的次数)
• 数据列
EXECUTIONS :执行次数
DISK_READS :读盘次数
COMMAND_TYPE :命令类型( 3:select,2:insert;6:update;7delete;47:pl/sql 程序单元)
OPTIMIZER_MODE :优化方式
SQL_TEXT : Sql 语句
SHARABLE_MEM :占用 shared pool 的内存多少
BUFFER_GETS :读取缓冲区的次数
• 用途
1 、帮忙找出性能较差的 SQL 语句
2 、帮忙找出最高频率的 SQL
3 、帮忙分析是否需要索引或改善联接
求 DISK READ 较多的 SQL
select st.ADDRESS,st.PIECE,st.sql_text
from v$sql s, v$sqltext st
where s.address = st.address
and s.hash_value = st.hash_value
and s.disk_reads > 300
order by st.address, st.piece ;
求 DISK SORT 严重的 SQL
select sess.username, sql .sql_text, sort1.blocks
from v$session sess, v$sqlarea sql , v$sort_usage sort1
where sess.serial# = sort1.session_num
and sort1.sqladdr = sql .address
and sort1.sqlhash = sql .hash_value
and sort1.blocks > 200 ;
查看语句占用的内存情况
select username, sum (sharable_mem), sum (persistent_mem), sum (runtime_mem)
from sys .v_$sqlarea a, dba_users b
where a.parsing_user_id = b.user_id
group by username;
6.2.2 通过操作系统查找相关 session 信息
# ps aux|head -1; ps aux|sort -nr +2 |head -10
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND
root 73764 6.1 0.0 384 384 - A Jan 10 130144:34 wait
root 57372 6.1 0.0 384 384 - A Jan 10 132116:52 wait
root 65568 6.0 0.0 384 384 - A Jan 10 129411:36 wait
# ps aux |head -1; ps aux |sort -nr +3 | head -10
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND
oracle 974978 2.2 1.0 57992 82316 - A 14:05:06 2:41 oracleSISDB2 (LO
oracle 966862 0.1 1.0 55144 79468 - A Jul 08 80:49 oracleSISDB2 (LO
oracle 942332 0.0 1.0 59112 83436 - A Feb 16 2:24 ora_arc0_SISDB2
oracle 909346 1.4 1.0 58364 82688 - A 13:49:28 3:22 oracleSISDB2 (LO
SELECT /*+ ORDERED */
address,piece,sql_text
FROM v$sqltext a
WHERE (a.hash_value, a.address) IN (
SELECT d.HASH_VALUE,d.ADDRESS
FROM v$session b,v$open_cursor d
where b.SID = d.SID
and b.paddr = ( SELECT addr
FROM v$process c
WHERE c.spid = '&pid' ))
ORDER BY address,piece;
6.3 session 的等待事件
V$session_event, v$session_wait 两个视图中记录的是 session 级别的等待事件 , 通过查询这两个视图用户可以得到当前数据库的一些操作到底在等待什么 , 是磁盘 IO, 缓冲区忙还是插锁等 .
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 字段有四种含义﹕
Waiting : SESSION 正等待这个事件。
Waited unknown time :由于设置了 timed_statistics 值为 false ,导致不能得到时间信息。表示发生了等待,但时间很短。
Wait short time :表示发生了等待,但由于时间非常短不超过一个时间单位,所以没有记录。
Waited knnow time :如果 session 等待然后得到了所需资源,那么将从 waiting 进入本状态。
Wait_time 值也有四种含义:
值 >0 :最后一次等待时间 ( 单位: 10ms) ,当前未在等待状态。
值 =0 : session 正在等待当前的事件。
值 =-1 :最后一次等待时间小于 1 个统计单位,当前未在等待状态。
值 =-2 :时间统计状态未置为可用,当前未在等待状态。
3.Wait_time 和 Second_in_wait 字段值与 state 相关 :
如果 state 值为 Waiting ,那么 wait_time 值无用。 Second_in_wait 值是实际的等待时间 ( 单位:秒 ) 。
如果 state 值为 Wait unknow time ,那么 wait_time 值和 Second_in_wait 值都无用。
如果 state 值为 Wait short time ,那么 wait_time 值和 Second_in_wait 值都无用。
如果 state 值为 Waiting known time ,那么 wait_time 值就是实际等待时间 ( 单位:秒 ) , Second_in_wait 值无用。
Select s.SID,
s.username,
s.program,
s.status,
se.event,
se.total_waits,
se.total_timeouts,
se.time_waited,
se.average_wait
from v$session s, v$session_event se
Where s.sid = se.sid
And se.event not like 'SQl*Net%'
And s.status = 'ACTIVE'
And s.username is not null ;
Select s.SID,
s.username,
s.program,
s.status,
sw.EVENT,
sw.STATE,
case when sw.STATE = 'WAITING' then ' 正在等待 ...'
when sw.state = 'WAITED UNKNOWN TIME' then ' 等待完成 , 但时间很短 '
when sw.state = 'WAITED SHORT TIME' THEN ' 等待完成 , 但时间更短 '
when sw.state = 'WAITED KNOWN TIME' then ' 等待完成 , 等待时间 ( 单位 10ms)' ||sw.wait_time end state_memo,
case when sw.STATE = 'WAITING' then sw.SECONDS_IN_WAIT else 0 end seconds_in_wait,
sw.WAIT_TIME,
case when sw.WAIT_TIME = - 1 then ' 等待完成 , 最后一次等待时间小于 10ms...'
when sw.WAIT_TIME = - 2 then ' 等待完成 , 统计时间未置为可用 '
when sw.WAIT_TIME > 0 then ' 等待完成 , 最后一次等待时间 ( 单位 10ms)' ||sw.WAIT_TIME
when sw.WAIT_TIME = 0 then ' 正在等待 ' end wait_time_memo,
st.PIECE,
st.SQL_TEXT,
sw.P1TEXT,sw.p1, sw.P2TEXT,sw.p2, sw.P3TEXT, sw.P3
from v$session s, v$session_wait sw, v$sqltext st
Where s.sid = sw.sid
and s.sql_address = st.address(+)
And sw.event not like 'SQl*Net%'
And s.status = 'ACTIVE'
And s.username is not null
order by sw.state,s.sid,st.PIECE;
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;
我们也可以查询 dba_data_files 以确定等待的文件的 file_name ,方法是使用 v$session_wait 中的 P1 。
从 v$session_wait 中查询 P3( 原因编码 ) 的值可以知道 session 等待的原因。原因编码的范围从 0 到 300 ,下列为部分编码所代表的事项:
0 块被读入缓冲区。
100 我们想要 NEW( 创建 ) 一个块,但这一块当前被另一 session 读入。
110 我们想将当前块设为共享,但这一块被另一 session 读入,所以我们必须等待 read() 结束。
120 我们想获得当前的块,但其他人已经将这一块读入缓冲区,所以我们只能等待他人的读入结束。
130 块被另一 session 读入,而且没有找到其它协调的块,所以我们必须等待读的结束。缓冲区死锁后这种情况也有可能产生。所以必须读入块的 CR 。
200 我们想新创建一个 block ,但其他人在使用,所以我们只好等待他人使用结束。
210 Session 想读入 SCUR 或 XCUR 中的块,如果块交换或者 session 处于非连续的 TX 模式,所以等待可能需要很长的时间。
220 在缓冲区查询一个块的当前版本,但有人以不合法的模式使用这一块,所以我们只能等待。
230 以 CR/CRX 方式获得一个块,但块中的更改开始并且没有结束。
231 CR/CRX 扫描找到当前块,但块中的更改开始并且没有结束。
6.4 跟踪长时间运行 session 的 10046 事件
1, 使用 sql_trace 跟踪当前 session 的 10046 事件
SQL> alter session set sql_trace = true;
Session altered
SQL> select 1 from dual;
1
SQL> alter session set sql_trace = false;
Session altered
2, 使用 set events 跟踪当前 session 的 10046 事件
SQL> alter session set events '10046 trace name context forever,level 12';
Session altered
SQL> select 2 from dual;
2
----------
2
SQL> alter session set events '10046 trace name context off';
Session altered
3, 使用 oradebug 跟踪当前 session 的 10046 事件
例如我们查看 PID = 487432 的进程 , 可以使用下面的方法 .
# su - oracle
[YOU HAVE NEW MAIL]
$ sqlplus /nolog
SQL*Plus: Release 10.2.0.3.0 - Production on Tue Jul 14 17:24:42 2009
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
SQL> conn / as sysdba
Connected.
SQL> oradebug setospid 487432
Oracle pid: 12, Unix process pid: 487432, image: oracle@i2db (MMNL)
SQL> oradebug event 10046 trace name context forever,level 8
Statement processed.
SQL> oradebug tracefile_name
/oracle/admin/arpdb/bdump/arpdb_mmnl_487432.trc
SQL> oradebug event 10046 trace name context off
Statement processed.
SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
$ tkprof /oracle/admin/arpdb/bdump/arpdb_mmnl_487432.trc
output = arpdb_mm1.txt
TKPROF: Release 10.2.0.3.0 - Production on Tue Jul 14 17:31:29 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
查看更多关于六,监控当前数据库的活动session的详细内容...