oracle查看历史session

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle查看历史session相关的知识,希望对你有一定的参考价值。

参考技术A

一、如何查询session执行的历史sql语句

如何知道一个session都执行过哪些SQL语句?(查看当前比较容易,历史的呢?怎么复原sql的执行场景——事务关系、执行序列、单SQL还是存储过程)

【方法一】查询v$sqltext、v$sqlarea、v$sqlstats视图

select * from v$sqlarea t where t.PARSING_SCHEMA_NAME in (\'schema\') order by t.LAST_ACTIVE_TIME desc;

#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。

#v$sqlstats信息保留时间比v$sql、v$sqltext、v$sqlarea长,及时SQL已经换出shared pool仍然可查到

【方法二】

联合v$active_session_history和v$sqlarea

#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。

#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。

查看视图:dba_hist_sqlstats、dba_hist_sqltext(历史数据)

二、如何使用PL/SQL Developer查看和杀掉session

oracle多用户操作有时候会造成session阻塞,形成了锁表等问题。

可以使用sql语句进行查询,但用工具更为方便。本文就介绍使用PL/SQL developer工具查看或杀掉oracle的session。

工具/原料 PL/SQL Developer 版本为 8.0.0.1480 方法/步骤 打开PL/SQL Developer,输入用户名密码和数据库等信息。 在工具栏中选择tools,在弹出的窗口选择Sessions。

即可。 如图所示,所有的session和起sid都列了出来,我们需要找Status为active(活动)的。

点击一下即可,或者选择如图的下拉菜单,选择 Active sessions. 如图,现在有两个活动的session,选择其中一个session后在下方可以查看此session的更多信息。 在SQL Text一栏中可以查看正在执行的sql语句。

在Locks一栏中,可以查看现在锁表等信息。 若要杀掉其中一个session,那么,对这个session一行点击右键,选择“kill”即可。

三、如何查看PL/SQL执行的历史

除了PL/SQL的ctrl+e的查看方法外还有如下方法:【方法一】查询v$sql、v$sqltext、v$sqlarea、v$sqlstats视图select * from v$sqlarea t where t.PARSING_SCHEMA_NAME in (\'schema\') order by t.LAST_ACTIVE_TIME desc;#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。

#v$sqlstats反应的是实例启动起来的sql执行统计,sql语句本身比v$sqltext/area完整,因为后者有可能失效换出缓存。【方法二】联合v$active_session_history和v$sqlarea#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。

所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。

#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。从v$sqlstat可以查看到数据库启动起来的所有SQL信息,但是没有时间顺序关系、没有执行用户信息,只有执行次数与资源统计。

从dba_hist_sqlstat可以看到AWR snapshot之间的SQL统计信息,与v$sqlstats比不受实例重启的影响,因为实例重启之后v$sqlstats中的信息就清除了。【方法三:session trace】SQL> execute dbms_session.session_trace_enable(true,true);PL/SQL procedure successfully pleted.SQL> select count(*) from dba_hist_sqltext; COUNT(*)---------- 478SQL> select * from V$sesstat where rownum=1; SID STATISTIC# VALUE---------- ---------- ---------- 134 0 1SQL> execute dbms_session.session_trace_disable;PL/SQL procedure successfully pleted.$ cd $ORACLE_HOME/admin/test/udump$ ls -lrt$ tkprof test_ora_2195620.trc report.txt sys=no explain=no aggregate=yes$ more report.txt --这个文件包括了启停trace之间所有SQL语句的执行信息,执行计划、统计【方法四:logminer】只包含DML与DDL语句,不能查询select语句。

另外需要开启supplemental logging,默认是没有开启的。conn / as sysdba--安装LOGMINERSQL> @$ORACLE_HOME/rdbms/admin/dbmslmd.sql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslm.sql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslms.sql;SQL> @$ORACLE_HOME/rdbms/admin/prvtlm.plb;--开启附加日志alter database add supplemental log data;--模拟DML操作conn p_chenming/。

SQL> select * from test2;SQL> insert into test2 values(7,77);SQL> mit;conn / as sysdba--切归档SQL> alter system switch logfile;SQL> select name,dest_id,thread#,sequence# from v$archived_log; --最后一个即为新的归档--新建LOG MINERSQL> execute dbms_logmnr.add_logfile(logfilename=>\'/oracle/archive_10g/test/test_1_138_786808434.arc\',options=>dbms_logmnr.new); --开始minerSQL> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);--查看结果SQL> col username format a8;SQL> col sql_redo format a50 SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where table_name=\'TEST2\'; SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where username=\'P_CHENMING\'; --关闭MINERSQL> execute dbms_logmnr.end_logmnr;--关闭辅助日志SQL> alter database drop supplemental log data;【总结】查看v$sqlarea只能查看粗略的历史,因为很多SQL是共享的。查看ASH也不全,因为这是采样数据,测试的时候基本没有把SQL查询出来。

查看V$SQLSTATS能看到所有执行过的sql,以及其执行统计,但是没有时序、没有用户信息。查看TRACE应该是最完整的,但需要在执行SQL前开启。

查看logminer不能查看select语句,而且默认的系统没有开启supplementing log,所以能查看的内容有限。或许还有审计的方法可用,我没测试。

每种方法都有各自的缺陷,看来很难有一种完备的查看SQL执行历史的方法。

四、如何查看PL/SQL执行的历史

除了PL/SQL的ctrl+e的查看方法外还有如下方法:【方法一】查询v$sql、v$sqltext、v$sqlarea、v$sqlstats视图select * from v$sqlarea t where t.PARSING_SCHEMA_NAME in (\'schema\') order by t.LAST_ACTIVE_TIME desc;#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。

#v$sqlstats反应的是实例启动起来的sql执行统计,sql语句本身比v$sqltext/area完整,因为后者有可能失效换出缓存。【方法二】联合v$active_session_history和v$sqlarea#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。

所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。

#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。从v$sqlstat可以查看到数据库启动起来的所有SQL信息,但是没有时间顺序关系、没有执行用户信息,只有执行次数与资源统计。

从dba_hist_sqlstat可以看到AWR snapshot之间的SQL统计信息,与v$sqlstats比不受实例重启的影响,因为实例重启之后v$sqlstats中的信息就清除了。【方法三:session trace】SQL> execute dbms_session.session_trace_enable(true,true);PL/SQL procedure successfully pleted.SQL> select count(*) from dba_hist_sqltext; COUNT(*)---------- 478SQL> select * from V$sesstat where rownum=1; SID STATISTIC# VALUE---------- ---------- ---------- 134 0 1SQL> execute dbms_session.session_trace_disable;PL/SQL procedure successfully pleted.$ cd $ORACLE_HOME/admin/test/udump$ ls -lrt$ tkprof test_ora_2195620.trc report.txt sys=no explain=no aggregate=yes$ more report.txt --这个文件包括了启停trace之间所有SQL语句的执行信息,执行计划、统计【方法四:logminer】只包含DML与DDL语句,不能查询select语句。

另外需要开启supplemental logging,默认是没有开启的。conn / as sysdba--安装LOGMINERSQL> @$ORACLE_HOME/rdbms/admin/dbmslmd.sql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslm.sql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslms.sql;SQL> @$ORACLE_HOME/rdbms/admin/prvtlm.plb;--开启附加日志alter database add supplemental log data;--模拟DML操作conn p_chenming/。

SQL> select * from test2;SQL> insert into test2 values(7,77);SQL> mit;conn / as sysdba--切归档SQL> alter system switch logfile;SQL> select name,dest_id,thread#,sequence# from v$archived_log; --最后一个即为新的归档--新建LOG MINERSQL> execute dbms_logmnr.add_logfile(logfilename=>\'/oracle/archive_10g/test/test_1_138_786808434.arc\',options=>dbms_logmnr.new); --开始minerSQL> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);--查看结果SQL> col username format a8;SQL> col sql_redo format a50 SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where table_name=\'TEST2\'; SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where username=\'P_CHENMING\'; --关闭MINERSQL> execute dbms_logmnr.end_logmnr;--关闭辅助日志SQL> alter database drop supplemental log data;【总结】查看v$sqlarea只能查看粗略的历史,因为很多SQL是共享的。查看ASH也不全,因为这是采样数据,测试的时候基本没有把SQL查询出来。

查看V$SQLSTATS能看到所有执行过的sql,以及其执行统计,但是没有时序、没有用户信息。查看TRACE应该是最完整的,但需要在执行SQL前开启。

查看logminer不能查看select语句,而且默认的系统没有开启supplementing log,所以能查看的内容有限。或许还有审计的方法可用,我没测试。

每种方法都有各自的缺陷,看来很难有一种完备的查看SQL执行历史的方法。

五、如何查看oracle中存储过程执行的历史记录

select t.sql_id,

t.sql_text,

s.plan_hash_value,

s.optimizer_cost,

s.executions_total,

s.elapsed_time_total,

s.disk_reads_total,

s.buffer_gets_total

from DBA_HIST_SQLSTAT s, DBA_HIST_SQLTEXT t

where s.sql_id=t.sql_id

and t.sql_text like\'%存储过程名称%\';

没有想到其他好办法,确实不太好查了,把存储过程当作SQL来查找吧。

六、oracle 中查询占用session最多的进程

在故障发生时,尝试用下面的语句抓取数据库引起故障的点。

/*********************************************************************************************/在oracle中监控死锁/*********************************************************************************************/SELECT sn.username, m.SID, sn.SERIAL#, m.TYPE, DECODE(m.lmode, 0, \'None\', 1, \'Null\', 2, \'Row Share\', 3, \'Row Excl.\', 4, \'Share\', 5, \'S/Row Excl.\', 6, \'Exclusive\', lmode, LTRIM(TO_CHAR(lmode, \'990\'))) lmode, DECODE(m.request, 0, \'None\', 1, \'Null\', 2, \'Row Share\', 3, \'Row Excl.\', 4, \'Share\', 5, \'S/Row Excl.\', 6, \'Exclusive\', request, LTRIM(TO_CHAR(m.request, \'990\'))) request, m.id1, m.id2 FROM v$session sn, v$lock m WHERE (sn.SID = m.SID AND m.request != 0) --存在锁请求,即被阻塞 OR (sn.SID = m.SID --不存在锁请求,但是锁定的对象被其他会话请求锁定 AND m.request = 0 AND lmode != 4 AND (id1, id2) IN (SELECT s.id1, s.id2 FROM v$lock s WHERE request != 0 AND s.id1 = m.id1 AND s.id2 = m.id2)) ORDER BY id1, id2, m.request; /*********************************************************************************************/定位引起oracle死锁的sql/*********************************************************************************************/select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object)) /*********************************************************************************************/下面的SQL查询可以用于确定锁住数据库对象的锁:/*********************************************************************************************/select c.owner, c.object_name, c.object_type, b.sid, b.serial#, b.status, b.osuser, b.machine from v$locked_object a , v$session b, dba_objects c where b.sid = a.session_id and a.object_id = c.object_id; /*********************************************************************************************/显示哪些会话被锁住/*********************************************************************************************//* showlock.sql */COLUMN o_name format a10COLUMN lock_type format a20COLUMN object_name format a15SELECT RPAD (oracle_username, 10) o_name, session_id SID, DECODE (locked_mode, 0, \'None\', 1, \'Null\', 2, \'Row share\', 3, \'Row Execlusive\', 4, \'Share\', 5, \'Share Row Exclusive\', 6, \'Exclusive\' ) lock_type, object_name, xidusn, xidslot, xidsqn FROM v$locked_object, all_objectsWHERE v$locked_object.object_id = all_objects.object_id;/*********************************************************************************************/显示所有的TM和TX锁/*********************************************************************************************//* showalllock.sql */SELECT SID, TYPE, id1, id2, DECODE (lmode, 0, \'None\', 1, \'Null\', 2, \'Row share\', 3, \'Row Exclusive\', 4, \'Share\', 5, \'Share Row Exclusive\', 6, \'Exclusive\' ) lock_type, request, ctime, BLOCK FROM v$lockWHERE TYPE IN (\'TX\', \'TM\');/*********************************************************************************************/ 在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: 被kill掉的session,状态会被标记为killed,Oracle会在该用户下一次touch时清除该进程.我们发现当一个session被kill掉以后,该session的paddr被修改,如果有多个session被kill,那么多个session的paddr都被更改为相同的进程地址:/*********************************************************************************************/alter system kill session \'sid,serial#\' ; /*********************************************************************************************/ 在oracle中kill掉的进程有时还需要等待pmon回滚数据库已经占有的资源有时候我们需要使用下面的脚本找出那些已经在oracle中kill掉的进程,在操作系统中在kill一次/*********************************************************************************************/select p.addr from v$process p where pid 1 minus select s.paddr from v$session s;$ kill -9 &paddr。

查看历史会话等待事件对应的session信息

此处以enq: TX - row lock contention等待时间为例。

如果在此回话发生在awr快照信息默认的保存天数以内。
可以通过如下sql查询到相关的session信息。
select * from DBA_HIST_ACTIVE_SESS_HISTORY where event like ‘%enq: TX - row lock contention%‘

DBA_HIST_ACTIVE_SESS_HISTORY 中的blocking_session字段关联DBA_HIST_ACTIVE_SESS_HISTORY中的session_id找到对应的sql_id从而得到回话信息。

可以通过如下查询直接获取信息:
select t.instance_number,
       t.sample_time,
       lpad(‘-‘, 2 * (level - 1), ‘-‘) || t.client_id,
       t.session_id,
       t.blocking_session,
       t.session_serial#,
       t.sql_id,
       t.event,
       t.session_state,
       level,
       connect_by_isleaf,
       connect_by_iscycle
  from dba_hist_active_sess_history  t
 where snap_id between 36878 and 36879
 start with blocking_session is not null
        and event like ‘enq: TX - row lock contention%‘
connect by nocycle sample_time = prior sample_time
       and session_id = prior blocking_session
       and session_serial# = prior blocking_session_serial#


其中blocking session为正在阻塞该回话的session


实战案例:
查看等待事件为行锁的session
select a.snap_id,
       a.sql_id,
       a.session_id,
       a.session_serial#,
       a.blocking_session,
       a.blocking_session_serial#,
       a.blocking_session_status
  from DBA_HIST_ACTIVE_SESS_HISTORY a
 where event like ‘%enq: TX - row lock contention%‘
   and snap_id between 20399 and 20400


编写子查询,查看阻塞回话,并统计阻塞次数
select a.blocking_session,
       a.blocking_session_serial#,
       count(a.blocking_session)
  from DBA_HIST_ACTIVE_SESS_HISTORY a
 where event like ‘%enq: TX - row lock contention%‘
   and snap_id between 20399 and 20400
 group by a.blocking_session, a.blocking_session_serial#
 order by 3 desc
 
查看阻塞回话的sql_id和被阻塞的sql_id,条件为阻塞大于19次的
select distinct b.sql_id,c.blocked_sql_id
  from DBA_HIST_ACTIVE_SESS_HISTORY b,
       (select a.sql_id as blocked_sql_id,
       a.blocking_session,
               a.blocking_session_serial#,
               count(a.blocking_session)
          from DBA_HIST_ACTIVE_SESS_HISTORY a
         where event like ‘%enq: TX - row lock contention%‘
           and snap_id between 20399 and 20400
         group by a.blocking_session, a.blocking_session_serial#,a.sql_id
        having count(a.blocking_session) > 19
         order by 3 desc) c
 where b.session_id = c.blocking_session
   and b.session_serial# = c.blocking_session_serial#
   and b.snap_id between 20399 and 20400

以上是关于oracle查看历史session的主要内容,如果未能解决你的问题,请参考以下文章

查看oracle 用户执行的sql语句历史记录

Oracle查看历史执行计划

plsql可以连接上,历史ip 端口都是对的,但是weblogic创建数据源连接失败是啥原因呢?

pl/sql查看锁表及解锁

mysql查看历史命令

查看JDK的历史版本