Reference: http://blog.csdn.net/xiaoxu0123/article/details/38846685html

Reference: http://blog.sina.com.cn/s/blog_4a80a5730101oxnk.html

Reference: http://blog.csdn.net/fycghy0803/article/details/16845575

Reference: https://www.cnblogs.com/net2012/archive/2013/01/21/2869636.html

1、查看Oracle执行过的SQL语句:

SELECT * FROM V$SQLAREA T ORDER BY T.LAST_ACTIVE_TIME DESC;

或者

SELECT * FROM v$sqlarea WHERE PARSING_SCHEMA_NAME='GAVIN' and SQL_TEXT LIKE '%delete%' ORDER BY LAST_ACTIVE_TIME

2、查看Oracle会话

SELECT * FROM V$SESSION T ORDER BY T.LAST_ACTIVE_TIME DESC;

3、查看Oracle的权限角色

select   *   from   dba_role_privs;    授予用户和其他角色的角色   
select   *   from   dba_sys_privs;     授予用户和其他角色的系统权限   
select   *   from   dba_tab_privs;     数据库中对象的所有授权
select   *   from   user_role_privs;   查看当前用户的角色
ORACLE中能够经过v$session表查看当前有效的session信息,而且能够经过v$session的sql_id或sql_address经过关联查询v$sql查看当前正在执行的sql语句;session
若是想查看session近期执行的sql语句,能够经过v$active_session_history表中的sql_id查看近期历史执行的sql语句,要求数据库的liberary没有被fresh。性能
SELECT b.sql_text,                    --content of SQL
         a.machine,                     --which machine run this code
         a.username, a.module,          -- the method to run this SQL
         c.sofar / totalwork * 100,     --conplete percent
         c.elapsed_seconds,             --run time
        c.time_remaining               --remain to run time
FROM v$session a, v$sqlarea b, v$session_longops c
WHERE a.sql_hash_value = b.hash_value(+) AND a.SID = c.SID(+)
              AND a.serial# = c.serial#(+)
       --AND a.sid=139

Oracle 最近执行过的sql语句:

SELECT   sql_text, last_load_time
FROM v$sql
WHERE last_load_time IS NOT NULL
ORDER BY last_load_time DESC

其它:

SELECT sql_text,last_load_time FROM v$sql order by last_load_time desc;
SELECT   sql_text, last_load_time FROM v$sql WHERE last_load_time IS NOT NULL and sql_text like 'select%' ORDER BY last_load_time DESC;
SELECT   sql_text, last_load_time FROM v$sql WHERE last_load_time IS NOT NULL and sql_text like 'update%' ORDER BY last_load_time DESC;
SELECT   sql_text, last_load_time FROM v$sql WHERE last_load_time IS NOT NULL and last_load_time like' 14-06-09%' ORDER BY last_load_time DESC;

监控concurrent 正在执行的sql

SELECT a.sid, a.serial#, b.sql_text
  FROM v$session a, v$sqltext b
WHERE a.sql_address = b.address
  --AND a.sid = <...>
ORDER BY b.piece

正在执行的

SELECT a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT
 FROM v$session a, v$sqlarea b 
where a.sql_address = b.address

执行过的

SELECT b.SQL_TEXT,b.FIRST_LOAD_TIME,b.SQL_FULLTEXT
FROM v$sqlarea b
WHERE b.FIRST_LOAD_TIME between '2009-10-15/09:24:47' and
       '2009-10-15/09:24:47' order by b.FIRST_LOAD_TIME

(此方法好处能够查看某一时间段执行过的sql,而且 SQL_FULLTEXT 包含了完整的 sql 语句)

其余

SELECT OSUSER,PROGRAM,USERNAME,SCHEMANAME,B.Cpu_Time,STATUS,B.SQL_TEXT 
FROM V$SESSION A LEFT JOIN V$SQL B ON A.SQL_ADDRESS=B.ADDRESS AND A.SQL_HASH_VALUE=B.HASH_VALUE ORDER BY b.cpu_time desc
SELECT address, sql_text, piece 
FROM v$session, v$sqltext 
WHERE address = sql_address 
  -- and machine = < you machine name > 
ORDER BY address, piece

查找前十条性能差的sql

SELECT * FROM (SELECT PARSING_USER_ID,EXECUTIONS,SORTS, 
COMMAND_TYPE,DISK_READS,sql_text FROM v$sqlarea 
ORDER BY disk_reads DESC )WHERE ROWNUM<10 ;

查看占io较大的正在运行的session

SELECT se.sid,se.serial#,pr.SPID,se.username,se.status, 
se.terminal,se.program,se.MODULE,se.sql_address,st.event,st. 
p1text,si.physical_reads, 
si.block_changes FROM v$session se,v$session_wait st, 
v$sess_io si,v$process pr WHERE st.sid=se.sid AND st. 
sid=si.sid AND se.PADDR=pr.ADDR AND se.sid>6 AND st. 
wait_time=0 AND st.event NOT LIKE '%SQL%' ORDER BY physical_reads DESC

问题:如何知道一个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反应的是实例启动起来的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 completed.
 
SQL> select count(*) from dba_hist_sqltext;
 
  COUNT(*)
----------
       478
 
SQL> select * from V$sesstat where rownum=1;
 
       SID STATISTIC#      VALUE
---------- ---------- ----------
       134          0          1
 
SQL> execute dbms_session.session_trace_disable();
PL/SQL procedure successfully completed.

$ 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
--安装LOGMINER
SQL> @$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> commit;
 
conn / as sysdba
--切归档
SQL> alter system switch logfile;
SQL> select name,dest_id,thread#,sequence# from v$archived_log; --最后一个即为新的归档
 
--新建LOG MINER
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/oracle/archive_10g/test/test_1_138_786808434.arc',options=>dbms_logmnr.new); 
--开始miner
SQL> 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,scn,timestamp,sql_redo from v$logmnr_contents where table_name='TEST2'; 
SQL> select username,scn,timestamp,sql_redo from v$logmnr_contents where username='P_CHENMING'; 
--关闭MINER
SQL> 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执行历史的方法。
最后修改:2022 年 07 月 10 日
如果觉得我的文章对你有用,请随意赞赏