【SQL】歷史SQL監控(Historical SQL Monitoring ) 功能(12c)

  • 2020 年 3 月 26 日
  • 筆記

概述

Oracle 11g版本 推出了實時SQL監控功能(Real-Time SQL Monitoring),用於實時地監視執行中SQL的性能;Oracle 12c 對其進一步進行了擴展,推出了歷史SQL監控功能(Historical SQL Monitoring)。

該功能類似於ASH資訊的履歷管理(DBAHISTACTIVESESSHISTORY),通過後台進程定期地把SQL的監視資訊保存到資料庫表中,以供事後分析SQL相關的問題。

歷史SQL監控使用的例子

首先通過以下歷史SQL監控使用的例子來初步了解一下該功能。

測試例:(12.1.0.2.0) 1.準備數據

SQL> conn /as sysdba  Connected.  SQL> create user teacherwhat identified by teacherwhat;User created.SQL> grant dba to teacherwhat;Grant succeeded.SQL> conn teacherwhat/teacherwhat  Connected.  SQL> create table SQLMON(a varchar2(3),b varchar2(10),c varchar2(5));Table created.SQL>  begin   for i in 1..1000   loop   insert into SQLMON values('A', i, 'A');   insert into SQLMON values('B', i, 'B');   end loop;   end;  /  2    3    4    5    6    7    8  PL/SQL procedure successfully completed.SQL> create index SQLMON_I on SQLMON(a,b,c);Index created.SQL> exec dbms_stats.gather_table_stats(OWNNAME => NULL, TABNAME => 'SQLMON', CASCADE => TRUE);PL/SQL procedure successfully completed.

2.執行監視對象SQL文

--通過指定/*+ MONITOR */ Hint 使執行SQL成為SQL monitor功能監視對象  SQL> select/*+ MONITOR */ count(*) from SQLMON where a='A'; COUNT(*)  ----------       1000

3.查看實時SQL監控的結果 (同11g)

SQL> SELECT sql_id, hash_value, substr(sql_text,1,40) sql_text  FROM  v$sql  WHERE sql_text like 'select/*+ MONITOR */ count(*)%';  2    3  SQL_ID        HASH_VALUE  ------------- ----------  SQL_TEXT  --------------------------------------------------------------------------------  bq20d7r8f6qa6 3504560454  select/*+ MONITOR */ count(*) from SQLMOSQL> SET LONG 1000000  SQL> SET LONGCHUNKSIZE 1000000  SQL> SET LINESIZE 1000  SQL> SET PAGESIZE 0  SQL> SET TRIM ON  SQL> SET TRIMSPOOL ON  SQL> SET ECHO OFF  SQL> SET FEEDBACK OFF  SQL>  SQL> SELECT DBMS_SQLTUNE.report_sql_monitor(sql_id => 'bq20d7r8f6qa6', type => 'TEXT') AS report FROM dual;  SQL Monitoring ReportSQL Text  ------------------------------  select/*+ MONITOR */ count(*) from SQLMON where a='A'Global Information  ------------------------------  Status              :  DONE (ALL ROWS)  Instance ID         :  1  Session             :  TEACHERWHAT (237:24669)  SQL ID              :  bq20d7r8f6qa6  SQL Execution ID    :  16777216  Execution Started   :  08/25/2016 21:07:26  First Refresh Time  :  08/25/2016 21:07:26  Last Refresh Time   :  08/25/2016 21:07:26  Duration            :  .000518s  Module/Action       :  SQL*Plus/-  Service             :  SYS$USERS  Program             :  sqlplus@db12102 (TNS V1-V3)  Fetch Calls         :  1Global Stats  =======================================  | Elapsed |  Other   | Fetch | Buffer |  | Time(s) | Waits(s) | Calls |  Gets  |  =======================================  |    0.00 |     0.00 |     1 |     12 |  =======================================SQL Plan Monitoring Details (Plan Hash Value=1559208047)  =================================================================================================================================  | Id |        Operation        |   Name   |  Rows   | Cost |   Time    | Start | Execs |   Rows   | Activity | Activity Detail |  |    |                         |          | (Estim) |      | Active(s) | Active |       | (Actual) |   (%)    |   (# samples)   |  =================================================================================================================================  |  0 | SELECT STATEMENT        |          |         |      |         1 |     +0 |     1 |        1 |          |                 |  |  1 |   SORT AGGREGATE        |          |       1 |      |         1 |     +0 |     1 |        1 |          |                 |  |  2 |    INDEX FAST FULL SCAN | SQLMON_I |    1000 |    3 |         1 |     +0 |     1 |     1000 |          |                 |  =================================================================================================================================

4.查看歷史SQL監控報告的結果

可以通過視圖DBAHISTREPORTS和DBAHISTREPORTSDETAILS來查看歷史的SQL監控結果,也可以通過DBMSAUTOREPORT.REPORTREPOSITORY_DETAIL包查看結果。

DBA_HIST_REPORTS        :SQL Monitor、DBOP、Real-Time ADDM等報告的資訊  DBA_HIST_REPORTS_DETAILS:各個報告的纖細資訊

4.1 通過SQLID或者時間等其他條件,DBAHISTREPORTS中查找歷史SQL監控報告的REPORTID。

SQL> SET LINESIZE 1000  SQL> col sql_id format a20  SQL> col sql_exec_id format a20  SQL> col sql_exec_start format a20  SQL> SELECT report_id, key1 sql_id, key2 sql_exec_id, key3 sql_exec_start   FROM dba_hist_reports where key1 ='bq20d7r8f6qa6';  2  REPORT_ID SQL_ID               SQL_EXEC_ID          SQL_EXEC_START  ---------- -------------------- -------------------- --------------------         20 bq20d7r8f6qa6        16777216             08:25:2016 21:07:26

4.2.通過DBMSAUTOREPORT.REPORTREPOSITORYDETAIL包來顯示查看實時SQL監控結果。

---通過指定REPORT_ID來獲得歷史SQL監控報告。  SQL> set long 10000000 longchunksize 10000000 pages 0 LINESIZE 1000  SQL> SELECT DBMS_AUTO_REPORT.REPORT_REPOSITORY_DETAIL(RID => 20, TYPE => 'text') FROM dual;  SQL Monitoring ReportSQL Text  ------------------------------  select/*+ MONITOR */ count(*) from SQLMON where a='A'Global Information  ------------------------------  Status              :  DONE (ALL ROWS)  Instance ID         :  1  Session             :  TEACHERWHAT (237:24669)  SQL ID              :  bq20d7r8f6qa6  SQL Execution ID    :  16777216  Execution Started   :  08/25/2016 21:07:26  First Refresh Time  :  08/25/2016 21:07:26  Last Refresh Time   :  08/25/2016 21:07:26  Duration            :  .000518s  Module/Action       :  SQL*Plus/-  Service             :  SYS$USERS  Program             :  sqlplus@db12102 (TNS V1-V3)  Fetch Calls         :  1Global Stats  =======================================  | Elapsed |  Other   | Fetch | Buffer |  | Time(s) | Waits(s) | Calls |  Gets  |  =======================================  |    0.00 |     0.00 |     1 |     12 |  =======================================SQL Plan Monitoring Details (Plan Hash Value=1559208047)  =================================================================================================================================  | Id |        Operation        |   Name   |  Rows   | Cost |   Time    | Start  | Execs |   Rows   | Activity | Activity Detail |  |    |                         |          | (Estim) |      | Active(s) | Active |       | (Actual) |   (%)    |   (# samples)   |  =================================================================================================================================  |  0 | SELECT STATEMENT        |          |         |      |         1 |     +0 |     1 |        1 |          |                 |  |  1 |   SORT AGGREGATE        |          |       1 |      |         1 |     +0 |     1 |        1 |          |                 |  |  2 |    INDEX FAST FULL SCAN | SQLMON_I |    1000 |    3 |         1 |     +0 |     1 |     1000 |          |                 |  =================================================================================================================================

通過上面的方法,我們可以對某些過去的SQL進行查看,這對某些問題的事後調查非常有用。

下面我們進一步了解該功能

關於"Automatic Report Capturing"

歷史SQL監控(Historical SQL Monitoring ) 功能是12c新功能"Automatic Report Capturing"的一部分,通過MMON_SLAVE後台進程定期地把實時SQL監控的資訊保存到資料庫的相關表中。

下面我們通過以下測試,進一步了解一下這個動作。

測試:(12.1.0.2.0 Single Instance)

1.對MMON_SLAVE的'Automatic Report Flush'動作設置SQL Trace。

SQL> set line 180  SQL> col PRIMARY_ID format a20  SQL> col QUALIFIER_ID1 format a20  SQL>  SQL> select trace_type, primary_id, qualifier_id1, waits, binds from DBA_ENABLED_TRACES;no rows selectedSQL> exec dbms_monitor.serv_mod_act_trace_enable -  (service_name=>'SYS$BACKGROUND',-  module_name=>'MMON_SLAVE',-  action_name=>'Automatic Report Flush',-  waits => true, -  binds => true);> > > > >PL/SQL procedure successfully completed.SQL> select trace_type, primary_id, qualifier_id1, waits, binds from DBA_ENABLED_TRACES;TRACE_TYPE            PRIMARY_ID           QUALIFIER_ID1        WAITS BINDS  --------------------- -------------------- -------------------- ----- -----  SERVICE_MODULE_ACTION SYS$BACKGROUND       MMON_SLAVE           TRUE  TRUE

2.查看trace路徑,可以看到每隔一分鐘系統生成一個Mxxx的跟蹤文件。

[oracle@db12102 trace]$ pwd  /u01/app/oracle/diag/rdbms/ora12102/ora12102/trace  [oracle@db12102 trace]$ ls -larth  total 192K  drwxr-x--- 16 oracle oinstall 4.0K Apr 10 20:18 ..  -rw-r-----  1 oracle oinstall  137 Aug 26 12:15 ora12102_m001_7311.trm  -rw-r-----  1 oracle oinstall 8.6K Aug 26 12:15 ora12102_m001_7311.trc  -rw-r-----  1 oracle oinstall   56 Aug 26 12:16 ora12102_m001_7317.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:16 ora12102_m001_7317.trc  -rw-r-----  1 oracle oinstall   83 Aug 26 12:17 ora12102_m001_7332.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:17 ora12102_m001_7332.trc  -rw-r-----  1 oracle oinstall   83 Aug 26 12:18 ora12102_m001_7340.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:18 ora12102_m001_7340.trc  -rw-r-----  1 oracle oinstall   73 Aug 26 12:19 ora12102_m001_7355.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:19 ora12102_m001_7355.trc  ...  -rw-r-----  1 oracle oinstall   83 Aug 26 12:36 ora12102_m001_7501.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:36 ora12102_m001_7501.trc  -rw-r-----  1 oracle oinstall   73 Aug 26 12:37 ora12102_m001_7508.trm  -rw-r-----  1 oracle oinstall 2.2K Aug 26 12:37 ora12102_m001_7508.trc  drwxr-x---  2 oracle oinstall  12K Aug 26 12:37 .[oracle@db12102 trace]$  

3.查看Mxxx的跟蹤文件的內容,我們可以看到執行的操作內容。

[oracle@db12102 trace]$ tkprof ora12102_m001_7508.trc ora12102_m001_7508.out  [oracle@db12102 trace]$ cat ora12102_m001_7508.out

Mxxx進程執行的SQL如下(整形後):

SELECT sql_id,        sql_exec_id,        dbop_name,        dbop_exec_id,        To_char(sql_exec_start, 'mm:dd:yyyy hh24:mi:ss'),        To_char(first_refresh_time, 'mm:dd:yyyy    hh24:mi:ss'),        To_char(last_refresh_time, 'mm:dd:yyyy hh24:mi:ss'),        elapsed_time,        px_servers_allocated,        sid,        session_serial#,        KEY,        con_id  FROM   v$sql_monitor  WHERE  report_id = 0        AND status != 'EXECUTING'        AND status != 'QUEUED'        AND px_qcsid IS NULL        AND last_refresh_time >                (SELECT Nvl(last_cycle_time, sysdate - ( 5 / 1440 ))                  FROM v$sys_report_stats);

根據上面的內容,我們可以發現,在默認的情況下,MMON_SLAVE後台進程會作以下的工作:

・每隔1分鐘檢查實時SQL監控資訊(v$sql_monitor視圖)。  ・保存對象為:不是正在執行也也不在排隊的 SQL。

4.接著測試,執行監視對象SQL文然後查看跟蹤文件中的內容。

SQL> conn teacherwhat/teacherwhat  Connected.  SQL> select/*+ MONITOR */ count(*) from SQLMON where a='A'; COUNT(*)  ----------       1000SQL> SET LINESIZE 1000  col sql_id format a20  col sql_exec_id format a20  col sql_exec_start format a20SQL> SQL> SQL>  SQL> SELECT report_id, key1 sql_id, key2 sql_exec_id, key3 sql_exec_start           FROM dba_hist_reports where key1 ='bq20d7r8f6qa6';  2  REPORT_ID SQL_ID               SQL_EXEC_ID          SQL_EXEC_START  ---------- -------------------- -------------------- --------------------         20 bq20d7r8f6qa6        16777216             08:25:2016 21:07:26         21 bq20d7r8f6qa6        16777217             08:26:2016 13:10:41 ★

5.查看相關的跟蹤文件,我們可以看到,當發現相關的實時SQL監控的資訊需要保存到資料庫表中時,Oracle會調用sys.dbmsautoreportinternal.isavereport的程式包把相關資訊保存到相關的內部表(WRP$REPORTS、WRP$REPORTSDETAILS)中。

具體動作如下:

BEGIN sys.dbms_auto_report_internal.i_save_report (:rep_ref, :snap_id,   :pr_class,                                              :rep_id, :suc);   END;INSERT INTO WRP$_REPORTS ...INSERT INTO WRP$_REPORTS_DETAILS ...INSERT INTO WRP$_REPORTS_TIME_BANDS ...

其中,wrp$表的更新即反映為如下的相關的視圖:

・DBA_HIST_REPORTS ← INT$DBA_HIST_REPORTS ← wrp$_reports  ・DBA_HIST_REPORTS_DETAILS ← INT$DBA_HIST_REPORTS_DETAILS ← wrp$_reports_detail  

相關視圖和程式包

歷史SQL監控的相關視圖主要包括以下

DBA_HIST_REPORTS_CONTROL:報告的相關控制資訊  DBA_HIST_REPORTS        :SQL Monitor、DBOP、Real-Time ADDM等報告的資訊  DBA_HIST_REPORTS_DETAILS:各個報告的詳細資訊

通過DBAHISTREPORTS_CONTROL視圖的內容我們可以知道,歷史SQL監控報告的模式可以分為2種:

REGULAR模式     :根據DB時間預算,每隔一分鐘捕獲一次  FULL_CAPTURE模式:不考慮DB時間預算,每隔一分鐘捕獲一次,捕獲更多的資訊。   /開啟FULL_CAPTURE模式     SQL> exec DBMS_AUTO_REPORT.START_REPORT_CAPTURE;   /關閉FULL_CAPTURE模式     SQL> exec DBMS_AUTO_REPORT.FINISH_REPORT_CAPTURE;

參考: Database Reference 12c >DBAHISTREPORTS_CONTROL

列EXECUTION_MODE:Mode of execution of automatic report capture. Possible values:   REGULAR: Regular per-minute report capture subject to DBTIME budget   FULL_CAPTURE: Report capture will be run per minute without the DBTIME budget constraints and is provided to capture a more comprehensive set of reportsNOTE: The FULL_CAPTURE mode can be started and ended respectively by executing the START_REPORT_CAPTURE and FINISH_REPORT_CAPTURE APIs in the DBMS_AUTO_REPORT package. At all other times, the execution mode should be REGULAR.

參考: Database Reference 12c

>DBAHISTREPORTS_CONTROL >DBAHISTREPORTS >DBAHISTREPORTS_DETAILS

另外,和這個功能密切相關的程式包DBMSAUTOREPORT,也可參考在線文檔。

Database PL/SQL Packages and Types Reference >31 DBMSAUTOREPORT

相關參數

我們可以通過下面的方法查看歷史SQL監控功能(Historical SQL Monitoring ) 的相關參數。

SQL> set pagesize 100  SQL> set linesize 200  SQL> col Parameter format a40  SQL> col Description format a35  SQL> col Value format a40  SQL> select a.ksppinm "Parameter",a.KSPPDESC "Description",b.ksppstvl "Value"  from x$ksppi a, x$ksppcv b where a.indx = b.indx and a.ksppinm like '%_report_capture%';   2  Parameter                             Description                         Value  ------------------------------------- ----------------------------------- ---------  _report_capture_cycle_time            Time (in sec) between two cycles of 60                                        report capture daemon_report_capture_dbtime_percent_cutoff 100X Percent of system db time daem 50                                       on is allowed over 10 cycles_report_capture_timeband_length       Length of time band (in hours) in t 1                                       he reports time bands table_report_capture_recharge_window       No of report capture cycles after w 10                                       hich db time is recharged

另外,在很多案例中由於Bug的影響,MMON進程會因為這個功能而消耗大量的CPU以及記憶體,或者發生ORA-12850錯誤(RAC環境)等問題,所以當你遭遇到相關問題時,可以通過設定reportcapturecycletime=0來禁用Automatic Report Capturing功能,從而停止歷史SQL監控(Historical SQL Monitoring ) 功能來迴避相關的問題。

例:  SQL> alter system set "_report_capture_cycle_time"=0;  

參考

Database Reference 12c

>DBAHISTREPORTS_CONTROL

>DBAHISTREPORTS

>DBAHISTREPORTS_DETAILS

Database PL/SQL Packages and Types Reference

>31 DBMSAUTOREPORT

Historical SQL Monitor reports in 12c! https://mauro-pagano.com/2015/05/04/historical-sql-monitor-reports-in-12c/ Top

Executions SQL Monitoring style reports in SQLd360 https://mauro-pagano.com/2016/01/14/top-executions-sql-monitoring-styles-reports-in-sqld360/