V$SQL_MONITOR 5秒起一秒一次,保留一分钟 OEM工作原理

----------OEM sql monitoring 的sql------- 

GOAL

How to view the same information from a target database without going through OEM performance to monitor SQL performance:

OEM > targets > databases >select a target database> click on performance. sql monitoring>


 

SOLUTION

Queries are derived from the view V$SQL_MONITOR for OEM, and inbuilt query.

Use query something like below:

select sid, sql_id, sql_exec_id, to_char(sql_exec_start,'DD-Mon-YY HH24:MI:SS') sql_exec_start, sql_plan_hash_value plan_hash_value,

elapsed_time  buffer_gets, disk_reads

from v$sql_monitor

where sql_id like nvl('&sql_id',sql_id)

----- purge records from v$Sql_monitor

Why does one database have more records in V$Sql_monitor compared to another database, and how to purge records from v$Sql_monitor?
 

SOLUTION


There are two important parameters which control the number of records in V$Sql_Monitor:

1. _sqlmon_max_plan: Default = 20 per CPU(Default). This parameter controls how many SQLs can be monitored which means that at any point of time "select distinct(sql_id) from v$SQL_MONITOR does not return more than 20 * Num.of.Cpu on the server where this DB is hosted"


2. _sqlmon_max_planlines: Default = 300(Default). When a statement exceeds that many lines, it does not get monitored by SQL Monitor, so if length of query is more than 300 lines, it will not be monitored

SQL monitor has a mechanism to recycle entries that correspond to old SQL executions, as long as there is not enough memory to allocate new ones. If the Database SGA size is quite large, then the code that recycles them does not kick in. This results in entries which keep adding up in V$sql_monitor.
 

There is currently no workaround to reduce the number of records(purge records) in v$sql_monitor other than bouncing the DB. If you have more records in V$sql_monitor than you see many rows for each sql_id, plan_hash_value combination is that we also use a timestamp (execution start time) in each row. So if a SQL is executed multiple times, it is expected that you will see many rows for that SQL in v$sql_monitor.

As a side note it is now possible to flush entries from v$sql_monitor with the following command taken from Document 2792268.1:

alter session set events 'immediate sqlmon_dump(level=23)';

------生成  dbms_sqltune.report_sql_monitor

GOAL

This document explains how to enable Explain Plan, SQL tuning, Statistics and Tuning Advisor from the OWB mapping editor for SQL within the mapping.
 

SOLUTION

For analysis of set based SQL from the design environment, there were some changes in Warehouse Builder 10.2.0.3 that included the ability to obtain access explain plans/statistics/tuning advisor from within the mapping editor for SQL within the mapping.

In order to utilize statistics and SQL Tuning, the following additional privileges are required :

  1. For statistics the following must be granted to the schema the mapping is being deployed to:
     

    SQL> connect SYS as SYDBA

    SQL>grant select on V_$SQL_PLAN to <TARGET_SCHEMA>;

    SQL>grant select on V_$SQL_PLAN_STATISTICS_ALL to <TARGET_SCHEMA>;

    SQL>grant select on V_$SQL to <TARGET_SCHEMA>;


     
  2. For SQL Tuning the advisor role is required:
     

    SQL> grant advisor to <target_schema>;

If  runtime analysis of SQL is required, the Oracle Database Release 11g has introduced a new performance view called v$sql_monitor. The v$sql_monitor view can be used for near real-time monitoring of SQL statements.
Please note that view can be used when the Enterprise Manager Tuning Pack is licensed. SQL monitoring is automatically started when a SQL statement runs parallel or when it has consumed at least 5 seconds of CPU or I/O time.

In Oracle Database Release 11g the way to get output in a readable format is through PL/SQL or grid control:

variable my_rept clob;
begin
:my_rept := dbms_sqltune.report_sql_monitor() ;
end ;
/
print :my_rept


Full documentation for v$sql_monitor can be found in the Database Reference and the Database Performance Tuning Guide.

-------并行的 "Servers Requested" and "Servers Allocated" 显示bug

When viewing details of a particular query, (which is executed high number of times), from SQL Monitor, very high values are seen for "Servers Requested" and "Servers Allocated" in the "Parallel Execution Details".
For example:

SH@dw23> SET LONG 1000000
SH@dw23> SET LONGCHUNKSIZE 1000000
SH@dw23> SET LINESIZE 1000
SH@dw23> SET PAGESIZE 0
SH@dw23> SELECT DBMS_SQLTUNE.report_sql_monitor(sql_id => <SQL ID>, type => 'TEXT',report_level=>'ALL') AS report FROM dual;
SQL Monitoring Report

SQL Text
------------------------------
SELECT * FROM (SELECT /*+ parallel(4) */ a.column1, b.column2....<rest of the query>

Global Information
------------------------------
Status              :  DONE (ALL ROWS)
Instance ID         :  1
Session             :  SYS (510:56699)
SQL ID              :  62ujw625atm4d
SQL Execution ID    :  16777218
Execution Started   :  01/04/2024 11:59:45
First Refresh Time  :  01/04/2024 11:59:45
Last Refresh Time   :  01/04/2024 12:00:00
Duration            :  15s
Module/Action       :  sqlplus@.... (TNS V1-V3)/-
Service             :  SYS$USERS
Program             :  sqlplus@.... (TNS V1-V3)
DOP Downgrade       :  3%
Fetch Calls         :  5

Global Stats
=====================================================================================
| Elapsed |   Cpu   |    IO    | PL/SQL  |  Other   | Fetch | Buffer | Read | Read  |
| Time(s) | Time(s) | Waits(s) | Time(s) | Waits(s) | Calls |  Gets  | Reqs | Bytes |
=====================================================================================
|    6.80 |    0.58 |     0.00 |    0.00 |     6.21 |     5 |  59121 |    3 | 24576 |
=====================================================================================

Parallel Execution Details (DOP=4 , Servers Requested=10600 , Servers Allocated=10296)
                                                      ^^^^                       ^^^^ 

.............

The Degree of Parallelism (DOP) however is set correctly to 4, as chosen in the PARALLEL Hint for the query.

The DOP downgrade is also listed as just 3% but we see:

Servers Requested=10600
Servers Allocated=10296

This document explains why the values for "Servers Requested" and "Servers Allocated" are shown as such high values.

CHANGES

CAUSE

This was investigated in an internal / unpublished Bug 11898399 - V$SQL_MONITOR REPORTS WRONG NUMBER OF PQ SLAVE SERVERS VALUE

DEV clarified that this is an expected behaviour. In the SQL Monitor report or v$sql_monitor view, the two columns - PX_SERVERS_REQUESTED (Servers Requested) and PX_SERVERS_ALLOCATED (Servers Allocated) are used to track how many PQ severs have been allocated in total. Each time a parallelizer row source executes, it potentially allocates new slaves and these slaves are potentially released during the next execution of this parallelizer.

Hence, these stats will keep increasing with each execution.

SOLUTION

The high values do not imply that these many PX slaves have been allocated for "each" execution. The difference between the servers allocated and requested is not high and there is also no high DOP downgrade seen, in the above case.

To monitor the PX executions, you can also use the steps listed provided in:

  How to Monitor the Parallel Statement Queue (Doc ID 1684985.1)
  Script To Monitor Parallel Queries/SQL (Doc ID 457857.1)

-------------------------EM13c, EM12c: How to Obtain The Data For The "Top Activity" Graph from SQL query ? (Doc ID 2635069.1)

GOAL

To get the Top Activity data for a specific target database using SQL query
 

SOLUTION

The following query can be used by Enterprise Manager (EM) Cloud Control Agent to fetch data for Top Activity page:


SELECT sql_id, sql_exec_id, session_id, session_serial, status, round((last_refresh - sql_exec_start )*24*60*60) duration, elapsed_time, cpu_time, user_io_wait_time, cluster_wait_time, application_wait_time, other_wait_time, nvl(dop,0) dop, inst_count FROM ( SELECT mo5.* FROM ( SELECT mo4.sql_id sql_id, mo4.sql_exec_start sql_exec_start, mo4.sql_exec_id sql_exec_id, (select sq.sql_text from v$sql sq where sq.sql_id = mo4.sql_id and rownum = 1) sql_fulltext, mo4.sql_plan_hash_value plan_hash_value, max(mo4.status) status, max(case when mo4.px_qcsid is null then mo4.sid else null end) session_id, max(case when mo4.px_qcsid is null then mo4.session_serial# else null end) session_serial, max(mo4.first_refresh_time) first_refresh, max(mo4.last_refresh_time) last_refresh, count(distinct mo4.inst_id) inst_count, max(case when mo4.px_server_group = 1 and mo4.px_server_set = 1 then mo4.px_server# else NULL end) dop, sum(mo4.fixed_elapsed_time) elapsed_time, sum(mo4.cpu_time) cpu_time, sum(mo4.application_wait_time) application_wait_time, sum(mo4.cluster_wait_time) cluster_wait_time, sum(mo4.user_io_wait_time) user_io_wait_time, sum(mo4.other_wait_time) other_wait_time FROM (SELECT mo1.*, case when (nvl(mo1.cpu_time, 0)+ nvl(mo1.application_wait_time,0)+ nvl(mo1.cluster_wait_time, 0)+ nvl(mo1.user_io_wait_time, 0)) > nvl(mo1.elapsed_time, 0) then (nvl(mo1.cpu_time, 0)+ nvl(mo1.application_wait_time,0)+ nvl(mo1.cluster_wait_time, 0)+ nvl(mo1.user_io_wait_time, 0)) else mo1.elapsed_time end fixed_elapsed_time, case when (nvl(mo1.cpu_time, 0)+ nvl(mo1.application_wait_time,0)+ nvl(mo1.cluster_wait_time, 0)+ nvl(mo1.user_io_wait_time, 0)) > nvl(mo1.elapsed_time, 0) then 0 else mo1.elapsed_time - (nvl(mo1.cpu_time, 0)+ nvl(mo1.application_wait_time,0)+ nvl(mo1.cluster_wait_time, 0)+ nvl(mo1.user_io_wait_time, 0)) end other_wait_time FROM (select * from gv$sql_monitor mo0 where mo0.INST_ID = userenv('INSTANCE') or PX_QCINST_ID is not null) mo1, (SELECT distinct mo2.sql_id, mo2.sql_exec_start, mo2.sql_exec_id FROM v$sql_monitor mo2 WHERE mo2.px_qcsid is null ) mo3 WHERE mo1.sql_id = mo3.sql_id AND mo1.sql_exec_start = mo3.sql_exec_start AND mo1.sql_exec_id = mo3.sql_exec_id) mo4 GROUP BY mo4.sql_id, mo4.sql_exec_start, mo4.sql_exec_id, mo4.sql_plan_hash_value ORDER BY last_refresh desc, mo4.sql_id ) mo5 WHERE mo5.sql_fulltext is not null ORDER BY mo5.elapsed_time desc) WHERE ROWNUM <= 5;

-------------sql_id will only show the top level user cursor ( if any). 难表述

GOAL

In 11.2, SQL_ID column of V$session view doesn't have any values for some sessions, Why is that happening?

SOLUTION

From 10.2 onwards sql_id will only show the top level user cursor ( if any).

Sometimes,Session does a plsql rpc call ie a client ( eg forms client) can request a plsql object to be executed at the server. In this case there is no top level sql and as such we don't see the sql_id in v$session.

Currently, Oracle does not store the current sql thru any v$ views. The only way to find that is thru event 10046.
This is covered in Unpublished bug 5528670: "NULL VALUES FOR SQL_ID, SQL_HASH_VALUE, SQL_ADDRESS AND OTHERS IN V$SESSION", Which was closed as "Not a Bug".

------并行session 某个session 空闲超过30分钟

SYMPTOMS

  • Running DBMS_SQLTUNE.REPORT_SQL_MONITOR
    For example:

    SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(SESSION_ID=>&1,
                  SESSION_SERIAL=>&2,    
                  INST_ID=>&3,
                  report_level=>'ALL',
                  type =>'ACTIVE') as report 

      
  • Query is running in parallel (PX)
  • After 30 minutes V$SQL_MONITOR.STATUS shows DONE(ERROR) even though the query is still running

CHANGES

CAUSE

This was filed under Bug 13523091 INCORRECT STATUS IN V$SQL_MONITOR WITH PARALLEL QUERY and closed as not a bug

The DONE(ERROR) occurs when one of the parallel slaves has been inactive for more than 30 minutes.
When MMON finds out that an entry that has active plan is idle for more than 30 minutes, it marks the entry as possible for reclamation with potential error. It is marked as error because there could have been an error in this plan that MMON was unable to detect,
considering that it is spending such a long time (30 minutes) as "idle". 
If there are no other errors during the execution the monitor report will be correct and will contain all the usual information.
The error does not indicate that SQL monitoring failed, nor does it indicate that the monitored SQL failed.

Following are the possible statuses for V$SQL_MONITOR.STATUS:

  • QUEUED - SQL statement is queued
  • EXECUTING - SQL statement is still executing
  • DONE (ERROR) - Execution terminated with an error
  • DONE (FIRST N ROWS) - Execution terminated by the application before all rows were fetched
  • DONE (ALL ROWS) - Execution terminated and all rows were fetched
  • DONE - Execution terminated (parallel execution)

SOLUTION

This is expected behavior for parallel queries where one (or more) of the slaves are inactive for more than 30 minutes.

---How to monitor long running operations i.e "insert", "move", "create index" etc (Doc ID 2821878.1) 监控并行session 进度

APPLIES TO:

Oracle Database - Enterprise Edition - Version 11.2.0.1 and later
Information in this document applies to any platform.

GOAL

 Monitor the long running jobs i.e. insert, move, create index etc

SOLUTION

 1/- Identify the size of "table" / "table partition" participating in operation

       SQL> select /* parallel 4 */ count(*) from demo partition(future);

        COUNT(*)
       ----------
       64000000

       SQL>

2/- Identify the SQL_ID of the  interested running job

       set lines 200
       col sql_text format a110
       select sql_id,substr(sql_text,0,110) sql_text from v$sql_monitor where status='EXECUTING';

       Example:

       SQL> set lines 200
       SQL> col sql_text format a110
       SQL> select sql_id,substr(sql_text,0,110) sql_text from v$sql_monitor where status='EXECUTING';
       SQL_ID SQL_TEXT
       ------------- --------------------------------------------------------------------------------------------------------------
       2x3k24vzu66sz insert /* parallel 4 */ into t13 select /* parallel 4 */* from demo partition(future)

3/- Update the below script with 

          -- Out put of the query 1
          -- running SQL_ID

                   select distinct to_char(a.sql_exec_start,'DD/MM/YYYY HH24:MI:SS') start_time ,
                   plan_parent_id,
                   plan_operation "Operation",
                   trunc(elapsed_time/1000000,0) "TimeElapsed(seconds)",a.output_rows "No of rows processed",
                   trunc((a.output_rows/<OUTPUT from QUERY 1>)*100,2) "Progress%"
                   from v$sql_plan_monitor a ,v$sql_monitor b
                   where a.status not like '%DONE%'
                   and a.key = b.key
                   and a.output_rows <>0
                   and b.sql_id='<SQL_ID from Query 2>'
                   order by plan_operation;

 Example:

      SQL> select distinct to_char(a.sql_exec_start,'DD/MM/YYYY HH24:MI:SS') start_time ,plan_parent_id,
       plan_operation "Operation",
       trunc(elapsed_time/1000000,0) "TimeElapsed(seconds)",a.output_rows "No of rows processed",
       trunc((a.output_rows/64000000)*100,2) "Progress%"
       from v$sql_plan_monitor a ,v$sql_monitor b
       where a.status not like '%DONE%'
       and a.key = b.key
       and a.output_rows <>0
       and b.sql_id='2x3k24vzu66sz'
       order by plan_operation;
      
      START_TIME          PLAN_PARENT_ID Operation                      TimeElapsed(seconds) No of rows processed Progress%
      ------------------- -------------- ------------------------------ -------------------- -------------------- ----------
      16/11/2021 11:47:25    1              PARTITION RANGE                77                    23216816            36.27
      16/11/2021 11:47:25    2              TABLE ACCESS                   77                    23216816            36.27

      SQL> /

      START_TIME          PLAN_PARENT_ID  Operation                      TimeElapsed(seconds) No of rows processed Progress%
      ------------------- -------------- ------------------------------  -------------------- -------------------- ----------
      16/11/2021 11:47:25    1              PARTITION RANGE                83                    25125915            39.25
      16/11/2021 11:47:25    2              TABLE ACCESS                   83                    25125915            39.25

      SQL> /

      START_TIME          PLAN_PARENT_ID   Operation                     TimeElapsed(seconds) No of rows processed Progress%
      ------------------- -------------- ------------------------------ -------------------- -------------------- ----------
      16/11/2021 11:47:25   1               PARTITION RANGE                191                   57981661             90.59
      16/11/2021 11:47:25   2               TABLE ACCESS                   191                   57981661             90.59

      SQL>

GOAL

All active SQL statements are not seen in OEM 13c - SQL Monitoring while it is shown in V$session.
 

SOLUTION

Not all SQL will be 'monitored' in SQL Monitoring

This is expected behavior. If the SQL takes less than 5 seconds to execute, it will not be seen in v$sql_monitor:

Oracle Database Online Documentation 11g Release 1 (11.1)
Database Administration

V$SQL_MONITOR


The sql statistics for SQL command execution can be monitored by using the V$SQL_MONITOR and V$SQL_PLAN_MONITOR views. After monitoring is initiated, an entry is added to the V$SQL_MONITOR dynamic performance view. These statistics are refreshed in near real time as the command executes, generally once every second. When the SQL statement being monitored is executing, statistics in V$SQL_MONITOR are generally refreshed in near real time, once every second. Once the execution ends, monitoring information is not deleted immediately. Instead, it is kept in V$SQL_MONITOR for at least one minute. The entry will eventually be deleted to reclaim its space as new statements are monitored.

So your SQL may be aged out before you look at it. Remember that OEM information is not real-time. It is collected by the agents and then batched up and eventually shown on the OEM screens.
 

Things to remember

1. Also make sure statistics_level =ALL or TYPICAL and control_management_pack_access = DIAGNOSTIC+TUNING

2. If a specific SQL needs to be monitored,  use the monitoring hint /*+ MONITOR */

Why does v$session contains information about all sessions unlike SQL Monitoring

V$sessions is used by the system to track all sessions so it must contain information about all sessions. It is also real-time, as the system has to rely on it. The monitoring views and tables are for monitored SQLs. This is not all sessions. Secondly monitoring information is not kept for ever. It will be aged out.

Thirdly OEM will always have a lag in it because it has to collect the information batch it up and then present it. OEM (Cloud Control) is NOT real time, like v$session.

Example scenario where the SQL is not shown

11:00:00   SQL starts and takes 20 seconds. Some information is in V$session as this process is active. No information is in any monitored tables. Nothing is shown by OEM. Agent collects information.
11:00:20   It will be collected by monitoring (as it is over 5 seconds).
11:01:20   One minute later the SQL has aged out from monitoring (worst case scenario). If the statement was in the top 20 for the snapshot interval it will go into the history but it wasn't so it does not go into the history.----top20 才去历史
11:15:00   The agent makes another collection of information to see what is being monitored. The SQL monitoring information is not there. Nothing relating to the statement is sent to OEM.

In the scenario above, the test SQL will not show in the monitored SQL in OEM. After 2 minutes it will also not be present in the Monitoring tables. At the time it was running, the information will be present in v$session.

This is the purpose of the "monitoring" hints --to force monitoring of a SQL statement even if it is below the 5 seconds.

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值