• 怎么查看用户的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反应的是实例启动起来的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执行历史的方法。
     
     

    不登高山,怎知天高;不临深溪,焉知地厚!站在坚实的土地上,做着生命中最真实的事情;像一棵挺拔的大树,认可自己的命运并敢于迎接属于这一方天空的风风雨雨。

  • 相关阅读:
    小白专场-堆中的路径-python语言实现
    小白专场-堆中的路径-c语言实现
    集合及运算
    哈弗曼树与哈夫曼编码

    线性结构之习题选讲-ReversingLinkedList
    小白专场-是否同一颗二叉搜索树-python语言实现
    微信公众平台开发教程第1篇-新手解惑(转)
    GIT GUI的使用(转)
    Git操作指南(2) —— Git Gui for Windows的建库、克隆(clone)、上传(push)、下载(pull)、合并(转)
  • 原文地址:https://www.cnblogs.com/net2012/p/2869636.html
Copyright © 2020-2023  润新知