2026-03-12 20:23:15

This commit is contained in:
root
2026-03-12 21:23:47 +01:00
parent eab4b36eca
commit 93039b8489
3332 changed files with 699614 additions and 0 deletions

7
Kevin_Meade/afiedt.buf Normal file
View File

@@ -0,0 +1,7 @@
SELECT column_id,
column_name,
histogram
FROM user_tab_columns
WHERE table_name = 'R3'
ORDER BY column_id
/

View File

@@ -0,0 +1,97 @@
--
-- load qep information into the plan_table from gv$sql_plan
--
-- requires you to identify the inst_id,sql_id,child_number first
--
-- parameter 1 = inst_id
-- parameter 2 = sql_id
-- parameter 3 = child_number
--
-- @loadplanfromcache11g.sql 1 6zcb0r0rch025 0
--
-- then use the normal plan_table scripts to get the goodness
--
-- @showplan11g
-- @showplandatamodel11g
-- ...
--
insert into plan_table
(
PLAN_ID
,TIMESTAMP
,REMARKS
,OPERATION
,OPTIONS
,OBJECT_NODE
,OBJECT_OWNER
,OBJECT_NAME
,OBJECT_ALIAS
,object_instance
,OBJECT_TYPE
,OPTIMIZER
,SEARCH_COLUMNS
,ID
,PARENT_ID
,DEPTH
,POSITION
,COST
,CARDINALITY
,BYTES
,OTHER_TAG
,PARTITION_START
,PARTITION_STOP
,PARTITION_ID
,OTHER
,OTHER_XML
,DISTRIBUTION
,CPU_COST
,IO_COST
,TEMP_SPACE
,ACCESS_PREDICATES
,FILTER_PREDICATES
,PROJECTION
,TIME
,QBLOCK_NAME
)
select
nvl((select max(plan_id) from plan_table),0)+1 plan_id
,TIMESTAMP
,REMARKS
,OPERATION
,OPTIONS
,OBJECT_NODE
,OBJECT_OWNER
,OBJECT_NAME
,OBJECT_ALIAS
,OBJECT# object_instance
,OBJECT_TYPE
,OPTIMIZER
,SEARCH_COLUMNS
,ID
,PARENT_ID
,DEPTH
,POSITION
,COST
,CARDINALITY
,BYTES
,OTHER_TAG
,PARTITION_START
,PARTITION_STOP
,PARTITION_ID
,OTHER
,OTHER_XML
,DISTRIBUTION
,CPU_COST
,IO_COST
,TEMP_SPACE
,ACCESS_PREDICATES
,FILTER_PREDICATES
,PROJECTION
,TIME
,QBLOCK_NAME
from gv$sql_plan
where inst_id = &&1
and sql_id = '&&2'
and child_number = &&3
/

View File

@@ -0,0 +1,103 @@
--
-- load qep information into the plan_table from DBA_HIST_SQL_PLAN (history of monitored plans)
--
-- requires you to identify the sql_id and date of when you want your plan
-- does a bob barker lookup based on the date, for the sql_id supplied
-- note use of +1 second to the date in order to account for the millseconds in the timestamp
-- note also the use of a specific format mask 'rrrrmmddhh24miss'
-- often you will need to guess about the time unless you know it from some other place
--
-- parameter 1 = sql_id
-- parameter 2 = timestamp (in the right format)
--
-- @loadplanfromhist11g.sql 6zcb0r0rch025 2014080212:10:03
--
-- then use the normal plan_table scripts to get the goodness
--
-- @showplan11g
-- @showplandatamodel11g
-- ...
--
insert into plan_table
(
PLAN_ID
,TIMESTAMP
,REMARKS
,OPERATION
,OPTIONS
,OBJECT_NODE
,OBJECT_OWNER
,OBJECT_NAME
,OBJECT_ALIAS
,object_instance
,OBJECT_TYPE
,OPTIMIZER
,SEARCH_COLUMNS
,ID
,PARENT_ID
,DEPTH
,POSITION
,COST
,CARDINALITY
,BYTES
,OTHER_TAG
,PARTITION_START
,PARTITION_STOP
,PARTITION_ID
,OTHER
,OTHER_XML
,DISTRIBUTION
,CPU_COST
,IO_COST
,TEMP_SPACE
,ACCESS_PREDICATES
,FILTER_PREDICATES
,PROJECTION
,TIME
,QBLOCK_NAME
)
select
nvl((select max(plan_id) from plan_table),0)+1 plan_id
,TIMESTAMP
,REMARKS
,OPERATION
,OPTIONS
,OBJECT_NODE
,OBJECT_OWNER
,OBJECT_NAME
,OBJECT_ALIAS
,OBJECT# object_instance
,OBJECT_TYPE
,OPTIMIZER
,SEARCH_COLUMNS
,ID
,PARENT_ID
,DEPTH
,POSITION
,COST
,CARDINALITY
,BYTES
,OTHER_TAG
,PARTITION_START
,PARTITION_STOP
,PARTITION_ID
,OTHER
,OTHER_XML
,DISTRIBUTION
,CPU_COST
,IO_COST
,TEMP_SPACE
,ACCESS_PREDICATES
,FILTER_PREDICATES
,PROJECTION
,TIME
,QBLOCK_NAME
from dba_hist_sql_plan
where sql_id = '&&1'
and timestamp = (
select max(timestamp)
from dba_hist_sql_plan
where sql_id = '&&1'
and timestamp <= to_date('&&2','rrrrmmddhh24miss')+1/24/60/60
)
/

View File

@@ -0,0 +1,113 @@
--
-- show have fast scan operations
-- (sorting / hashing / table scans / index scans) will take
--
-- provides a MB/second metric that can be used to compare different systems
-- has plenty of flaws yet still works great
--
-- also provides an expected end time for the operation
-- though this can be misleading
--
-- usage is: @SHOWALLSCANRATES
--
--clear breaks
--clear computes
--clear columns
col time_remaining head 'Seconds|Remaining'
col scanned_blocks head 'Scanned Blocks|or Indexes'
col all_blocks head 'All Blocks|or Indexes'
col blocks_remaining head 'Blocks|or Indexes|Remaining' noprint
col opname format a16
col target format a40
col username format a15
col MB_per_Second form 990.0 head 'MB/s'
col pct_scanned head '%Scanned' format 990.00
col predicted_runtime_seconds head 'Estmd.|Runtime|Seconds'
col total_blocks head 'Total|Blocks|or|Indexes'
col sid format 99990
col block_size format 99990 head 'Block|Size'
col id_passes_temp format a25
break on inst_id skip page
with
scan_data as (
select
to_number(
substr(a.message
,instr(a.message,': ',1,2)+2
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
)
)
/ to_number(
substr(a.message
,instr(a.message,' out of ',1,1)+8
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
)
) *100 pct_scanned
, to_number(
substr(a.message
,instr(a.message,' out of ',1,1)+8
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
)
)
- to_number(
substr(a.message
,instr(a.message,': ',1,2)+2
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
)
) blocks_remaining
, a.time_remaining
, a.opname
, to_number(b.value) block_size
, a.target
, a.sid
, a.inst_id
, a.username
, a.sql_hash_value
from (
select
replace(gv$session_longops.message,'RMAN:','RMAN') message
, gv$session_longops.time_remaining
, gv$session_longops.opname
, nvl(gv$session_longops.target,replace(gv$session_longops.target_desc,'Table ')) target
, gv$session_longops.sid
, gv$session_longops.inst_id
, gv$session_longops.username
, gv$session_longops.sql_hash_value
from gv$session_longops
, gv$session
where gv$session_longops.sid = gv$session.sid
and gv$session_longops.inst_id = gv$session.inst_id
and gv$session_longops.sid = gv$session.sid
and gv$session_longops.serial# = gv$session.serial#
and gv$session_longops.time_remaining > 0
) a
,(select value from gv$parameter where name = 'db_block_size' and rownum = 1) b
)
select
scan_data.inst_id
, round(blocks_remaining*block_size/1024/1024/time_remaining,1) MB_per_Second
, scan_data.time_remaining
, round(time_remaining/(1-pct_scanned/100)) predicted_runtime_seconds
, scan_data.pct_scanned
, scan_data.blocks_remaining
, round(blocks_remaining/(1-pct_scanned/100)) total_blocks
, scan_data.opname
, scan_data.BLOCK_SIZE
, scan_data.target
, (
select
max(operation_id)||':'||DECODE(MAX(NUMBER_PASSES),0,'OPTIMAL',1,'ONE-PASS',NULL,NULL,'MULTI-PASS('||max(number_passes)||')')||DECODE(max(TEMPSEG_SIZE),NULL,NULL,','||round(max(TEMPSEG_SIZE)/1024/1024)||'M')
from gv$sql_workarea_active
where gv$sql_workarea_active.sid = scan_data.sid
and gv$sql_workarea_active.inst_id = scan_data.inst_id
-- and scan_data.opname in ('Hash Join','Sort Output')
-- and gv$sql_workarea_active.OPERATION_TYPE in ('HASH-JOIN','SORT','WINDOW (SORT)','GROUP BY (SORT)')
) id_passes_temp
, scan_data.sid
, scan_data.username
, scan_data.sql_hash_value
from scan_data
order by inst_id,username,sid,time_remaining
/

View File

@@ -0,0 +1,12 @@
--
-- show work areas in use
--
col SQL_EXEC_START noprint
col SQL_EXEC_ID noprint
col WORKAREA_ADDRESS noprint
col OPERATION_TYPE format a20 trunc
col active_time noprint
col expected_size noprint
select * from gv$sql_workarea_active;

View File

@@ -0,0 +1,76 @@
--
-- show all column stats for columns in the specified table
-- requires the function KEV_RAW_TO_STRING
-- very usefull for looking at column recorded HIGH/LOW
--
-- parameter 1 = owner
-- parameter 2 = table_name
--
-- usage is: @SHOWCOLSTATS <owner> <table_name>
--
/*
CREATE OR replace FUNCTION kev_raw_to_string (rawval RAW, TYPE VARCHAR2) RETURN VARCHAR2
IS
cn NUMBER;
cv VARCHAR2(32);
cd DATE;
cnv NVARCHAR2(32);
cr ROWID;
cc CHAR(32);
BEGIN
IF ( TYPE = 'NUMBER' ) THEN
dbms_stats.Convert_raw_value(rawval, cn);
RETURN '"'||cn||'"';
ELSIF ( TYPE = 'VARCHAR2' ) THEN
dbms_stats.Convert_raw_value(rawval, cv);
RETURN '"'||cv||'"';
ELSIF ( TYPE = 'DATE' ) THEN
dbms_stats.Convert_raw_value(rawval, cd);
RETURN '"'||to_char(cd,'dd-mon-rrrr.hh24:mi:ss')||'"';
ELSIF ( TYPE = 'NVARCHAR2' ) THEN
dbms_stats.Convert_raw_value(rawval, cnv);
RETURN '"'||cnv||'"';
ELSIF ( TYPE = 'ROWID' ) THEN
dbms_stats.Convert_raw_value(rawval, cr);
RETURN '"'||cnv||'"';
ELSIF ( TYPE = 'CHAR' ) THEN
dbms_stats.Convert_raw_value(rawval, cc);
RETURN '"'||cc||'"';
ELSE
RETURN '"UNSUPPORTED DATA_TYPE"';
END IF;
exception when others then
return '--- conversion error ---';
END;
/
*/
col low_value format a30
col high_value format a30
col last_analyzed format a22
--select table_name,column_name, num_distinct, num_nulls, num_buckets, sample_size,last_analyzed
select
OWNER
, TABLE_NAME
, COLUMN_NAME
, NUM_DISTINCT
, NUM_NULLS
, NUM_BUCKETS
, SAMPLE_SIZE
, AVG_COL_LEN
, DENSITY
, TO_CHAR(LAST_ANALYZED,'dd-mon-rrrr.hh24:mi:ss') last_analyzed
, GLOBAL_STATS
, USER_STATS
, km21378.kev_raw_to_string (LOW_VALUE,(select data_type from dba_tab_columns b where b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name)) LOW_VALUE
, km21378.kev_raw_to_string (HIGH_VALUE,(select data_type from dba_tab_columns b where b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name)) HIGH_VALUE
from dba_tab_col_statistics a
where (owner,table_name) in
(
(upper('&&1'),upper('&&2'))
)
--and (column_name = 'ROW_TERM_DATE$' or num_buckets > 1)
order by TABLE_NAME,COLUMN_NAME
/

View File

@@ -0,0 +1,39 @@
--
-- given a table
-- show is PK/UK/FK constraints
-- and FK constraints that point to it
--
-- usage is: @SHOWCONSTRAINTS <owner> <table_name>
--
break on constraint_name skip 1 on parent_table_name
col column_name format a30
col sort_order noprint
col select_id noprint
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,1 select_id
from dba_constraints a
,dba_constraints b
,dba_cons_columns c
where a.owner = upper('&&1')
and a.table_name = upper('&&2')
and a.r_owner = b.owner(+)
and a.r_constraint_name = b.constraint_name(+)
and a.owner = c.owner
and a.constraint_name = c.constraint_name
and a.constraint_type != 'C'
union all
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,2 select_id
from dba_constraints a
,dba_constraints b
,dba_cons_columns c
where b.owner = upper('&&1')
and b.table_name = upper('&&2')
and b.constraint_type in ('P','U')
and a.r_owner = b.owner
and a.r_constraint_name = b.constraint_name
and b.table_name != a.table_name
and a.owner = c.owner
and a.constraint_name = c.constraint_name
order by select_id,sort_order,owner,table_name,constraint_name,column_name
/

View File

@@ -0,0 +1,69 @@
/*
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 1
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 2
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 3
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 4
use this to get a starting point for best combination of columns based on distinct
note this still have the NULLS issue maybe (how do we handle columns with large % of null values)
but ignoring this, the technique is pretty solid
generate code and run it to find out how distinct different combinations of columns are
give some list of columns generate the possible combinations of columns restricted to a limited number (exp. combinations of N things taken M at a time)
results should point you to a good starting set of columns for an index given you list of columns you are intersted in
from this you use GENCARDINALITYCHECKCODE2.SQL
*/
with
table_data as (
select owner,table_name
from dba_tables
where owner = upper('&&1')
and table_name = upper('&&2')
)
, column_list as (
select dba_tab_columns.owner,dba_tab_columns.table_name,dba_tab_columns.column_name
from dba_tab_columns
,table_data
where dba_tab_columns.owner = table_data.owner
and dba_tab_columns.table_name = table_data.table_name
and instr(','||upper('&&3')||',',','||dba_tab_columns.column_name||',') > 0
)
, column_expression as (
select a.*
,length(sys_connect_by_path(a.column_name,','))-length(replace(sys_connect_by_path(a.column_name,','),',')) column_count
,substr(sys_connect_by_path(a.column_name,'||'',''||'),8) column_expression
from column_list a
connect by prior a.column_name < a.column_name
)
select 'clear columns' from dual union all
select 'col column_count newline' from dual union all
select 'col COLUMN_EXPRESSION format a800' from dual union all
select 'set linesize 999' from dual union all
select 'set pagesize 0' from dual union all
select 'set trimspool on' from dual union all
select 'set trimout on' from dual union all
--select 'set feedback off' from dual union all
--select 'set timing off' from dual union all
--select 'set time off' from dual union all
select '--owner table_name rowcount number_of_columns column_combo_cardinality column_expression' from dual union all
select 'select '''||table_data.owner||''' owner,'''||table_data.table_name||''' table_name,count(*) table_rowcount'
from table_data
union all
select *
from (
select ' ,'||column_expression.column_count||' column_count,count(distinct '||column_expression.column_expression||') expression_rowcount,'''||replace(column_expression.column_expression,chr(39),chr(39)||chr(39))||''' column_expression'
from column_expression
where column_count <= &&4
order by column_count,column_expression
)
union all
select 'from '||table_data.owner||'.'||table_data.table_name
from table_data
union all
select '/'
from table_data
/

View File

@@ -0,0 +1,29 @@
--
-- shows the histogram for a specific column
-- very usefull for showing when statistics might not help
--
-- parameter 1 = owner
-- parameter 2 = table_name
-- parameter 3 = column_name
--
-- usage is: @SHOWHISTOGRAM <owner> <table_name> <column_name>
--
COLUMN endpoint_actual_value noprint
COLUMN actual_value ON FORMAT a30
col column format a30
select b.*
,round(ratio_to_report(cardinality) over(partition by owner,table_name,column_name)*100) pct
,endpoint_actual_value actual_value
from (
select a.*
,ENDPOINT_NUMBER-nvl(lag(ENDPOINT_NUMBER) over(partition by owner,table_name,column_name order by endpoint_number),0) cardinality
from dba_histograms a
where owner = upper('&&1')
and table_name = upper('&&2')
and column_name = upper('&&3')
) b
order by owner,table_name,column_name,ENDPOINT_NUMBER
/

View File

@@ -0,0 +1,24 @@
--
-- for the given table
-- list the indexes on the table
--
-- parameter 1 = owner
-- parameter 2 = table_name
--
-- usage is: @SHOWINDEXES <owner> <table_name>
--
set verify off
break on index_name skip 1
col column_name format a30
select index_name,column_name
,(select index_type from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) index_type
,(select uniqueness from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) uniqueness
,(select tablespace_name from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) tablespace_name
from dba_ind_columns a
where table_name = upper('&&2')
and table_owner = upper('&&1')
order by 1,column_position
/

View File

@@ -0,0 +1,101 @@
--clear breaks
--clear computes
--clear columns
col time_remaining head 'Seconds|Remaining'
col scanned_blocks head 'Scanned Blocks|or Indexes'
col all_blocks head 'All Blocks|or Indexes'
col blocks_remaining head 'Blocks|or Indexes|Remaining' noprint
col opname format a16
col target format a40
col username format a15
col MB_per_Second form 990.0 head 'MB/s'
col pct_scanned head '%Scanned' format 990.00
col predicted_runtime_seconds head 'Estmd.|Runtime|Seconds'
col total_blocks head 'Total|Blocks|or|Indexes'
col sid format 99990
col block_size format 99990 head 'Block|Size'
col id_passes_temp format a25
break on inst_id skip page
with
scan_data as (
select
to_number(
substr(a.message
,instr(a.message,': ',1,2)+2
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
)
)
/ to_number(
substr(a.message
,instr(a.message,' out of ',1,1)+8
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
)
) *100 pct_scanned
, to_number(
substr(a.message
,instr(a.message,' out of ',1,1)+8
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
)
)
- to_number(
substr(a.message
,instr(a.message,': ',1,2)+2
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
)
) blocks_remaining
, a.time_remaining
, a.opname
, to_number(b.value) block_size
, a.target
, a.sid
, a.inst_id
, a.username
, a.sql_hash_value
from (
select
replace(gv$session_longops.message,'RMAN:','RMAN') message
, gv$session_longops.time_remaining
, gv$session_longops.opname
, nvl(gv$session_longops.target,replace(gv$session_longops.target_desc,'Table ')) target
, gv$session_longops.sid
, gv$session_longops.inst_id
, gv$session_longops.username
, gv$session_longops.sql_hash_value
from gv$session_longops
, gv$session
where gv$session_longops.sid = gv$session.sid
and gv$session_longops.inst_id = gv$session.inst_id
and gv$session_longops.sid = gv$session.sid
and gv$session_longops.serial# = gv$session.serial#
and gv$session_longops.time_remaining > 0
and gv$session_longops.username = user
) a
,(select value from gv$parameter where name = 'db_block_size' and rownum = 1) b
)
select
scan_data.inst_id
, round(blocks_remaining*block_size/1024/1024/time_remaining,1) MB_per_Second
, scan_data.time_remaining
, round(time_remaining/(1-pct_scanned/100)) predicted_runtime_seconds
, scan_data.pct_scanned
, scan_data.blocks_remaining
, round(blocks_remaining/(1-pct_scanned/100)) total_blocks
, scan_data.opname
, scan_data.BLOCK_SIZE
, scan_data.target
, (
select
max(operation_id)||':'||DECODE(MAX(NUMBER_PASSES),0,'OPTIMAL',1,'ONE-PASS',NULL,NULL,'MULTI-PASS('||max(number_passes)||')')||DECODE(max(TEMPSEG_SIZE),NULL,NULL,','||round(max(TEMPSEG_SIZE)/1024/1024)||'M')
from gv$sql_workarea_active
where gv$sql_workarea_active.sid = scan_data.sid
and gv$sql_workarea_active.inst_id = scan_data.inst_id
-- and scan_data.opname in ('Hash Join','Sort Output')
-- and gv$sql_workarea_active.OPERATION_TYPE in ('HASH-JOIN','SORT','WINDOW (SORT)','GROUP BY (SORT)')
) id_passes_temp
, scan_data.sid
, scan_data.username
, scan_data.sql_hash_value
from scan_data
order by inst_id,username,sid,time_remaining
/

View File

@@ -0,0 +1 @@
select * from gv$sql_workarea_active where (inst_id,sid) in (select inst_id,sid from gv$session where username = user);

12
Kevin_Meade/showowner.sql Normal file
View File

@@ -0,0 +1,12 @@
--
-- given an object name
-- show what schema owns it and what it is
--
col object_name format a30
select owner,object_type,object_name,status
from dba_objects
where object_name = upper('&&1')
order by 1,2,3
/

View File

@@ -0,0 +1,35 @@
col value format a30
col name format a40
col keyword format a10
break on keyword skip 1 dup
select decode(sign(instr(name,'dyn')),1,'dyn'
,decode(sign(instr(name,'size')),1,'size'
,decode(sign(instr(name,'pga')),1,'pga'
,decode(sign(instr(name,'index')),1,'index'
,decode(sign(instr(name,'cpu')),1,'cpu'
,decode(sign(instr(name,'mode')),1,'mode'
,decode(sign(instr(name,'optimizer')),1,'optimizer'
,decode(sign(instr(name,'parallel')),1,'parallel'
,decode(sign(instr(name,'rewrite')),1,'rewrite'
,decode(sign(instr(name,'statistics')),1,'statistics'
)))))))))) keyword
,name
,value
,isdefault
from v$parameter
where (
name like '%dyn%' or
name like '%pga%' or
name like '%area%' or
name like '%index%' or
name like '%cpu%' or
name like '%mode%' or
name like '%optimizer%' or
name like 'parallel%' or
name like '%rewrite%' or
name like '%statistics%'
)
order by keyword,name
/

View File

@@ -0,0 +1,7 @@
--
-- dump the most recent plan from the plan_table
--
-- usage is: @SHOWPLAN11G
--
select * from table(dbms_xplan.display('PLAN_TABLE',NULL,'ADVANCED'));

View File

@@ -0,0 +1,8 @@
--
-- dump the most recent plan in the plan_table
-- but do not include lesser used sections of the plan
--
-- usage is: @SHOWPLAN11GSHORT
--
select * from table(dbms_xplan.display('PLAN_TABLE',NULL,'ADVANCED -projection -outline -alias'));

View File

@@ -0,0 +1,60 @@
--
-- show all PK/UK/FK constraints for any table referenced by most recent query plan in the plan_table
-- note that table references may be indirect and that not all tables in a query need be used by a query plan
--
-- usage is: @SHOWPLANCONSTRAINTS11G
--
break on constraint_name skip 1 on parent_table_name
col column_name format a30
col sort_order noprint
col select_id noprint
with
plan_references as (
select id,object_owner owner,object_name table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table
where object_type = 'TABLE'
and plan_id = (select max(plan_id) from plan_table)
union
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
and a.plan_id = (select max(plan_id) from plan_table)
)
, plan_tables as (
select distinct owner,table_name
from plan_references
)
select *
from (
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type parent_constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,1 select_id
from dba_constraints a
,dba_constraints b
,dba_cons_columns c
where (a.owner,a.table_name) in (select owner,table_name from plan_tables)
and a.r_owner = b.owner(+)
and a.r_constraint_name = b.constraint_name(+)
and a.owner = c.owner
and a.constraint_name = c.constraint_name
and a.constraint_type != 'C'
and (b.owner is null and a.constraint_type in ('P','U') or (b.owner,b.table_name) in (select owner,table_name from plan_tables))
union
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type parent_constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,2 select_id
from dba_constraints a
,dba_constraints b
,dba_cons_columns c
where (a.owner,a.table_name) in (select owner,table_name from plan_tables)
and b.constraint_type in ('P','U')
and a.r_owner = b.owner
and a.r_constraint_name = b.constraint_name
and b.table_name != a.table_name
and a.owner = c.owner
and a.constraint_name = c.constraint_name
and (b.owner,b.table_name) in (select owner,table_name from plan_tables)
)
order by select_id,sort_order,owner,table_name,constraint_name,column_name
/

View File

@@ -0,0 +1,26 @@
--
-- construct count queries for tables referenced by the most recent plan in the plan_table
--
-- usage is: @SHOWPLANCOUNTQUERIES11G
--
select count_query_sqltext||decode(lead(count_query_sqltext) over (order by object_owner,object_name),null,';',' union all') sql_text
from (
select distinct object_owner,object_name,'select count(*) rowcount,'''||object_owner||''' owner,'''||object_name||''' table_name from '||object_owner||'.'||object_name count_query_sqltext
from (
select id,object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
from plan_table
where object_type = 'TABLE'
and plan_id = (select max(plan_id) from plan_table)
union
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
and a.plan_id = (select max(plan_id) from plan_table)
)
order by object_owner,object_name
)
/

View File

@@ -0,0 +1,209 @@
--
-- dumps a crude ascii art data model for the current plan in the plan_table
--
-- usage is: @SHOWPLANDATAMODEL11G
--
with
table_list as (
select b.*,chr(rownum+96) dm_key
from (
select a.*
from (
select object_owner owner,object_name table_name
from plan_table
where object_type = 'TABLE'
and plan_id = (select max(plan_id) from plan_table)
union
select b.table_owner,b.table_name
from plan_table a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
and a.plan_id = (select max(plan_id) from plan_table)
) a
order by a.table_name,a.owner
) b
)
, constraint_data as (
select a.owner,a.table_name,a.constraint_type,a.constraint_name,a.r_owner,a.r_constraint_name
,nvl(b.owner,a.owner) parent_owner,nvl(b.table_name,a.table_name) parent_table_name
,decode(a.constraint_type,'R',a.owner) child_owner,decode(a.constraint_type,'R',a.table_name) child_table_name
from dba_constraints a
,dba_constraints b
where a.constraint_type in ('P','R')
and (a.owner,a.table_name) in (select owner,table_name from table_list)
and a.r_owner = b.owner(+)
and a.r_constraint_name = b.constraint_name(+)
union all
select owner,table_name,'P',null,null,null,null,null,null,null
from table_list a
where not exists (
select null
from dba_constraints b
where b.owner = a.owner
and b.table_name = a.table_name
and b.constraint_type = 'P'
)
)
, table_list_plus as (
select a.owner,a.table_name,listagg(c.dm_key,',') within group (order by c.dm_key) parent_dm_key_list
from table_list a
,constraint_data b
,table_list c
where a.owner = b.child_owner
and a.table_name = b.child_table_name
and b.parent_owner = c.owner
and b.parent_table_name = c.table_name
group by a.owner,a.table_name
)
, table_level as (
select c.*,(ordinal_position)*prefix_spaces+(ordinal_position-1)*3+cumm_table_name_length-length(table_name)+1 start_position
from (
select b.*,trunc((max_total_table_name_length-total_table_name_length)/(table_count+1)) prefix_spaces
from (
select a.*,max(table_count) over () max_table_count,max(total_table_name_length) over() max_total_table_name_length
from (
select owner,table_name,max(lvlno) dm_lvl,max_dm_lvl
,sum(length(table_name)) over (partition by max(lvlno)) total_table_name_length
,count(*) over(partition by max(lvlno)) table_count
,row_number() over(partition by max(lvlno) order by table_name,owner) ordinal_position
,sum(length(table_name)) over (partition by max(lvlno) order by table_name,owner) cumm_table_name_length
from (
select level lvlno,max(level) over () max_dm_lvl,a.*
from constraint_data a
connect by r_owner = prior owner
and r_constraint_name = prior constraint_name
start with r_owner is null
)
group by owner,table_name,max_dm_lvl
) a
) b
) c
)
, table_lines as (
select a.*
from (
select table_level.*,replace(substr(sys_connect_by_path(lpad(' ',prefix_spaces,' ')||table_name,','),2),',',' ') line_text
from table_level
connect by prior dm_lvl = dm_lvl
and prior ordinal_position = ordinal_position - 1
start with ordinal_position = 1
) a
where ordinal_position = table_count
order by dm_lvl
)
, print_array as (
select x.*
,case
when exists (
select null
from table_level b2
,constraint_data c2
,table_level d2
where x.columnno = b2.start_position
and b2.owner = c2.parent_owner
and b2.table_name = c2.parent_table_name
and c2.child_owner = d2.owner
and c2.child_table_name = d2.table_name
and (
x.dm_lvl < d2.dm_lvl-1 or
x.dm_lvl = d2.dm_lvl-1 and x.rowno in (1,2)
)
) then (
select e2.dm_key
from table_level b2
,constraint_data c2
,table_level d2
,table_list e2
where x.columnno = b2.start_position
and b2.owner = c2.parent_owner
and b2.table_name = c2.parent_table_name
and c2.child_owner = d2.owner
and c2.child_table_name = d2.table_name
and (
x.dm_lvl < d2.dm_lvl-1 or
x.dm_lvl = d2.dm_lvl-1 and x.rowno in (1,2)
)
and c2.parent_owner = e2.owner
and c2.parent_table_name = e2.table_name
)
when exists (
select null
from table_level b2
,constraint_data c2
,table_level d2
where x.dm_lvl = b2.dm_lvl-1
and x.rowno in (3)
and b2.owner = c2.child_owner
and b2.table_name = c2.child_table_name
and c2.parent_owner = d2.owner
and c2.parent_table_name = d2.table_name
and (x.columnno between b2.start_position and d2.start_position or
x.columnno between d2.start_position and b2.start_position)
) then '-'
when exists (
select null
from table_level b2
,constraint_data c2
where x.columnno = b2.start_position
and b2.owner = c2.child_owner
and b2.table_name = c2.child_table_name
and x.dm_lvl = b2.dm_lvl-1
and x.rowno in (4,5)
) then (
select decode(x.rowno,4,'|','| ('||f2.parent_dm_key_list||')')
from table_level b2
,constraint_data c2
,table_list_plus f2
where x.columnno = b2.start_position
and b2.owner = c2.child_owner
and b2.table_name = c2.child_table_name
and x.dm_lvl = b2.dm_lvl-1
and x.rowno in (4,5)
and b2.owner = f2.owner
and b2.table_name = f2.table_name
)
else ' '
end cell_value
from (
select c.dm_lvl,2 rowtype,b.rowno,a.rowno columnno
from (
select rownum rowno
from dual
connect by level <= (select max(length(line_text)) from table_lines)
) a
,(
select level rowno
from dual
connect by level <= 5
) b
,table_lines c
where c.dm_lvl < c.max_dm_lvl
and a.rowno <= length(c.line_text)
) x
)
, constraint_lines as (
select *
from (
select dm_lvl,rowtype,rowno,columnno,connect_by_isleaf cbil,replace(sys_connect_by_path(cell_value,','),',') line_text
from print_array
connect by prior dm_lvl = dm_lvl
and prior rowtype = rowtype
and prior rowno = rowno
and prior columnno = columnno-1
start with columnno = 1
)
where cbil = 1
)
, data_model as (
select dm_lvl,1 rowtype,1 rowno,line_text
from table_lines
union all
select dm_lvl,rowtype,rowno,line_text
from constraint_lines
order by 1,2,3
)
select ' '||line_text data_model from data_model
/

View File

@@ -0,0 +1,36 @@
--
-- show the driving table for the most recent query plan in the plan_table
--
-- usage is: @SHOWPLANDRIVINGTABLES11G
--
set linesize 999
col driving_table format a61
col driving_table_alias format a30
col leading_hint format a300
select id
,object_owner||'.'||object_name driving_table
,driving_table_alias
,object_type
,leading_hint
from (
select substr(replace(leading_hint,')',' ')
,instr(replace(leading_hint,')',' '),' ',1,1)+1
,instr(replace(leading_hint,')',' '),' ',1,2)-instr(replace(leading_hint,')',' '),' ',1,1)-1) driving_table_alias
,leading_hint
from (
select substr(c1,1,instr(c1,')')) leading_hint
from (
select substr(other_xml,instr(other_xml,'LEADING(')) c1
from plan_table
where other_xml is not null
and plan_id = (select max(plan_id) from plan_table)
)
)
) x
,plan_table
where plan_table.object_alias = trim(replace(to_char(substr(x.driving_table_alias,1,4000)),'"'))
and plan_table.plan_id = (select max(plan_id) from plan_table)
/

View File

@@ -0,0 +1,103 @@
--
-- show filter queries for the most recent plan in the plan_table
--
-- usage is: @SHOWPLANFILTERQUERIES11G
--
with
table_list as (
select 'TABLE' plan_object_type,a.id,a.object_owner table_owner,a.object_name table_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
from plan_table a
,dba_tables b
where b.owner = a.object_owner
and b.table_name = a.object_name
and a.plan_id = (select max(plan_id) from plan_table)
union all
select 'INDEX' plan_object_type,a.id,b.table_owner,b.table_name object_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
from plan_table a
,dba_indexes b
where b.owner = a.object_owner
and b.index_name = a.object_name
and a.plan_id = (select max(plan_id) from plan_table)
)
--
-- given the raw data for tables, modify the predicates so that we only see predicates for constant tests, no join predicates
-- join predicates are not used in FRP analysis
-- this is a bit of a hack as I never took the COMPILER and PARSER classes in school, basically this means it is almost 100%right
--
, modified_table_list as (
select id,table_owner,table_name,object_alias,cardinality,plan_object_type
,case when
instr(replace(access_predicates,'"="'),'=') > 0 or
instr(replace(access_predicates,'">"'),'>') > 0 or
instr(replace(access_predicates,'"<"'),'<') > 0 or
instr(replace(access_predicates,'">="'),'>=') > 0 or
instr(replace(access_predicates,'"<="'),'<=') > 0 or
instr(replace(access_predicates,'"!="'),'!=') > 0 or
instr(replace(access_predicates,'"<>"'),'<>') > 0 or
instr(replace(access_predicates,'" LIKE "'),' LIKE ') > 0 or
instr(replace(access_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
instr(replace(access_predicates,'" IN ("'),' IN (') > 0 or
instr(replace(access_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
instr(replace(access_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
instr(replace(access_predicates,'" NOT IN ("'),' NOT IN (') > 0
then access_predicates
end access_predicates
,case when
instr(replace(filter_predicates,'"="'),'=') > 0 or
instr(replace(filter_predicates,'">"'),'>') > 0 or
instr(replace(filter_predicates,'"<"'),'<') > 0 or
instr(replace(filter_predicates,'">="'),'>=') > 0 or
instr(replace(filter_predicates,'"<="'),'<=') > 0 or
instr(replace(filter_predicates,'"!="'),'!=') > 0 or
instr(replace(filter_predicates,'"<>"'),'<>') > 0 or
instr(replace(filter_predicates,'" LIKE "'),' LIKE ') > 0 or
instr(replace(filter_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
instr(replace(filter_predicates,'" IN ("'),' IN (') > 0 or
instr(replace(filter_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
instr(replace(filter_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
instr(replace(filter_predicates,'" NOT IN ("'),' NOT IN (') > 0
then filter_predicates
end filter_predicates
from table_list
)
--
-- do the final massaging of the raw data
-- in particular, get the true alias for each table, get data from dba_tables, generate an actual predicate we can test with
--
, plan_info as
(
select
id
, table_owner
, table_name
, substr(object_alias,1,instr(object_alias,'@')-1) table_alias
, cardinality
, (select num_rows from dba_tables where dba_tables.owner = modified_table_list.table_owner and dba_tables.table_name = modified_table_list.table_name) num_rows
, case
when access_predicates is null and filter_predicates is null then null
when access_predicates is null and filter_predicates is not null then filter_predicates
when access_predicates is not null and filter_predicates is null then access_predicates
when access_predicates is not null and filter_predicates is not null and access_predicates != filter_predicates then access_predicates||' and '||filter_predicates
else access_predicates
end predicate
from modified_table_list
)
--
-- look for places where indexes are accessed followed by table acces by rowid
-- combine the two lines into one
--
, combined_plan_info as (
select plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.num_rows
,min(plan_info.id) id
,max(plan_info.cardinality) cardinality
,listagg(plan_info.predicate,' and ') within group (order by id) predicate
from plan_info
group by plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.num_rows
)
select 'select count(*) filtered_rowcount,'''||table_owner||''' table_owner,'''||table_name||''' table_name,'''||table_alias||''' table_alias from '||table_owner||'.'||table_name||' '||table_alias||decode(predicate,null,null,' where '||predicate)
||decode(lead(table_name) over (order by table_owner,table_name),null,' ;',' union all')
from combined_plan_info
order by table_owner,table_name
/

View File

@@ -0,0 +1,141 @@
--
-- generate SQL for the FRP spreadsheet from the most recent plan in the plan_table
--
-- usage is: @SHOWPLANFRPSPREADSHEETCODE11G
--
col actual_frp format 999.0
col plan_frp format 999.0
col select_id noprint
with
--
-- generates a FRP SPREADSHEET query using plan table information for an EXPLAINED query
--
--
-- THIS CODE IS DEPENDENT UPON WHAT IS IN THE PLAN TABLE
-- among other things this means that if oracle changes the contents of this table, this query may stop working
--
-- several possible flaws can prevent this code from generating an executable SQL SELECT
--
-- 1. bind variables: the corresponding select here must be modified to group on the bind column and select an round(avg(count(*))
-- 2. join predicates: if any are used along with constant tests in a plan step, they must be manaully edited out of the correspoding select here
-- 3. packaged functions: column=functioncall predicates can be dropped in which case filtered_cardinality will be affected, check it if you query has these
-- 4. outer join is not supported. These should be removed. If the case expression becomes empty use count(*).
-- 5. correlated subqueries are confusing. This is because the appear as queries with bind variables. Test like #1 but ingnore their results.
--
--
-- get raw_data from the plan_table for each table reference in the query plan
-- a table may be used more than once in which case there will be more than one row returned here
-- this is managed by using ID so that we know the plan step the table reference refers to
-- note that some plan steps may be index lookups so in this section we translate the index to its underlying table
--
table_list as (
select a.id,a.object_owner table_owner,a.object_name table_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
from plan_table a
,dba_tables b
where b.owner = a.object_owner
and b.table_name = a.object_name
and a.plan_id = (select max(plan_id) from plan_table)
union all
select a.id,b.table_owner,b.table_name object_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
from plan_table a
,dba_indexes b
where b.owner = a.object_owner
and b.index_name = a.object_name
and a.plan_id = (select max(plan_id) from plan_table)
)
--
-- given the raw data for tables, modify the predicates so that we only see predicates for constant tests, no join predicates
-- join predicates are not used in FRP analysis
-- this is a bit of a hack as I never took the COMPILER and PARSER classes in school, basically this means it is almost 100%right
-- what we call "close enough for jazz"
--
, modified_table_list as (
select id,table_owner,table_name,object_alias,cardinality
,case when
instr(replace(access_predicates,'"="'),'=') > 0 or
instr(replace(access_predicates,'">"'),'>') > 0 or
instr(replace(access_predicates,'"<"'),'<') > 0 or
instr(replace(access_predicates,'">="'),'>=') > 0 or
instr(replace(access_predicates,'"<="'),'<=') > 0 or
instr(replace(access_predicates,'"!="'),'!=') > 0 or
instr(replace(access_predicates,'"<>"'),'<>') > 0 or
instr(replace(access_predicates,'" LIKE "'),' LIKE ') > 0 or
instr(replace(access_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
instr(replace(access_predicates,'" IN ("'),' IN (') > 0 or
instr(replace(access_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
instr(replace(access_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
instr(replace(access_predicates,'" NOT IN ("'),' NOT IN (') > 0
then access_predicates
end access_predicates
,case when
instr(replace(filter_predicates,'"="'),'=') > 0 or
instr(replace(filter_predicates,'">"'),'>') > 0 or
instr(replace(filter_predicates,'"<"'),'<') > 0 or
instr(replace(filter_predicates,'">="'),'>=') > 0 or
instr(replace(filter_predicates,'"<="'),'<=') > 0 or
instr(replace(filter_predicates,'"!="'),'!=') > 0 or
instr(replace(filter_predicates,'"<>"'),'<>') > 0 or
instr(replace(filter_predicates,'" LIKE "'),' LIKE ') > 0 or
instr(replace(filter_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
instr(replace(filter_predicates,'" IN ("'),' IN (') > 0 or
instr(replace(filter_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
instr(replace(filter_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
instr(replace(filter_predicates,'" NOT IN ("'),' NOT IN (') > 0
then filter_predicates
end filter_predicates
from table_list
)
--
-- do the final massaging of the raw data
-- in particular, get the true alias for each table, get data from dba_tables, generate an actual predicate we can test with
--
, plan_info as
(
select
id
, table_owner
, table_name
, substr(object_alias,1,instr(object_alias,'@')-1) table_alias
, cardinality
, (select num_rows from dba_tables where dba_tables.owner = modified_table_list.table_owner and dba_tables.table_name = modified_table_list.table_name) num_rows
, case
when access_predicates is null and filter_predicates is null then null
when access_predicates is null and filter_predicates is not null then filter_predicates
when access_predicates is not null and filter_predicates is null then access_predicates
when access_predicates is not null and filter_predicates is not null and access_predicates != filter_predicates then access_predicates||' and '||filter_predicates
else access_predicates
end predicate
from modified_table_list
)
--
-- look for places where indexes are accessed followed by table acces by rowid
-- combine the two lines into one
--
, combined_plan_info as (
select plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.cardinality,plan_info.num_rows
,min(plan_info.id) id
,listagg(plan_info.predicate,' and ') within group (order by id) predicate
from plan_info
group by plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.cardinality,plan_info.num_rows
)
--
-- give us a SQL statement that for each table reference, both counts all rows and counts only rows that pass the filter predictes
-- then do the math needed to generate an FRP SPREADSHEET
-- this version (4) only scans each table once instead of twice like the old versions
--
select 1 select_id,'with' sqltext from dual union all
select 2 select_id,' frp_data as (' from dual union all
select 3 select_id,' select '''||lpad(id,5,' ')||''' id,'''||table_owner||''' table_owner,'''||table_name||''' table_name,'''||table_alias||''' table_alias,'||nvl(to_char(num_rows),'cast(null as number)')||' num_rows,count(*) rowcount,'||cardinality||' cardinality,'||decode(predicate,null,'cast(null as number)','count(case when '||predicate||' then 1 end)')||' filtered_cardinality from '||table_owner||'.'||table_name||' '||table_alias||' union all'
from combined_plan_info
union all
select 4 select_id,' select null,null,null,null,null,null,null,null from dual' from dual union all
select 5 select_id,' )' from dual union all
select 6 select_id,'select frp_data.*,round(frp_data.filtered_cardinality/case when frp_data.rowcount = 0 then cast(null as number) else frp_data.rowcount end*100,1) actual_frp,decode(frp_data.filtered_cardinality,null,cast(null as number),round(frp_data.cardinality/case when frp_data.num_rows = 0 then cast(null as number) else frp_data.num_rows end*100,1)) plan_frp' from dual union all
select 7 select_id,'from frp_data' from dual union all
select 8 select_id,'where id is not null' from dual union all
select 9 select_id,'order by frp_data.id' from dual union all
select 10 select_id,'/' from dual
order by 1
/

View File

@@ -0,0 +1,38 @@
--
-- show indexes for any table referenced directly or indirectly in the current plan of the plan_table
--
-- usage is: @SHOWPLANINDEXES11G
--
break on table_owner on table_name on index_owner skip 1 on index_name skip 1 on uniqueness
col column_name format a30
with
plan_references as (
select id,object_owner owner,object_name table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table
where object_type = 'TABLE'
and plan_id = (select max(plan_id) from plan_table)
union
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
and a.plan_id = (select max(plan_id) from plan_table)
)
, plan_tables as (
select distinct owner,table_name
from plan_references
)
select dba_ind_columns.column_name,dba_indexes.index_name,dba_indexes.uniqueness,dba_indexes.table_name,dba_indexes.table_owner,dba_indexes.owner index_owner
from dba_indexes
,dba_ind_columns
,plan_tables
where plan_tables.owner = dba_indexes.table_owner
and plan_tables.table_name = dba_indexes.table_name
and dba_indexes.owner = dba_ind_columns.index_owner
and dba_indexes.index_name = dba_ind_columns.index_name
order by dba_indexes.table_owner,dba_indexes.table_name,dba_indexes.owner,dba_indexes.index_name,dba_ind_columns.column_position
/

View File

@@ -0,0 +1,28 @@
--
-- get num_rows off DBA_TABLES for any table referenced by the current plan in the plan_table
--
-- usage is: @SHOWPLANNUMROWS11G
--
with
table_list as (
select object_owner owner,object_name table_name
from plan_table
where object_type = 'TABLE'
and plan_id = (select max(plan_id) from plan_table)
union
select b.table_owner,b.table_name
from plan_table a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
and a.plan_id = (select max(plan_id) from plan_table)
)
select num_rows,dba_tables.owner,dba_tables.table_name
from dba_tables
,table_list
where table_list.owner = dba_tables.owner
and table_list.table_name = dba_tables.table_name
order by 2,1
/

View File

@@ -0,0 +1,128 @@
--
-- show a query diagram for the current plan of the plan_table
-- uses the join tree with extended information
--
-- usage is: @SHOWPLANQUERYDIAGRAM11G
--
col query_diagram format a300
col query_name format a30
break on query_name skip 1 dup
with
plan_table_current as (
select *
from plan_table
where plan_id = (select max(plan_id) from plan_table)
)
, predicate_data as (
select nvl(query_name,'SEL$1') adjusted_query_name
,z.*
from (
select case
when table_2_alias is null then 'CONSTANT TEST'
else 'JOIN'
end expression_type
,substr(pt.object_alias,instr(object_alias,'@')+1) query_name
,y.*
from plan_table_current pt
,(
select case
when instr(predicate_expression,'.') > 0 then substr(predicate_expression,1,instr(predicate_expression,'.')-1)
else (select substr(object_alias,1,instr(object_alias,'@')-1) from plan_table_current where id = x.id and rownum = 1)
end table_1_alias
,substr(predicate_expression,instr(predicate_expression,'=')+1,instr(predicate_expression,'.',1,2)-instr(predicate_expression,'=')-1) table_2_alias
,x.*
from (
select distinct *
from (
select id,substr( ' '||p||' '
,instr(' '||p||' ',' ',1,level)+1
,instr(' '||p||' ',' ',1,level+1)-instr(' '||p||' ',' ',1,level)-1
) predicate_expression
,level rowno
,p
from (
select *
from (
select id,trim(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
p
,' ',' ')
,' ',' ')
,' ',' ')
,' ',' ')
,' ',' ')
,' ',' ')
,' ',' ')
,' ',' ')
) p
from (
select id,trim(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
p
,'"')
,' AND ',' ')
,' OR ',' ')
,' NOT ',' ')
,'(',' ')
,')',' ')
,' and ',' ')
,' and ',' ')
) p
from (
select id,access_predicates||' '||filter_predicates p
from plan_table_current
where rownum >= 1
)
)
)
where p is not null
)
connect by level <= length(p)-length(replace(p,' '))+1
)
) x
) y
where y.id = pt.id
) z
)
, constant_test as (
select distinct expression_type,table_1_alias
from predicate_data
where expression_type = 'CONSTANT TEST'
)
select t.query_name
,decode(ct,'c','c',' ')||lpad(decode(ct,'c','-',' '),(lvlno)*3,decode(ct,'c','-',' '))||table_2_alias query_diagram
from (
select query_name,table_1_alias,table_2_alias
,level lvlno
,max(level) over (partition by query_name) max_lvlno
,case when (select expression_type from constant_test where table_1_alias = x.table_2_alias) is not null then 'c' end ct
from (
select distinct adjusted_query_name query_name,table_1_alias,table_2_alias
from predicate_data
where expression_type = 'JOIN'
union all
select distinct adjusted_query_name query_name,null,table_1_alias
from predicate_data
where table_1_alias not in (select table_2_alias from predicate_data where table_2_alias is not null)
) x
connect by prior table_2_alias = table_1_alias
and prior query_name = query_name
start with table_1_alias is null
) t
/

View File

@@ -0,0 +1,23 @@
--
-- show all tables referenced by the qep
-- this include indrect references so an index reference translates to the table in this report
--
with
plan_table_current as (
select *
from plan_table
where plan_id = (select max(plan_id) from plan_table)
)
select id,object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
from plan_table_current
where object_type = 'TABLE'
union
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table_current a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
order by 2,3,1
/

View File

@@ -0,0 +1,22 @@
--
-- show actual unique list of tables referenced by the QEP
--
with
plan_table_current as (
select *
from plan_table
where plan_id = (select max(plan_id) from plan_table)
)
select object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
from plan_table_current
where object_type = 'TABLE'
union
select b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
from plan_table_current a
,dba_indexes b
where a.object_type like 'INDEX%'
and a.object_owner = b.owner
and a.object_name = b.index_name
order by 1,2
/

View File

@@ -0,0 +1,124 @@
--
-- create a multi-part report on database SQL by instance
-- grouping SQL into powers of ten based on cpu consumed
-- in order to see easily the top 1% of queries that are most busy
--
set linesize 999
set pagesize 50000
set feedback 1
set trimspool on
set trimout on
set doc off
clear breaks
clear computes
set echo off
-- alter session set nls_date_format = 'dd-mon-rrrr hh24:mi:ss';
select * from v$version
/
select inst_id
,instance_name
,startup_time
,round((sysdate-startup_time),1) up_days
,round(round((sysdate-startup_time),1)*24) maximum_cache_hours
,to_char(sysdate,'dd-mon-rrrr hh24:mi:ss') right_now
from gv$instance
order by inst_id
/
--
-- show how long the database has been up, how many cpus are available, and thus the theoretical CPU available
--
select inst_id
,instance_name
,(select cpu_count_highwater from sys.v_$license) cpu_count
,round((round((sysdate-startup_time),1)*24)*(select cpu_count_highwater from sys.v_$license)) available_cpu_hours
from gv$instance
order by inst_id
/
col sql_text format a700 trunc
col sql_text clear
col sql_text format a700 trunc
col pct_total format 990
compute sum of sql_statements on inst_id
compute sum of sql_statements on report
compute sum of db_pct_total on inst_id
compute sum of db_pct_total on report
compute sum of running_consumed_cpu_hours on report
break on inst_id skip page on report
--
-- use a logarithmic scale to plot cpu consumtion of all queries in the cache
-- we can use this to zero in on the top consumers
-- notice we exclude PLSQL CALLS but not the sql inside these calls
-- this gives us the true SQL workload
--
select
inst_id
,cpu_time_log10
,sql_statements
,cpu_time_rounded,round(cpu_time) cpu_time
,round(100*ratio_to_report(cpu_time) over(partition by inst_id)) inst_pct_total
,round(100*ratio_to_report(cpu_time) over()) db_pct_total
,round(sum(cpu_time) over (partition by inst_id order by cpu_time_log10)) running_cpu_time
,round(round(sum(cpu_time) over (partition by inst_id order by cpu_time_log10))/60/60,2) running_consumed_cpu_hours
from (
select
inst_id
,trunc(log(10,mycpu_time)) cpu_time_log10
,count(*) sql_statements
,power(10,trunc(log(10,mycpu_time))) cpu_time_rounded
,sum(mycpu_time) cpu_time
from (
select inst_id,case when cpu_time <= 0 then 1 else cpu_time end/1000000 mycpu_time
from gv$sqlarea
where trim(upper(sql_text)) not like 'BEGIN%'
and trim(upper(sql_text)) not like 'DECLARE%'
and trim(upper(sql_text)) not like 'CALL%'
)
group by trunc(log(10,mycpu_time)),inst_id
) a
order by inst_id,a.cpu_time_log10
/
clear computes
col module format a30 word
col sec_per_exec format 999999990.0
--compute sum of cpu_seconds on inst_id , report
break on inst_id skip page
--
-- show use the actual SQL that exceeds some threshhold
-- these are the queries we want to concentrate on
-- configure the last AND predicate to whatever is reasonable based on the above query
--
select inst_id
,sql_id
,child_number
,trunc(cpu_time/1000000) cpu_seconds
,trunc(elapsed_time/1000000) eplapsed_seconds
,executions
,round(trunc(elapsed_time/1000000)/decode(executions,0,null,executions),1) sec_per_exec
,round((sysdate-to_date(first_load_time,'rrrr-mm-dd/hh24:mi:ss'))*24) hours_in_cache
,module
-- ,address
,hash_value
,(select 'Open' from gv$open_cursor b where b.inst_id = a.inst_id and b.address = a.address and b.hash_value = a.hash_value and rownum = 1) open
/*
,case when sql_text like '%SELECT /*+ ORDERED NO_EXPAND USE_HASH%' or sql_text like '%FROM :Q%' or instr(sql_text,'CIV_GB') > 0 or instr(sql_text,'PIV_GB') > 0 or instr(sql_text,'PIV_SSF') > 0 or instr(sql_text,'SWAP_JOIN_INPUTS') > 0 then 'Slave'
when sql_text like '%SELECT /*+ Q%' then 'Query'
else (select 'Yes' from gv$sql_plan b where b.inst_id = a.inst_id and b.address = a.address and b.hash_value = a.hash_value and b.child_number = a.child_number and b.other_tag like 'PARALLEL%' and rownum = 1)
end parallel
*/
,sql_text
from gv$sql a
where trim(upper(sql_text)) not like 'BEGIN%'
and trim(upper(sql_text)) not like 'DECLARE%'
and trim(upper(sql_text)) not like 'CALL%'
and cpu_time/1000000 >= 1000
--and cpu_time/1000000 >= 100
order by 1,4,5
/

1
csierra/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.DS_Store

376
csierra/README.md Normal file
View File

@@ -0,0 +1,376 @@
CS Scripts Inventory by Type (2023-07-29)
============================
* Latency
* Load
* SQL Performance
* SPBL - SQL Plan Baselines
* SPRF - SQL Profiles
* SPCH - SQL Patches
* Sessions
* Kill Sessions
* Blocked Sessions
* Locks
* Space Reporting
* Space Maintenance
* Container
* System Metrics
* System Stats and Events
* Configuration
* Logs
* Traces
* Reports
* Miscellaneous Utilities
Latency
-------
* la.sql | l.sql | cs_latency.sql - Current SQL latency (elapsed time over executions)
* le.sql | cs_latency_extended.sql - Current SQL latency (elapsed time over executions) - Extended
* lr.sql | cs_latency_range.sql - SQL latency for a time range (elapsed time over executions) (AWR) - 15m Granularity
* lre.sql | cs_latency_range_extended.sql - SQL latency for a time range (elapsed time over executions) (AWR) - 15m Granularity - Extended
* cs_latency_1m.sql - Last 1m SQL latency (elapsed time over executions)
* cs_latency_1m_extended.sql - Last 1m SQL latency (elapsed time over executions) - Extended
* cs_latency_snapshot.sql - Snapshot SQL latency (elapsed time over executions)
* cs_latency_snapshot_extended.sql - Snapshot SQL latency (elapsed time over executions) - Extended
* lah.sql | lh.sql | cs_latency_hist.sql - Current and Historical SQL latency (cpu time over executions)
* cs_sql_latency_histogram.sql - SQL Latency Histogram (elapsed time over executions)
* cs_sql_perf_long_executions.sql - SQL Executions longer than N seconds
* cs_dg_redo_dest_resp_histogram_chart.sql - Data Guard (DG) REDO Transport Duration Chart
* cs_dg_redo_dest_resp_histogram_report.sql - Data Guard (DG) REDO Transport Duration Report
* cs_LGWR_chart.sql - Log Writer LGWR Slow Writes Duration Chart - from current LGWR trace
* cs_LGWR_report.sql - Log Writer LGWR Slow Writes Duration Report - from current LGWR trace
Load
----
* ta.sql | t.sql | cs_top.sql - Top Active SQL as per Active Sessions History ASH - last 1m
* tr.sql | cs_top_range.sql - Top Active SQL as per Active Sessions History ASH - time range
* aa.sql | cs_ash_analytics.sql - Poor-man's version of ASH Analytics for all Timed Events (Average Active Sessions AAS)
* ma.sql | cs_max_ash_analytics.sql - Poor-man's version of ASH Analytics for all Timed Events (Maximum Active Sessions)
* cpu.sql | cs_cpu_demand.sql - Poor-man's version of ASH Analytics for CPU Demand (ON CPU + Scheduler)
* aas.sql | cs_average_active_sessions.sql - Average Active Sessions (ASH Analytics on dbc_active_session)
* mas.sql | cs_maximum_active_sessions.sql - Maximum Active Sessions (ASH Analytics on dbc_active_session)
* cs_osstat_chart.sql - OS Stats from AWR (time series chart)
* cs_osstat_cpu_util_perc_chart.sql - CPU Utilization Percent Chart (AWR) - 15m Granularity
* cs_osstat_cpu_util_perc_now.sql - CPU Utilization Percent - Now
* cs_osstat_cpu_report.sql - CPU Cores Load and Busyness as per OS Stats from AWR (time series report)
* cs_osstat_cpu_load_chart.sql - CPU Cores Load as per OS Stats from AWR (time series chart)
* cs_osstat_cpu_busy_chart.sql - CPU Cores Busyness as per OS Stats from AWR (time series chart)
* cs_top_pdb_chart.sql - Top PDBs as per use of CPU Cores, Disk Space or Sessions (time series chart)
* cs_top_pdb_tps_chart.sql - Top PDBs as per TPS (time series chart)
* cs_timed_event_top_consumers_pie.sql - Top contributors of a given Wait Class or Event (pie chart)
* cs_timed_event_top_consumers_report.sql - Top contributors of a given Wait Class or Event (text report)
SQL Performance
---------------
* p.sql | cs_sqlperf.sql - Basic SQL performance metrics for a given SQL_ID
* pp.sql | cs_sqlperf_plus.sql - Basic SQL performance metrics for a given SQL_ID + Top Keys
* x.sql | cs_planx.sql - Execution Plans and SQL performance metrics for a given SQL_ID
* ssa.sql | cs_sqlstat_analytics.sql - SQL Statistics Analytics (AWR) - 15m Granularity
* ssaa.sql | cs_sqlstat_analytics_aggregate.sql - SQL Statistics Analytics Aggregate (AWR) - 15m Granularity
* ssr.sql | cs_sqlstat_report.sql - SQL Statistics Report (AWR) - detailed(15m), hourly, daily, global
* pm.sql | cs_planm.sql - Execution Plans in Memory for a given SQL_ID
* ph.sql | cs_planh.sql - Execution Plans in AWR for a given SQL_ID
* dc.sql - Display Cursor Execution Plan. Execute this script after one SQL for which you want to see the Execution Plan
* dp.sql - Display Plan Table Explain Plan. Execute this script after one EXPLAIN PLAN FOR for a SQL for which you want to see the Explain Plan
* cs_sqltext.sql - SQL Text for a given SQL_ID
* cs_sqlmon_hist.sql - SQL Monitor Report for a given SQL_ID (from AWR)
* cs_sqlmon_mem.sql - SQL Monitor Report for a given SQL_ID (from MEM)
* cs_sqlmon_duration_chart.sql - SQL Monitor Reports duration for a given SQL_ID (time series chart)
* cs_sqlmon_capture.sql - Generate SQL Monitor Reports for given SQL_ID for a short period of time
* cs_sqlmon_binds.sql - SQL Monitor Binds for given SQL_ID
* cs_sqlmon_top_binds.sql - SQL Monitor Top Binds for given SQL_ID
* cs_sql_bind_capture.sql - SQL Bind Capture for given SQL_ID
* cs_sql_bind_capture_one.sql - SQL Bind Capture for given SQL_ID and Bind name (text report)
* cs_sql_bind_capture_one_chart.sql - SQL Bind Capture for given SQL_ID and Bind name (time series chart)
* cs_binds.sql - Binds for a given SQL_ID
* cs_sql_sessions.sql - Recent and Active Sessions executing a SQL_ID
* cs_high_execution_rate_rps.sql - List executions by time for a given SQL_ID with high RPS
* cs_sql_perf_concurrency.sql - Concurrency Histogram of SQL with more than N Concurrent Sessions
* cs_sql_perf_high_aas.sql - SQL with AAS per hour for a given Timed Event higher than N (time series text report)
* cs_purge_cursor.sql - Purge Cursor(s) for SQL_ID using DBMS_SHARED_POOL.PURGE and SQL Patch
SPBL - SQL Plan Baselines
-------------------------
* cs_spbl_evolve.sql - Evolve a SQL Plan Baseline for given SQL_ID
* cs_spbl_create.sql - Create a SQL Plan Baseline for given SQL_ID
* cs_spbl_drop.sql - Drop one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_drop_all.sql - Drop all SQL Plan Baselines for some SQL Text string on PDB
* cs_spbl_sprf_spch_drop_all.sql - Drop all SQL Plan Baselines, SQL Profiles and SQL Patches for some SQL Text string on PDB
* cs_spbl_list.sql - Summary list of SQL Plan Baselines for given SQL_ID
* cs_spbl_list_all_pdb.sql - List all SQL Plan Baselines for some SQL Text string on PDB
* cs_spbl_list_all_cdb.sql - List all SQL Plan Baselines for some SQL Text string on CDB
* cs_spbl_sprf_spch_list_all.sql - List all SQL Plan Baselines, SQL Profiles and SQL Patches for some SQL Text string on PDB
* cs_spbl_plan.sql - Display SQL Plan Baseline for given SQL_ID
* cs_spbl_enable.sql - Enable one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_disable.sql - Disable one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_accept.sql - Accept one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_fix.sql - Fix one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_unfix.sql - Unfix one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_stgtab.sql - Creates Staging Table for SQL Plan Baselines
* cs_spbl_stgtab_delete.sql - Deletes Staging Table for SQL Plan Baselines
* cs_spbl_pack.sql - Packs into staging table one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_unpack.sql - Unpacks from staging table one or all SQL Plan Baselines for given SQL_ID
* cs_spbl_expdp.sql - Packs into staging table one or all SQL Plan Baselines for given SQL_ID and Exports such Baselines using Datapump
* cs_spbl_impdp.sql - Imports from Datapump file into a staging table all SQL Plan Baselines and Unpacks from staging table one or all SQL Plan Baselines for given SQL
* cs_spbl_meta.sql - SQL Plan Baseline Metadata for given SQL_ID
* cs_spbl_indexes.sql - List of Indexes Referenced by all SQL Plan Baselines on PDB
* cs_spbl_failed.sql - List of SQL Plans with: "Failed to use SQL plan baseline for this statement"
* cs_spbl_corrupt.sql - List of Corrupt SQL Plans with: missing Plan Rows from sys.sqlobj$plan
* cs_spbl_purge_outdated.sql - Purge Outdated SQL Plan Baselines
* create_spb_from_awr.sql - Create SQL Plan Baselin from AWR Plan (legacy script)
* create_spb_from_cur.sql - Create SQL Plan Baseline from SQL Cursor (legacy script)
* spm_backup.sql - Create DATAPUMP backup of SQL Plan Management (SPM) Repository for one PDB
SPRF - SQL Profiles
-------------------
* cs_sprf_create.sql - Create a SQL Profile for given SQL_ID
* cs_sprf_drop.sql - Drop all SQL Profiles for given SQL_ID
* cs_sprf_drop_all.sql - Drop all SQL Profiles for some SQL Text string on PDB
* cs_sprf_list.sql - Summary list of SQL Profiles for given SQL_ID
* cs_sprf_list_all_pdb.sql - List all SQL Profiles for some SQL Text string on PDB
* cs_sprf_list_all_cdb.sql - List all SQL Profiles for some SQL Text string on CDB
* cs_sprf_plan.sql - Display SQL Profile Plan for given SQL_ID
* cs_sprf_enable.sql - Enable one or all SQL Profiles for given SQL_ID
* cs_sprf_disable.sql - Disable one or all SQL Profiles for given SQL_ID
* cs_sprf_xfr.sql - Transfers a SQL Profile for given SQL_ID
* cs_sprf_export.sql - Exports Execution Plans for some SQL_ID or all SQL in some PDBs, using SQL Profile(s)
* cs_sprf_stgtab.sql - Creates Staging Table for SQL Profiles
* cs_sprf_pack.sql - Packs into staging table one or all SQL Profiles for given SQL_ID
* cs_sprf_unpack.sql - Unpack from staging table one or all SQL Profiles for given SQL_ID
* cs_sprf_category.sql - Changes category for a SQL Profile for given SQL_ID
* cs_sprf_indexes.sql - List of Indexes Referenced by all SQL Profiles on PDB
* coe_xfr_sql_profile.sql - Transfer (copy) a SQL Profile from PDBx on CDBa into PDBy on CDBb (legacy script)
SPCH - SQL Patches
------------------
* cs_spch_first_rows.sql - Create a SQL Patch with FIRST_ROWS for given SQL_ID, and drops SQL Profile and SQL Plan Baselines
* cs_spch_create.sql - Create a SQL Patch for given SQL_ID
* cs_spch_drop.sql - Drop all SQL Patches for given SQL_ID
* cs_spch_drop_all.sql - Drop all SQL Patches for some SQL Text string on PDB
* cs_spch_list.sql - Summary list of SQL Patches for given SQL_ID
* cs_spch_list_all_pdb.sql - List all SQL Patches for some SQL Text string on PDB
* cs_spch_list_all_cdb.sql - List all SQL Patches for some SQL Text string on CDB
* cs_spch_plan.sql - Display SQL Patch Plan for given SQL_ID
* cs_spch_enable.sql - Enable one or all SQL Patches for given SQL_ID
* cs_spch_disable.sql - Disable one or all SQL Patches for given SQL_ID
* cs_spch_stgtab.sql - Creates Staging Table for SQL Patches
* cs_spch_pack.sql - Packs into staging table one or all SQL Patches for given SQL_ID
* cs_spch_unpack.sql - Unpack from staging table one or all SQL Patches for given SQL_ID
* cs_spch_xfr.sql - Transfers a SQL Patch for given SQL_ID
* cs_spch_category.sql - Changes category for a SQL Patch for given SQL_ID
Sessions
--------
* a.sql | as.sql | cs_active_sessions.sql - Active Sessions including SQL Text and Exection Plan
* am.sql | cs_ash_mem_sample_report.sql - ASH Samples from MEM
* ah.sql | cs_ash_awr_sample_report.sql - ASH Samples from AWR
* cs_ash_awr_block_chains_report.sql - ASH Block Chains Report from AWR
* cs_ash_mem_block_chains_report.sql - ASH Block Chains Report from MEM
* cs_ash_awr_peaks_report.sql - ASH Peaks Report from AWR
* cs_ash_mem_peaks_report.sql - ASH Peaks Report from MEM
* cs_ash_awr_peaks_chart.sql - ASH Peaks Chart from AWR
* cs_ash_mem_peaks_chart.sql - ASH Peaks Chart from MEM
* cs_ash_awr_peaks_bubble.sql - ASH Peaks Bubble from AWR
* cs_ash_mem_peaks_bubble.sql - ASH Peaks Bubble from MEM
* cs_sessions.sql - Simple list all current Sessions (all types and all statuses)
* cs_sessions_hist.sql - Simple list all historical Sessions (all types and all statuses)
* cs_sessions_PCTL_by_machine.sql - Sessions Percentiles by Machine
* cs_sessions_by_type_and_status_chart.sql - Sessions by Type and Status (time series chart)
* cs_sessions_by_machine_chart.sql - Sessions by Machine (time series chart)
* cs_sessions_age_by_machine_chart.sql - Session Age by Machine (time series chart)
* cs_sessions_by_pdb_chart.sql - Sessions by PDB (time series chart)
* cs_sess_mon.sql - Monitored Sessions
* mysid.sql - Get SID and SPID of own Session
* open_cursor.sql - Open Cursors and Count of Distinct SQL_ID per Session
* session_undo.sql - Displays undo information on relevant database sessions (by Tim Hall)
Kill Sessions
-------------
* cs_kill_sid.sql - Kill one User Session
* cs_kill_sql_id.sql - Kill User Sessions executing some SQL_ID
* cs_kill_root_blockers.sql - Kill Root Blocker User Sessions
* cs_kill_machine.sql - Kill User Sessions connected from some Machine(s)
* cs_kill_scheduler.sql - Kill User Sessions waiting on Scheduler (Resource Manager)
Blocked Sessions
----------------
* bs.sql | cs_blocked_sessions_report.sql - Blocked Sessions Report
* cs_blocked_sessions_ash_awr_report.sql - Top Session Blockers by multiple Dimensions as per ASH from AWR (text report)
* cs_blocked_sessions_by_state_ash_awr_chart.sql - Top Session Blockers by State of Root Blocker as per ASH from AWR (time series chart)
* cs_blocked_sessions_by_machine_ash_awr_chart.sql - Top Session Blockers by Machine of Root Blocker as per ASH from AWR (time series chart)
* cs_blocked_sessions_by_module_ash_awr_chart.sql - Top Session Blockers by Module of Root Blocker as per ASH from AWR (time series chart)
* cs_blocked_sessions_by_sid_ash_awr_chart.sql - Top Session Blockers by SID of Root Blocker as per ASH from AWR (time series chart)
Locks
-----
* locks.sql | cs_locks.sql - Locks Summary and Details
* cs_locks_mon.sql - Locks Summary and Details - Monitor
* cs_wait_chains.sql - Wait Chains (text report)
Space Reporting
---------------
* cs_df_u02_chart.sql - Disk FileSystem u02 Utilization Chart
* cs_top_pdb_size_chart.sql - Top PDB Disk Size Utilization (time series chart)
* cdb_tablespace_usage_metrics.sql - Application Tablespace Inventory for all PDBs
* cs_tablespaces.sql - Tablespace Utilization (text report)
* cs_tablespace_chart.sql - Tablespace Utilization (time series chart)
* cs_extents_map.sql - Tablespace Block Map
* cs_top_segments.sql - Top CDB or PDB Segments (text report)
* cs_top_segments_pdb.sql - Top PDB Segments (text report)
* cs_segment_chart.sql - Segment Size GBs for given Segment (time series chart)
* cs_tempseg_usage.sql - Temporary (Temp) Segment Usage (text report)
* cs_table_segments_chart.sql - Table-related Segment Size GBs (Table, Indexes and Lobs) for given Table (time series chart)
* cs_estimate_table_size.sql - Estimate Table Size
* cs_tables.sql - All Tables and Top N Tables (text report)
* cs_top_tables.sql - Top Tables according to Segment(s) size (text report)
* cs_top_table_size_chart.sql - Top PDB Tables (time series chart)
* cs_table.sql - Table Details
* cs_table_stats_chart.sql - CBO Statistics History for given Table (time series chart)
* cs_table_stats_30d_chart.sql - CBO Statistics History for given Table (30 days time series chart)
* cs_table_stats_report.sql - CBO Statistics History for given Table (time series text report)
* cs_table_mod_chart.sql - Table Modification History (INS, DEL and UPD) for given Table (time series chart)
* cs_table_mod_report.sql - Table Modification History (INS, DEL and UPD) for given Table (text report)
* cs_tables_rows_vs_count.sql - Compares CBO Stats Rows to COUNT(*) on Application Tables
* cs_tables_rows_vs_count_outliers.sql - Compares CBO Stats Rows to COUNT(*) on Application Tables and Reports Outliers
* cs_estimate_index_size.sql - Estimate Index Size
* cs_top_bloated_indexes.sql - Top bloated indexes on a PDB (text report)
* cs_top_indexes.sql - Top Indexes according to Segment(s) size
* cs_index_part_reorg.sql - Calculate index reorg savings
* cs_index_usage.sql - Index Usage (is an index still in use?)
* cs_foreign_key_fk_constraints_missing_indexes.sql - Generate DDL to create missing Indexes to support FK constraints
* cs_recyclebin.sql - Recyclebin Content
* cs_top_lobs.sql - Top Lobs according to Segment(s) size
Space Maintenance
-----------------
* cs_tbs_resize.sql - Tablespace Resize
* cs_redef_table.sql - Table Redefinition
* cs_redef_table_silent.sql - Table Redefinition - Silent
* cs_redef_table_with_purge.sql - Table Redefinition with Purge
* cs_redef_schema.sql - Schema Redefinition (by moving all objects into new Tablespace)
* cs_redef_remove_lob_dedup_on_pdb.sql - Remove LOB Deduplication on PDB
* cs_drop_redef_table.sql - Generate commands to drop stale objects from failed Table Redefinition(s)
Container
---------
* cdb.sql - Connect into CDB$ROOT
* pdb.sql - List all PDBs and Connect into one PDB
* cs_pdbs.sql - PDBs attributes
System Metrics
--------------
* cs_all_sysmetric_for_cdb_mem.sql - All System Metrics as per V$SYSMETRIC Views for a CDB (text report)
* cs_all_sysmetric_for_pdb_mem.sql - All System Metrics as per V$CON_SYSMETRIC Views for a PDB (text report)
* cs_all_sysmetric_for_cdb_hist.sql - All System Metrics as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (text report)
* cs_all_sysmetric_for_pdb_hist.sql - All System Metrics as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (text report)
* cs_load_sysmetric_for_cdb_mem.sql - System Load as per V$SYSMETRIC Views for a CDB (text report)
* cs_load_sysmetric_per_pdb_mem.sql - System Load as per V$CON_SYSMETRIC Views per PDB (text report)
* cs_load_sysmetric_for_pdb_mem.sql - System Load as per V$CON_SYSMETRIC Views for a PDB (text report)
* cs_load_sysmetric_for_cdb_hist.sql - System Load as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (text report)
* cs_load_sysmetric_per_pdb_hist.sql - System Load as per DBA_HIST_CON_SYSMETRIC_SUMM View per PDB (text report)
* cs_load_sysmetric_for_pdb_hist.sql - System Load as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (text report)
* cs_one_sysmetric_per_pdb_chart.sql - One System Metric as per DBA_HIST_CON_SYSMETRIC_SUMM View per PDB (time series chart)
* cs_some_sysmetric_for_cdb_mem_chart.sql - Some System Metrics as per V$SYSMETRIC_HISTORY View for a CDB (time series chart)
* cs_some_sysmetric_for_pdb_mem_chart.sql - Some System Metrics as per V$CON_SYSMETRIC_HISTORY View for a PDB (time series chart)
* cs_some_sysmetric_for_cdb_hist_chart.sql - Some System Metrics as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (time series chart)
* cs_some_sysmetric_for_pdb_hist_chart.sql - Some System Metrics as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (time series chart)
* cs_cpu_sysmetric_for_cdb_mem_chart.sql - CPU System Metrics as per V$SYSMETRIC_HISTORY View for a CDB (time series chart)
* cs_cpu_sysmetric_for_pdb_mem_chart.sql - CPU System Metrics as per V$CON_SYSMETRIC_HISTORY View for a PDB (time series chart)
* cs_cpu_sysmetric_for_cdb_hist_chart.sql - CPU System Metrics as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (time series chart)
* cs_cpu_sysmetric_for_pdb_hist_chart.sql - CPU System Metrics as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (time series chart)
System Stats and Events
-----------------------
* cs_sysstat_hist_chart.sql - Subset of System Statistics from AWR (time series chart)
* cs_sysstat_hist_chart_io.sql - IO System Statistics from AWR (time series chart)
* cs_system_event_hist_latency_chart.sql - Subset of System Event Latency from AWR (time series chart)
* cs_system_event_hist_load_char.sql - Subset of System Event AAS Load from AWR (time series chart)
* cs_system_event_hist_total_waits_chart.sql - Subset of System Event Total Waits from AWR (time series chart)
* cs_system_event_histogram_chart.sql - One System Event AAS Load Histogram from AWR as per Latency Bucket (time series chart)
* cs_sqlarea_per_pdb.sql - SQL Area per PDB
* cs_pga_consumers.sql - PGA Consumption per Process
* cs_resource_limit_chart.sql - Resource Limit (time series chart)
* cs_total_and_parse_cpu_to_db_chart.sql - Total and Parse CPU-to-DB Ratio from AWR (time series chart)
* cs_total_and_parse_db_and_cpu_aas_chart.sql - Total and Parse DB and CPU Average Active Sessions (AAS) from AWR (time series chart)
Configuration
-------------
* cs_fix_configuration_and_parameters.sql - Fix database configuration and parameters set incorrectly
* cs_acs_enable.sql - Enable Adaptive Cursor Sharing (ACS)
* cs_acs_disable.sql - Disable Adaptive Cursor Sharing (ACS)
* cs_dba_hist_parameter.sql - System Parameters History
* cs_dg.sql - Data Guard Configuration
* cs_dg_protection_mode_switches.sql - Data Guard Protection Mode Switches as per Log Archive Dest
* cs_sgastat_awr_area_chart.sql - SGA Pools History Chart from AWR
* cs_sgastat_awr_line_chart.sql - SGA Pools History Chart from AWR (include free memory)
* cs_sgastat_awr_report.sql - SGA Pools History Report from AWR (include free memory)
* dba_high_water_mark_statistics.sql - Database High Water Mark (HWM) Statistics
* spfile.sql - SPFILE Parameters (from PDB or CDB)
* pdb_spfile.sql - PDB SPFILE Parameters (from CDB)
* syncup_pdb_parameters_to_standbys.sql - Sync up SPFILE PDB Parameters from Primary into Standby and Bystander
* hidden_parameter.sql - Get value of one hidden parameter
* hidden_parameters.sql - Get value of all hidden parameters
Logs
----
* log.sql - REDO Log on Primary and Standby
* log_history.sql - REDO Log History
* archived_log.sql - Archived Logs list
Traces
------
* cs_diag_trace.sql - Directory path for traces
* alert_log_tail.sql - Last 50 lines of alert log refreshed every 5 seconds 20 times
* cs_alert_log.sql - Get alert log
* cs_LGWR_trc.sql - Get log writer LGWR trace
* cs_DBRM_trc.sql - Get database resource manager DBRM trace
* cs_CKPT_trc.sql - Get check point CKPT trace
* cs_listener_log.sql - Get listener log
* cs_hanganalyze.sql - Generate Hanganalyze Trace
* cs_systemstate.sql - Generate System State Dump Trace
* cs_trace_session.sql - Trace one session given a SID
* trace_10046_sql_id.sql - Turn ON and OFF SQL Trace EVENT 10046 LEVEL 12 on given SQL_ID
* trace_10053_sql_id.sql - Turn ON and OFF SQL Trace EVENT 10053 LEVEL 1 on given SQL_ID
* trace_DUMP_sql_id.sql - DBMS_SQLDIAG.dump_trace SQL_Optimizer on given SQL_ID
* trace_SPM_sql_id.sql - Turn ON and OFF SQL Plan Management Trace on given SQL_ID
* trace_10046_mysid_on.sql - Turn ON SQL Trace EVENT 10046 LEVEL 12 on own Session
* trace_10046_mysid_off.sql - Turn OFF SQL Trace on own Session
* trace_10053_mysid_on.sql - Turn ON CBO EVENT 10053 LEVEL 1 on own Session
* trace_10053_mysid_off.sql - Turn OFF CBO EVENT 10053 on own Session
* trace_10046_10053_mysid_on.sql - Turn ON SQL Trace EVENT 10046 LEVEL 12 and 10053 on own Session
* trace_10046_10053_mysid_off.sql - Turn OFF SQL Trace and 10053 on own Session
Reports
-------
* awrrpt.sql - AWR Report
* awrddrpt.sql - AWR Difference Report
* ashrpt.sql - ASH report
* awrsqrpt.sql - AWR SQL Report
* awr_snapshot.sql - Create AWR snapshot
* cs_dbms_stats_age.sql - DBMS_STATS Age as per "auto optimizer stats collection"
* cs_dbms_stats_gather_database_stats.sql - Execute DBMS_STATS.GATHER_DATABASE_STATS
* cs_dbms_stats_gather_database_stats_job.sql - Execute DBMS_STATS.GATHER_DATABASE_STATS (stand-alone)
* cs_dbms_stats_operations.sql - Generate DBMS_STATS.report_stats_operations
* cs_dbms_stats_auto.sql - Generate DBMS_STATS.report_gather_auto_stats
* cs_amw_report.sql - Automatic Maintenance Window Report
Miscellaneous Utilities
-----------------------
* cs_fs.sql - Find SQL statements matching some string
* cs_mark_sql_hot.sql - Use DBMS_SHARED_POOL.markhot to reduce contention during high concurency hard parse
* cs_unmark_sql_hot.sql - Use DBMS_SHARED_POOL.unmarkhot to undo cs_mark_sql_hot.sql
* pr.sql | cs_pr.sql - Print Table (vertical display of result columns for last query)
* cs_burn_cpu.sql - Burn CPU in multiple cores/threads for some time
* cs_hexdump_to_timestamp.sql - Convert Hexadecimal Dump to Time
* cs_epoch_to_time.sql - Convert Epoch to Time
* cs_time_to_epoch.sql - Convert Time to Epoch
* cs_past_days_to_epoch.sql - Convert Past Days to Epoch
* opatch.sql - Oracle Patch Registry and History
* reason_not_shared.sql - Reasons for not sharing Cursors
* sysdate.sql - Display SYSDATE in Filename safe format and in YYYY-MM-DDTHH24:MI:SS UTC format
* view.sql - Display Text of a given VIEW name
* find_all_privs.sql - Roles and Priviledges for a given User (Pete Finnigan)
Notes
-----
* To use these cscripts scripts, connect to database server as oracle, navigate to cscripts scripts directory, and connect into SQL*Plus as SYS.
* Execute h.sql or help.sql for full list above. Execute ls.sql for a full alphabetical list. Type q to exit.

1
csierra/a.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_active_sessions.sql

1
csierra/aa.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_ash_analytics.sql

1
csierra/aas.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_average_active_sessions.sql

1
csierra/ah.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_ash_awr_sample_report.sql

1
csierra/ahs.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_ash_snap_sample_report.sql

View File

@@ -0,0 +1,8 @@
-- Last 50 lines of alert log refreshed every 5 seconds 20 times
COL alert_log NEW_V alert_log FOR A150;
SELECT d.value||'/alert_'||t.instance||'.log' alert_log FROM v$diag_info d, v$thread t WHERE d.name = 'Diag Trace';
HOS tail -n 50 &&alert_log.
PRO Executing alert_log_tail.sql 20 times...
EXEC DBMS_LOCK.sleep(5);
CLEAR SCREEN;
@@alert_log_tail.sql

1
csierra/am.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_ash_mem_sample_report.sql

16
csierra/archived_log.sql Normal file
View File

@@ -0,0 +1,16 @@
-- archived_log.sql - Archived Logs list
SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
--
COL recid_range FOR A13;
--
SELECT first_time, next_time,
(next_time - first_time) * 24 * 3600 seconds,
ROUND(AVG(blocks * block_size) / POWER(2,30), 3) size_gbs, MIN(recid)||'-'||MAX(recid) recid_range
FROM v$archived_log
WHERE name IS NOT NULL
GROUP BY
first_time, next_time
ORDER BY
first_time, next_time
/

1
csierra/as.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_internal/cs_active_sessions_internal.sql

8
csierra/ashrpt.sql Normal file
View File

@@ -0,0 +1,8 @@
-- ASH report
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
--
HOS cp ashrpt_*.* /tmp
HOS chmod 644 /tmp/ashrpt_*.*
PRO
PRO If you want to preserve script output, execute corresponding scp command below, from a TERM session running on your Mac/PC:
HOS echo "scp $HOSTNAME:/tmp/ashrpt_*.* ."

2
csierra/awr_snapshot.sql Normal file
View File

@@ -0,0 +1,2 @@
-- Create AWR snapshot
EXEC DBMS_WORKLOAD_REPOSITORY.create_snapshot;

8
csierra/awrddrpt.sql Normal file
View File

@@ -0,0 +1,8 @@
-- AWR Difference Report
@$ORACLE_HOME/rdbms/admin/awrddrpt.sql
--
HOS cp awrdiff_*.* /tmp
HOS chmod 644 /tmp/awrdiff_*.*
PRO
PRO If you want to preserve script output, execute corresponding scp command below, from a TERM session running on your Mac/PC:
HOS echo "scp $HOSTNAME:/tmp/awrdiff_*.* ."

8
csierra/awrrpt.sql Normal file
View File

@@ -0,0 +1,8 @@
-- AWR Report
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
--
HOS cp awrrpt_*.* /tmp
HOS chmod 644 /tmp/awrrpt_*.*
PRO
PRO If you want to preserve script output, execute corresponding scp command below, from a TERM session running on your Mac/PC:
HOS echo "scp $HOSTNAME:/tmp/awrrpt_*.* ."

8
csierra/awrsqrpt.sql Normal file
View File

@@ -0,0 +1,8 @@
-- AWR SQL Report
@$ORACLE_HOME/rdbms/admin/awrsqrpt.sql
--
HOS cp awrsqlrpt_*.* /tmp
HOS chmod 644 /tmp/awrsqlrpt_*.*
PRO
PRO If you want to preserve script output, execute corresponding scp command below, from a TERM session running on your Mac/PC:
HOS echo "scp $HOSTNAME:/tmp/awrsqlrpt_*.* ."

1
csierra/bs.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_blocked_sessions_report.sql

7
csierra/cdb.sql Normal file
View File

@@ -0,0 +1,7 @@
-- @@cs_internal/&&cs_set_container_to_cdb_root.
ALTER SESSION SET container = CDB$ROOT;
--
UNDEF 1 2 3 4 5 6 7 8 9 10 11 12;
@@set.sql
CLEAR BREAK COLUMNS COMPUTE;
--

View File

@@ -0,0 +1,185 @@
-- Create cdb_attributes Table and merge_cdb_attributes Procedure for IOD Fleet Inventory
CREATE TABLE c##iod.cdb_attributes (
-- soft PK
version VARCHAR2(10),
db_domain VARCHAR2(64),
db_name VARCHAR2(9),
-- columns
host_name VARCHAR2(64),
disk_config VARCHAR2(16),
host_shape VARCHAR2(64),
host_class VARCHAR2(64),
num_cpu_cores NUMBER,
num_cpu_threads NUMBER,
maxed_out NUMBER,
cdb_weight NUMBER,
load_avg NUMBER,
load_p90 NUMBER,
load_p95 NUMBER,
load_p99 NUMBER,
aas_on_cpu_avg NUMBER,
aas_on_cpu_p90 NUMBER,
aas_on_cpu_p95 NUMBER,
aas_on_cpu_p99 NUMBER,
u02_size_1m NUMBER,
u02_used_1m NUMBER,
u02_available_1m NUMBER,
u02_size NUMBER,
u02_used NUMBER,
u02_available NUMBER,
fs_u02_util_perc NUMBER,
fs_u02_at_80p VARCHAR2(10),
fs_u02_at_90p VARCHAR2(10),
fs_u02_at_95p VARCHAR2(10),
db_version VARCHAR2(17),
dg_members NUMBER,
pdbs NUMBER,
kiev_flag VARCHAR2(1),
kiev_pdbs NUMBER,
wf_flag VARCHAR2(1),
wf_pdbs NUMBER,
casper_flag VARCHAR2(1),
casper_pdbs NUMBER,
-- extension
realm_type VARCHAR2(12), -- Commercial | Government
realm_type_order_by NUMBER,
realm VARCHAR2(12), -- R1, OC1, OC2, OC3, OC4
realm_order_by NUMBER,
region VARCHAR2(64),
region_acronym VARCHAR2(10),
region_order_by NUMBER,
locale VARCHAR2(4),
locale_order_by NUMBER
)
TABLESPACE iod
/
ALTER TABLE c##iod.cdb_attributes ADD (
disk_config VARCHAR2(16),
host_shape VARCHAR2(64),
host_class VARCHAR2(64)
)
/
ALTER TABLE c##iod.cdb_attributes ADD (
db_version VARCHAR2(17)
)
/
CREATE UNIQUE INDEX c##iod.cdb_attributes_pk
ON c##iod.cdb_attributes
(version, db_domain, db_name)
COMPRESS ADVANCED LOW
TABLESPACE IOD
/
-- SELECT * FROM c##iod.cdb_attributes WHERE (version, db_domain, db_name) IN (
-- SELECT DISTINCT version, db_domain, db_name
-- FROM c##iod.cdb_attributes
-- --WHERE version > SYSDATE - 30
-- GROUP BY version, db_domain, db_name
-- HAVING COUNT(*) > 1
-- )
-- /
-- DELETE c##iod.cdb_attributes WHERE version < SYSDATE - 30;
CREATE OR REPLACE
PROCEDURE c##iod.merge_cdb_attributes (
p_version IN VARCHAR2,
p_host_name IN VARCHAR2,
p_db_domain IN VARCHAR2,
p_disk_config IN VARCHAR2,
p_host_shape IN VARCHAR2,
p_host_class IN VARCHAR2,
p_num_cpu_cores IN NUMBER,
p_num_cpu_threads IN NUMBER,
p_maxed_out IN NUMBER,
p_cdb_weight IN NUMBER,
p_load_avg IN NUMBER,
p_load_p90 IN NUMBER,
p_load_p95 IN NUMBER,
p_load_p99 IN NUMBER,
p_aas_on_cpu_avg IN NUMBER,
p_aas_on_cpu_p90 IN NUMBER,
p_aas_on_cpu_p95 IN NUMBER,
p_aas_on_cpu_p99 IN NUMBER,
p_u02_size_1m IN NUMBER,
p_u02_used_1m IN NUMBER,
p_u02_available_1m IN NUMBER,
p_u02_size IN NUMBER,
p_u02_used IN NUMBER,
p_u02_available IN NUMBER,
p_fs_u02_util_perc IN NUMBER,
p_fs_u02_at_80p IN VARCHAR2,
p_fs_u02_at_90p IN VARCHAR2,
p_fs_u02_at_95p IN VARCHAR2,
p_db_name IN VARCHAR2,
p_db_version IN VARCHAR2,
p_dg_members IN NUMBER,
p_pdbs IN NUMBER,
p_kiev_pdbs IN NUMBER,
p_wf_pdbs IN NUMBER,
p_casper_pdbs IN NUMBER
)
IS
r c##iod.cdb_attributes%ROWTYPE;
BEGIN
r.version := p_version;
r.host_name := LOWER(TRIM(p_host_name));
r.db_domain := LOWER(TRIM(p_db_domain));
r.disk_config := LOWER(TRIM(p_disk_config));
r.host_shape := LOWER(TRIM(p_host_shape));
r.host_class := UPPER(TRIM(p_host_class));
r.num_cpu_cores := p_num_cpu_cores;
r.num_cpu_threads := p_num_cpu_threads;
r.maxed_out := p_maxed_out;
r.cdb_weight := p_cdb_weight;
r.load_avg := p_load_avg;
r.load_p90 := p_load_p90;
r.load_p95 := p_load_p95;
r.load_p99 := p_load_p99;
r.aas_on_cpu_avg := p_aas_on_cpu_avg;
r.aas_on_cpu_p90 := p_aas_on_cpu_p90;
r.aas_on_cpu_p95 := p_aas_on_cpu_p95;
r.aas_on_cpu_p99 := p_aas_on_cpu_p99;
r.u02_size_1m := p_u02_size_1m;
r.u02_used_1m := p_u02_used_1m;
r.u02_available_1m := p_u02_available_1m;
r.u02_size := p_u02_size;
r.u02_used := p_u02_used;
r.u02_available := p_u02_available;
r.fs_u02_util_perc := p_fs_u02_util_perc;
r.fs_u02_at_80p := p_fs_u02_at_80p;
r.fs_u02_at_90p := p_fs_u02_at_90p;
r.fs_u02_at_95p := p_fs_u02_at_95p;
r.db_name := UPPER(TRIM(p_db_name));
r.db_version := TRIM(p_db_version);
r.dg_members := p_dg_members;
r.pdbs := p_pdbs;
r.kiev_pdbs := p_kiev_pdbs;
r.wf_pdbs := p_wf_pdbs;
r.casper_pdbs := p_casper_pdbs;
--
r.region := C##IOD.IOD_META_AUX.get_region(r.host_name);
r.locale := C##IOD.IOD_META_AUX.get_locale(r.db_domain);
r.locale_order_by := C##IOD.IOD_META_AUX.get_locale_order_by(r.db_domain);
r.realm_type := C##IOD.IOD_META_AUX.get_realm_type(r.region);
IF r.realm_type = 'C' THEN r.realm_type := 'Commercial'; ELSE r.realm_type := 'Government'; END IF;
r.realm_type_order_by := C##IOD.IOD_META_AUX.get_realm_type_order_by(r.region);
r.realm := C##IOD.IOD_META_AUX.get_realm(r.region);
r.realm_order_by := C##IOD.IOD_META_AUX.get_realm_order_by(r.region);
r.region_acronym := C##IOD.IOD_META_AUX.get_region_acronym(r.region);
r.region_order_by := C##IOD.IOD_META_AUX.get_region_order_by(r.region);
--
IF p_kiev_pdbs > 0 THEN r.kiev_flag := 'Y'; ELSE r.kiev_flag := 'N'; END IF;
IF p_wf_pdbs > 0 THEN r.wf_flag := 'Y'; ELSE r.wf_flag := 'N'; END IF;
IF p_casper_pdbs > 0 THEN r.casper_flag := 'Y'; ELSE r.casper_flag := 'N'; END IF;
--
DELETE c##iod.cdb_attributes WHERE version = r.version AND db_domain = r.db_domain AND db_name = r.db_name;
INSERT INTO c##iod.cdb_attributes VALUES r;
COMMIT;
END merge_cdb_attributes;
/
SHOW ERRORS;

View File

@@ -0,0 +1,69 @@
-- Application Tablespace Inventory for all PDBs
SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
SET RECSEP OFF;
--
CLEAR BREAK COMPUTE;
COL pdb_tablespace_name1 FOR A35 HEA 'PDB|TABLESPACE_NAME';
COL pdb_tablespace_name2 FOR A35 HEA 'PDB|TABLESPACE_NAME';
COL used_space_gbs1 FOR 999,990.000 HEA 'USED_SPACE|(GB)';
COL used_space_gbs2 FOR 999,990.000 HEA 'USED_SPACE|(GB)';
COL max_size_gbs1 FOR 999,990.000 HEA 'MAX_SIZE|(GB)';
COL max_size_gbs2 FOR 999,990.000 HEA 'MAX_SIZE|(GB)';
COL used_percent1 FOR 990.000 HEA 'USED|PERCENT';
COL used_percent2 FOR 990.000 HEA 'USED|PERCENT';
--
BREAK ON REPORT;
COMPUTE SUM LABEL 'TOTAL' OF used_space_gbs1 max_size_gbs1 used_space_gbs2 max_size_gbs2 ON REPORT;
--
COL output_file_name NEW_V output_file_name NOPRI;
SELECT 'cdb_tablespace_usage_metrics_'||LOWER(name)||'_'||LOWER(REPLACE(SUBSTR(host_name, 1 + INSTR(host_name, '.', 1, 2), 30), '.', '_'))||'_'||TO_CHAR(SYSDATE, 'yyyymmdd"T"hh24miss') output_file_name FROM v$database, v$instance;
--
SPO &&output_file_name..txt;
PRO
PRO SQL> @cdb_tablespace_usage_metrics.sql
PRO
PRO &&output_file_name..txt;
PRO
WITH
t AS (
SELECT c.name||'('||c.con_id||')' pdb,
m.tablespace_name,
ROUND(m.used_percent, 3) used_percent, -- as per maximum size (considering auto extend)
ROUND(m.used_space * t.block_size / POWER(10, 9), 3) used_space_gbs,
ROUND(m.tablespace_size * t.block_size / POWER(10, 9), 3) max_size_gbs,
ROW_NUMBER() OVER (ORDER BY c.name, m.tablespace_name) row_number1,
ROW_NUMBER() OVER (ORDER BY m.used_percent DESC, m.used_space * t.block_size DESC, m.tablespace_size * t.block_size DESC) row_number2
FROM cdb_tablespace_usage_metrics m,
cdb_tablespaces t,
v$containers c
WHERE t.con_id = m.con_id
AND t.tablespace_name = m.tablespace_name
AND t.status = 'ONLINE'
AND t.contents = 'PERMANENT'
AND t.tablespace_name NOT IN ('SYSTEM', 'SYSAUX')
AND c.con_id = m.con_id
AND c.open_mode = 'READ WRITE'
)
SELECT t1.pdb||CHR(10)||' '||
t1.tablespace_name pdb_tablespace_name1,
t1.used_percent used_percent1,
t1.used_space_gbs used_space_gbs1,
t1.max_size_gbs max_size_gbs1,
'|'||CHR(10)||'|' "|",
t2.used_percent used_percent2,
t2.used_space_gbs used_space_gbs2,
t2.max_size_gbs max_size_gbs2,
t2.pdb||CHR(10)||' '||
t2.tablespace_name pdb_tablespace_name2
FROM t t1, t t2
WHERE t1.row_number1 = t2.row_number2
ORDER BY
t1.row_number1
/
PRO
PRO &&output_file_name..txt;
PRO
SPO OFF;
--
CLEAR BREAK COMPUTE;

View File

@@ -0,0 +1,500 @@
-- Transfer (copy) a SQL Profile from PDBx on CDBa into PDBy on CDBb
SPO coe_xfr_sql_profile.log;
SET DEF ON TERM OFF ECHO ON FEED OFF VER OFF HEA ON LIN 2000 PAGES 100 LONG 8000000 LONGC 800000 TRIMS ON TI OFF TIMI OFF SERVEROUT ON SIZE 1000000 NUMF "" SQLP SQL>;
SET SERVEROUT ON SIZE UNL;
REM
REM $Header: coe_xfr_sql_profile.sql 2020/03/10 carlos.sierra $
REM
REM AUTHOR
REM Carlos Sierra
REM
REM SCRIPT
REM coe_xfr_sql_profile.sql
REM
REM DESCRIPTION
REM This script generates another that contains the commands to
REM create a manual custom SQL Profile out of a known plan from
REM memory or AWR. The manual custom profile can be implemented
REM into the same SOURCE system where the plan was retrieved,
REM or into another similar TARGET system that has same schema
REM objects referenced by the SQL that generated the known plan.
REM
REM PRE-REQUISITES
REM 1. Oracle Tuning Pack license.
REM
REM PARAMETERS
REM 1. SQL_ID (required)
REM 2. Plan Hash Value for which a manual custom SQL Profile is
REM needed (required). A list of known plans is presented.
REM You may choose from list provided or enter a valid phv
REM from a version of the SQL modified with Hints.
REM
REM EXECUTION
REM 1. Connect into SQL*Plus as user with access to data dictionary.
REM Do not use SYS.
REM 2. Execute script coe_xfr_sql_profile.sql passing SQL_ID and
REM plan hash value (parameters can be passed inline or until
REM requested).
REM
REM EXAMPLE
REM # sqlplus system
REM SQL> START coe_xfr_sql_profile.sql [SQL_ID] [PLAN_HASH_VALUE];
REM SQL> START coe_xfr_sql_profile.sql gnjy0mn4y9pbm 2055843663;
REM SQL> START coe_xfr_sql_profile.sql gnjy0mn4y9pbm;
REM SQL> START coe_xfr_sql_profile.sql;
REM
REM NOTES
REM 1. For possible errors see coe_xfr_sql_profile.log
REM 2. If SQLT is installed in SOURCE, you can use instead:
REM sqlt/utl/sqltprofile.sql
REM 3. Be aware that using DBMS_SQLTUNE requires a license for
REM Oracle Tuning Pack.
REM 4. Use a DBA user but not SYS.
REM 5. If you get "ORA-06532: Subscript outside of limit, ORA-06512: at line 1"
REM Then you may consider this change (only in a test and disposable system):
REM create or replace TYPE sys.sqlprof_attr AS VARRAY(5000) of VARCHAR2(500);
REM
SET TERM ON ECHO OFF;
PRO
PRO Parameter 1:
PRO SQL_ID (required)
PRO
DEF sql_id = '&1.';
UNDEF 1;
PRO
WITH
p AS (
SELECT plan_hash_value
FROM gv$sql_plan
WHERE sql_id = TRIM('&&sql_id.')
AND other_xml IS NOT NULL
UNION
SELECT plan_hash_value
FROM dba_hist_sql_plan
WHERE sql_id = TRIM('&&sql_id.')
AND dbid = (SELECT dbid FROM v$database)
AND other_xml IS NOT NULL ),
m AS (
SELECT plan_hash_value,
SUM(elapsed_time)/SUM(executions) avg_et_secs,
SUM(executions) executions
FROM gv$sql
WHERE sql_id = TRIM('&&sql_id.')
AND executions > 0
GROUP BY
plan_hash_value ),
a AS (
SELECT plan_hash_value,
SUM(elapsed_time_delta)/SUM(executions_delta) avg_et_secs,
SUM(executions_delta) executions
FROM dba_hist_sqlstat
WHERE sql_id = TRIM('&&sql_id.')
AND executions_delta > 0
GROUP BY
plan_hash_value )
SELECT
TO_CHAR(ROUND(m.avg_et_secs/1e6, 6), '999,990.000000') avg_et_secs_mem,
TO_CHAR(ROUND(a.avg_et_secs/1e6, 6), '999,990.000000') avg_et_secs_awr,
p.plan_hash_value,
m.executions executions_mem,
a.executions executions_awr
--TO_CHAR(ROUND(NVL(m.avg_et_secs, a.avg_et_secs)/1e6, 6), '999,990.000000') avg_et_secs
FROM p, m, a
WHERE p.plan_hash_value = m.plan_hash_value(+)
AND p.plan_hash_value = a.plan_hash_value(+)
ORDER BY
NVL(m.avg_et_secs, a.avg_et_secs) NULLS LAST, a.avg_et_secs;
PRO
PRO Parameter 2:
PRO PLAN_HASH_VALUE (required)
PRO
DEF plan_hash_value = '&2';
UNDEF 2;
PRO
PRO Values passed to coe_xfr_sql_profile:
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PRO SQL_ID : "&&sql_id."
PRO PLAN_HASH_VALUE: "&&plan_hash_value."
PRO
SET TERM OFF ECHO ON;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
-- trim parameters
COL sql_id NEW_V sql_id FOR A30;
COL plan_hash_value NEW_V plan_hash_value FOR A30;
SELECT TRIM('&&sql_id.') sql_id, TRIM('&&plan_hash_value.') plan_hash_value FROM DUAL;
VAR sql_text CLOB;
VAR sql_text2 CLOB;
VAR other_xml CLOB;
EXEC :sql_text := NULL;
EXEC :sql_text2 := NULL;
EXEC :other_xml := NULL;
-- get sql_text from memory
DECLARE
l_sql_text VARCHAR2(32767);
BEGIN -- 10g see bug 5017909
FOR i IN (SELECT DISTINCT piece, sql_text
FROM gv$sqltext_with_newlines
WHERE sql_id = TRIM('&&sql_id.')
ORDER BY 1, 2)
LOOP
IF :sql_text IS NULL THEN
DBMS_LOB.CREATETEMPORARY(:sql_text, TRUE);
DBMS_LOB.OPEN(:sql_text, DBMS_LOB.LOB_READWRITE);
END IF;
-- removes NUL characters
l_sql_text := REPLACE(i.sql_text, CHR(00), ' ');
-- adds a NUL character at the end of each line
DBMS_LOB.WRITEAPPEND(:sql_text, LENGTH(l_sql_text) + 1, l_sql_text||CHR(00));
END LOOP;
-- if found in memory then sql_text is not null
IF :sql_text IS NOT NULL THEN
DBMS_LOB.CLOSE(:sql_text);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting sql_text from memory: '||SQLERRM);
:sql_text := NULL;
END;
/
SELECT :sql_text FROM DUAL;
-- get sql_text from awr
DECLARE
l_sql_text VARCHAR2(32767);
l_clob_size NUMBER;
l_offset NUMBER;
BEGIN
IF :sql_text IS NULL OR NVL(DBMS_LOB.GETLENGTH(:sql_text), 0) = 0 THEN
SELECT sql_text
INTO :sql_text2
FROM dba_hist_sqltext
WHERE sql_id = TRIM('&&sql_id.')
AND sql_text IS NOT NULL
AND ROWNUM = 1;
END IF;
-- if found in awr then sql_text2 is not null
IF :sql_text2 IS NOT NULL THEN
l_clob_size := NVL(DBMS_LOB.GETLENGTH(:sql_text2), 0);
l_offset := 1;
DBMS_LOB.CREATETEMPORARY(:sql_text, TRUE);
DBMS_LOB.OPEN(:sql_text, DBMS_LOB.LOB_READWRITE);
-- store in clob as 64 character pieces plus a NUL character at the end of each piece
WHILE l_offset < l_clob_size
LOOP
IF l_clob_size - l_offset > 64 THEN
l_sql_text := REPLACE(DBMS_LOB.SUBSTR(:sql_text2, 64, l_offset), CHR(00), ' ');
ELSE -- last piece
l_sql_text := REPLACE(DBMS_LOB.SUBSTR(:sql_text2, l_clob_size - l_offset + 1, l_offset), CHR(00), ' ');
END IF;
DBMS_LOB.WRITEAPPEND(:sql_text, LENGTH(l_sql_text) + 1, l_sql_text||CHR(00));
l_offset := l_offset + 64;
END LOOP;
DBMS_LOB.CLOSE(:sql_text);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting sql_text from awr: '||SQLERRM);
:sql_text := NULL;
END;
/
SELECT :sql_text2 FROM DUAL;
SELECT :sql_text FROM DUAL;
-- validate sql_text
SET TERM ON;
BEGIN
IF :sql_text IS NULL THEN
RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
END IF;
END;
/
SET TERM OFF;
-- get other_xml from memory
BEGIN
FOR i IN (SELECT other_xml
FROM gv$sql_plan
WHERE sql_id = TRIM('&&sql_id.')
AND plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
AND other_xml IS NOT NULL
ORDER BY
child_number, id)
LOOP
:other_xml := i.other_xml;
EXIT; -- 1st
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting other_xml from memory: '||SQLERRM);
:other_xml := NULL;
END;
/
-- get other_xml from awr
BEGIN
IF :other_xml IS NULL OR NVL(DBMS_LOB.GETLENGTH(:other_xml), 0) = 0 THEN
FOR i IN (SELECT other_xml
FROM dba_hist_sql_plan
WHERE sql_id = TRIM('&&sql_id.')
AND plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
AND dbid = (SELECT dbid FROM v$database)
AND other_xml IS NOT NULL
ORDER BY
id)
LOOP
:other_xml := i.other_xml;
EXIT; -- 1st
END LOOP;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting other_xml from awr: '||SQLERRM);
:other_xml := NULL;
END;
/
-- get other_xml from memory from modified SQL
BEGIN
IF :other_xml IS NULL OR NVL(DBMS_LOB.GETLENGTH(:other_xml), 0) = 0 THEN
FOR i IN (SELECT other_xml
FROM gv$sql_plan
WHERE plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
--WHERE full_plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
AND other_xml IS NOT NULL
ORDER BY
child_number, id)
LOOP
:other_xml := i.other_xml;
EXIT; -- 1st
END LOOP;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting other_xml from memory: '||SQLERRM);
:other_xml := NULL;
END;
/
-- get other_xml from awr from modified SQL
BEGIN
IF :other_xml IS NULL OR NVL(DBMS_LOB.GETLENGTH(:other_xml), 0) = 0 THEN
FOR i IN (SELECT other_xml
FROM dba_hist_sql_plan
WHERE plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
--WHERE full_plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
AND dbid = (SELECT dbid FROM v$database)
AND other_xml IS NOT NULL
ORDER BY
id)
LOOP
:other_xml := i.other_xml;
EXIT; -- 1st
END LOOP;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('getting other_xml from awr: '||SQLERRM);
:other_xml := NULL;
END;
/
SELECT :other_xml FROM DUAL;
-- validate other_xml
SET TERM ON;
BEGIN
IF :other_xml IS NULL THEN
RAISE_APPLICATION_ERROR(-20101, 'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
END IF;
END;
/
SET TERM OFF;
-- generates script that creates sql profile in target system:
SET ECHO OFF;
PRO coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql.
SET FEED OFF LIN 666 TRIMS ON TI OFF TIMI OFF SERVEROUT ON SIZE 1000000 FOR WOR;
SET SERVEROUT ON SIZE UNL FOR WOR;
SPO OFF;
SPO coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql;
DECLARE
l_pos NUMBER;
l_clob_size NUMBER;
l_offset NUMBER;
l_sql_text VARCHAR2(32767);
l_len NUMBER;
l_hint VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('SPO coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..log;');
DBMS_OUTPUT.PUT_LINE('SET ECHO ON TERM ON LIN 2000 TRIMS ON NUMF 99999999999999999999;');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM $Header: 215187.1 coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql 11.4.4.4 '||TO_CHAR(SYSDATE, 'YYYY/MM/DD')||' carlos.sierra $');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM Copyright (c) 2000-2012, Oracle Corporation. All rights reserved.');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM AUTHOR');
DBMS_OUTPUT.PUT_LINE('REM carlos.sierra@oracle.com');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM SCRIPT');
DBMS_OUTPUT.PUT_LINE('REM coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM DESCRIPTION');
DBMS_OUTPUT.PUT_LINE('REM This script is generated by coe_xfr_sql_profile.sql');
DBMS_OUTPUT.PUT_LINE('REM It contains the SQL*Plus commands to create a custom');
DBMS_OUTPUT.PUT_LINE('REM SQL Profile for SQL_ID &&sql_id. based on plan hash');
DBMS_OUTPUT.PUT_LINE('REM value &&plan_hash_value..');
DBMS_OUTPUT.PUT_LINE('REM The custom SQL Profile to be created by this script');
DBMS_OUTPUT.PUT_LINE('REM will affect plans for SQL commands with signature');
DBMS_OUTPUT.PUT_LINE('REM matching the one for SQL Text below.');
DBMS_OUTPUT.PUT_LINE('REM Review SQL Text and adjust accordingly.');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM PARAMETERS');
DBMS_OUTPUT.PUT_LINE('REM None.');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM EXAMPLE');
DBMS_OUTPUT.PUT_LINE('REM SQL> START coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql;');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('REM NOTES');
DBMS_OUTPUT.PUT_LINE('REM 1. Should be run as SYSTEM or SYSDBA.');
DBMS_OUTPUT.PUT_LINE('REM 2. User must have CREATE ANY SQL PROFILE privilege.');
DBMS_OUTPUT.PUT_LINE('REM 3. SOURCE and TARGET systems can be the same or similar.');
DBMS_OUTPUT.PUT_LINE('REM 4. To drop this custom SQL Profile after it has been created:');
DBMS_OUTPUT.PUT_LINE('REM EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE(''coe_&&sql_id._&&plan_hash_value.'');');
DBMS_OUTPUT.PUT_LINE('REM 5. Be aware that using DBMS_SQLTUNE requires a license');
DBMS_OUTPUT.PUT_LINE('REM for the Oracle Tuning Pack.');
DBMS_OUTPUT.PUT_LINE('REM 6. If you modified a SQL putting Hints in order to produce a desired');
DBMS_OUTPUT.PUT_LINE('REM Plan, you can remove the artifical Hints from SQL Text pieces below.');
DBMS_OUTPUT.PUT_LINE('REM By doing so you can create a custom SQL Profile for the original');
DBMS_OUTPUT.PUT_LINE('REM SQL but with the Plan captured from the modified SQL (with Hints).');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('WHENEVER SQLERROR EXIT SQL.SQLCODE;');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('VAR signature NUMBER;');
DBMS_OUTPUT.PUT_LINE('VAR signaturef NUMBER;');
DBMS_OUTPUT.PUT_LINE('REM');
DBMS_OUTPUT.PUT_LINE('DECLARE');
DBMS_OUTPUT.PUT_LINE('sql_txt CLOB;');
DBMS_OUTPUT.PUT_LINE('h SYS.SQLPROF_ATTR;');
DBMS_OUTPUT.PUT_LINE('PROCEDURE wa (p_line IN VARCHAR2) IS');
DBMS_OUTPUT.PUT_LINE('BEGIN');
DBMS_OUTPUT.PUT_LINE('DBMS_LOB.WRITEAPPEND(sql_txt, LENGTH(p_line), p_line);');
DBMS_OUTPUT.PUT_LINE('END wa;');
DBMS_OUTPUT.PUT_LINE('BEGIN');
DBMS_OUTPUT.PUT_LINE('DBMS_LOB.CREATETEMPORARY(sql_txt, TRUE);');
DBMS_OUTPUT.PUT_LINE('DBMS_LOB.OPEN(sql_txt, DBMS_LOB.LOB_READWRITE);');
DBMS_OUTPUT.PUT_LINE('-- SQL Text pieces below do not have to be of same length.');
DBMS_OUTPUT.PUT_LINE('-- So if you edit SQL Text (i.e. removing temporary Hints),');
DBMS_OUTPUT.PUT_LINE('-- there is no need to edit or re-align unmodified pieces.');
l_clob_size := NVL(DBMS_LOB.GETLENGTH(:sql_text), 0);
l_offset := 1;
WHILE l_offset < l_clob_size
LOOP
l_pos := DBMS_LOB.INSTR(:sql_text, CHR(00), l_offset);
IF l_pos > 0 THEN
l_len := l_pos - l_offset;
ELSE -- last piece
l_len := l_clob_size - l_pos + 1;
END IF;
l_sql_text := DBMS_LOB.SUBSTR(:sql_text, l_len, l_offset);
/* cannot do such 3 replacement since a line could end with a comment using "--"
l_sql_text := REPLACE(l_sql_text, CHR(10), ' '); -- replace LF with SP
l_sql_text := REPLACE(l_sql_text, CHR(13), ' '); -- replace CR with SP
l_sql_text := REPLACE(l_sql_text, CHR(09), ' '); -- replace TAB with SP
*/
l_offset := l_offset + l_len + 1;
IF l_len > 0 THEN
IF INSTR(l_sql_text, '''[') + INSTR(l_sql_text, ']''') = 0 THEN
l_sql_text := '['||l_sql_text||']';
ELSIF INSTR(l_sql_text, '''{') + INSTR(l_sql_text, '}''') = 0 THEN
l_sql_text := '{'||l_sql_text||'}';
ELSIF INSTR(l_sql_text, '''<') + INSTR(l_sql_text, '>''') = 0 THEN
l_sql_text := '<'||l_sql_text||'>';
ELSIF INSTR(l_sql_text, '''(') + INSTR(l_sql_text, ')''') = 0 THEN
l_sql_text := '('||l_sql_text||')';
ELSIF INSTR(l_sql_text, '''"') + INSTR(l_sql_text, '"''') = 0 THEN
l_sql_text := '"'||l_sql_text||'"';
ELSIF INSTR(l_sql_text, '''|') + INSTR(l_sql_text, '|''') = 0 THEN
l_sql_text := '|'||l_sql_text||'|';
ELSIF INSTR(l_sql_text, '''~') + INSTR(l_sql_text, '~''') = 0 THEN
l_sql_text := '~'||l_sql_text||'~';
ELSIF INSTR(l_sql_text, '''^') + INSTR(l_sql_text, '^''') = 0 THEN
l_sql_text := '^'||l_sql_text||'^';
ELSIF INSTR(l_sql_text, '''@') + INSTR(l_sql_text, '@''') = 0 THEN
l_sql_text := '@'||l_sql_text||'@';
ELSIF INSTR(l_sql_text, '''#') + INSTR(l_sql_text, '#''') = 0 THEN
l_sql_text := '#'||l_sql_text||'#';
ELSIF INSTR(l_sql_text, '''%') + INSTR(l_sql_text, '%''') = 0 THEN
l_sql_text := '%'||l_sql_text||'%';
ELSIF INSTR(l_sql_text, '''$') + INSTR(l_sql_text, '$''') = 0 THEN
l_sql_text := '$'||l_sql_text||'$';
ELSE
l_sql_text := CHR(96)||l_sql_text||CHR(96);
END IF;
DBMS_OUTPUT.PUT_LINE('wa(q'''||l_sql_text||''');');
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('DBMS_LOB.CLOSE(sql_txt);');
DBMS_OUTPUT.PUT_LINE('h := SYS.SQLPROF_ATTR(');
DBMS_OUTPUT.PUT_LINE('q''[BEGIN_OUTLINE_DATA]'',');
FOR i IN (SELECT /*+ opt_param('parallel_execution_enabled', 'false') */
SUBSTR(EXTRACTVALUE(VALUE(d), '/hint'), 1, 4000) hint
FROM TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE(:other_xml), '/*/outline_data/hint'))) d)
LOOP
l_hint := i.hint;
WHILE NVL(LENGTH(l_hint), 0) > 0
LOOP
IF LENGTH(l_hint) <= 500 THEN
DBMS_OUTPUT.PUT_LINE('q''['||l_hint||']'',');
l_hint := NULL;
ELSE
l_pos := INSTR(SUBSTR(l_hint, 1, 500), ' ', -1);
DBMS_OUTPUT.PUT_LINE('q''['||SUBSTR(l_hint, 1, l_pos)||']'',');
l_hint := ' '||SUBSTR(l_hint, l_pos);
END IF;
END LOOP;
END LOOP;
DBMS_OUTPUT.PUT_LINE('q''[END_OUTLINE_DATA]'');');
DBMS_OUTPUT.PUT_LINE(':signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt);');
DBMS_OUTPUT.PUT_LINE(':signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);');
DBMS_OUTPUT.PUT_LINE('DBMS_SQLTUNE.IMPORT_SQL_PROFILE (');
DBMS_OUTPUT.PUT_LINE('sql_text => sql_txt,');
DBMS_OUTPUT.PUT_LINE('profile => h,');
DBMS_OUTPUT.PUT_LINE('name => ''coe_&&sql_id._&&plan_hash_value.'',');
DBMS_OUTPUT.PUT_LINE('description => ''coe &&sql_id. &&plan_hash_value. ''||:signature||'' ''||:signaturef||'''',');
DBMS_OUTPUT.PUT_LINE('category => ''DEFAULT'',');
DBMS_OUTPUT.PUT_LINE('validate => TRUE,');
DBMS_OUTPUT.PUT_LINE('replace => TRUE,');
DBMS_OUTPUT.PUT_LINE('force_match => FALSE /* TRUE:FORCE (match even when different literals in SQL). FALSE:EXACT (similar to CURSOR_SHARING) */ );');
DBMS_OUTPUT.PUT_LINE('DBMS_LOB.FREETEMPORARY(sql_txt);');
DBMS_OUTPUT.PUT_LINE('END;');
DBMS_OUTPUT.PUT_LINE('/');
DBMS_OUTPUT.PUT_LINE('WHENEVER SQLERROR CONTINUE');
DBMS_OUTPUT.PUT_LINE('SET ECHO OFF;');
DBMS_OUTPUT.PUT_LINE('PRINT signature');
DBMS_OUTPUT.PUT_LINE('PRINT signaturef');
DBMS_OUTPUT.PUT_LINE('PRO');
DBMS_OUTPUT.PUT_LINE('PRO ... manual custom SQL Profile has been created');
DBMS_OUTPUT.PUT_LINE('PRO');
DBMS_OUTPUT.PUT_LINE('SET TERM ON ECHO OFF LIN 80 TRIMS OFF NUMF "";');
DBMS_OUTPUT.PUT_LINE('SPO OFF;');
DBMS_OUTPUT.PUT_LINE('PRO');
DBMS_OUTPUT.PUT_LINE('PRO COE_XFR_SQL_PROFILE_&&sql_id._&&plan_hash_value. completed');
END;
/
SPO OFF;
SET DEF ON TERM ON ECHO OFF FEED 6 VER ON HEA ON LIN 80 PAGES 14 LONG 80 LONGC 80 TRIMS OFF TI OFF TIMI OFF SERVEROUT OFF NUMF "" SQLP SQL>;
SET SERVEROUT OFF;
PRO
PRO Execute coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql
PRO on TARGET system in order to create a custom SQL Profile
PRO with plan &&plan_hash_value linked to adjusted sql_text.
PRO
UNDEFINE 1 2 sql_id plan_hash_value
CL COL
PRO
PRO COE_XFR_SQL_PROFILE completed.

1
csierra/cpu.sql Normal file
View File

@@ -0,0 +1 @@
@@cs_cpu_demand.sql

View File

@@ -0,0 +1,108 @@
-- Create SQL Plan Baselin from AWR Plan
SET PAGES 200 LONG 80000;
ACC sql_id PROMPT 'Enter SQL_ID: ';
WITH
p AS (
SELECT plan_hash_value
FROM dba_hist_sql_plan
WHERE sql_id = TRIM('&&sql_id.')
AND dbid = (SELECT dbid FROM v$database)
AND other_xml IS NOT NULL ),
a AS (
SELECT plan_hash_value,
SUM(elapsed_time_total)/SUM(executions_total) avg_et_secs,
MAX(executions_total) executions_total
FROM dba_hist_sqlstat
WHERE sql_id = TRIM('&&sql_id.')
AND executions_total > 0
GROUP BY
plan_hash_value )
SELECT p.plan_hash_value,
ROUND(a.avg_et_secs/1e6, 6) avg_et_secs,
a.executions_total
FROM p, a
WHERE p.plan_hash_value = a.plan_hash_value(+)
ORDER BY
avg_et_secs NULLS LAST;
ACC plan_hash_value PROMPT 'Enter Plan Hash Value: ';
COL dbid NEW_V dbid NOPRI;
SELECT dbid FROM v$database;
COL begin_snap_id NEW_V begin_snap_id NOPRI;
COL end_snap_id NEW_V end_snap_id NOPRI;
SELECT MIN(p.snap_id) begin_snap_id, MAX(p.snap_id) end_snap_id
FROM dba_hist_sqlstat p,
dba_hist_snapshot s
WHERE p.dbid = &&dbid
AND p.sql_id = '&&sql_id.'
AND p.plan_hash_value = TO_NUMBER('&&plan_hash_value.')
AND s.snap_id = p.snap_id
AND s.dbid = p.dbid
AND s.instance_number = p.instance_number;
VAR sqlset_name VARCHAR2(30);
EXEC :sqlset_name := REPLACE('s_&&sql_id._&&plan_hash_value._awr', ' ');
PRINT sqlset_name;
SET SERVEROUT ON;
VAR plans NUMBER;
DECLARE
l_sqlset_name VARCHAR2(30);
l_description VARCHAR2(256);
sts_cur SYS.DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
l_sqlset_name := :sqlset_name;
l_description := 'SQL_ID:&&sql_id., PHV:&&plan_hash_value., BEGIN:&&begin_snap_id., END:&&end_snap_id.';
l_description := REPLACE(REPLACE(l_description, ' '), ',', ', ');
BEGIN
DBMS_OUTPUT.put_line('dropping sqlset: '||l_sqlset_name);
SYS.DBMS_SQLTUNE.drop_sqlset (
sqlset_name => l_sqlset_name,
sqlset_owner => USER );
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line(SQLERRM||' while trying to drop STS: '||l_sqlset_name||' (safe to ignore)');
END;
l_sqlset_name :=
SYS.DBMS_SQLTUNE.create_sqlset (
sqlset_name => l_sqlset_name,
description => l_description,
sqlset_owner => USER );
DBMS_OUTPUT.put_line('created sqlset: '||l_sqlset_name);
OPEN sts_cur FOR
SELECT VALUE(p)
FROM TABLE(DBMS_SQLTUNE.select_workload_repository (&&begin_snap_id., &&end_snap_id.,
'sql_id = ''&&sql_id.'' AND plan_hash_value = TO_NUMBER(''&&plan_hash_value.'') AND loaded_versions > 0',
NULL, NULL, NULL, NULL, 1, NULL, 'ALL')) p;
SYS.DBMS_SQLTUNE.load_sqlset (
sqlset_name => l_sqlset_name,
populate_cursor => sts_cur );
DBMS_OUTPUT.put_line('loaded sqlset: '||l_sqlset_name);
CLOSE sts_cur;
:plans := DBMS_SPM.load_plans_from_sqlset (
sqlset_name => l_sqlset_name,
sqlset_owner => USER );
END;
/
PRINT plans;
SET PAGES 14 LONG 80 ECHO OFF SERVEROUT OFF;
UNDEF sql_id plan_hash_value
CL COL

View File

@@ -0,0 +1,35 @@
REM $Header: 215187.1 create_spb_from_cur.sql 12.1.02 2013/09/09 carlos.sierra $
-- Create SQL Plan Baseline from SQL Cursor
ACC sql_text_piece PROMPT 'Enter SQL Text piece: '
SET PAGES 200 LONG 80000 ECHO ON;
COL sql_text PRI;
SELECT sql_id, sql_text /* exclude_me */
FROM v$sqlarea
WHERE sql_text LIKE '%&&sql_text_piece.%'
AND sql_text NOT LIKE '%/* exclude_me */%';
ACC sql_id PROMPT 'Enter SQL_ID: ';
SELECT plan_hash_value, SUM(executions) executions, SUM(elapsed_time) elapsed_time, /* exclude_me */
CASE WHEN SUM(executions) > 0 THEN ROUND(SUM(elapsed_time)/SUM(executions)/1e6, 3) END avg_secs_per_exec
FROM v$sql
WHERE sql_id = '&&sql_id.'
GROUP BY
plan_hash_value
ORDER BY
4 DESC NULLS FIRST;
ACC plan_hash_value PROMPT 'Enter Plan Hash Value: ';
VAR plans NUMBER;
EXEC :plans := DBMS_SPM.load_plans_from_cursor_cache('&&sql_id.', TO_NUMBER('&&plan_hash_value.'));
PRINT plans;
SET PAGES 14 LONG 80 ECHO OFF;
UNDEF sql_text_piece sql_id plan_hash_value

44
csierra/cs_CKPT_trc.sql Normal file
View File

@@ -0,0 +1,44 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_CKPT_trc.sql
--
-- Purpose: Get check point CKPT trace
--
-- Author: Carlos Sierra
--
-- Version: 2022/09/08
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_CKPT_trc.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
--
COL trace_dir NEW_V trace_dir FOR A100 NOPRI;
COL ckpt_trc NEW_V ckpt_trc FOR A30 NOPRI;
SELECT d.value AS trace_dir, LOWER('&&cs_db_name._')||LOWER(p.pname)||'_'||p.spid||'.trc' AS ckpt_trc FROM v$diag_info d, v$process p WHERE d.name = 'Diag Trace' AND p.pname = 'CKPT';
--
HOS cat &&trace_dir./&&ckpt_trc.
PRO
PRO &&trace_dir./&&ckpt_trc.
PRO
HOS cp &&trace_dir./&&ckpt_trc. /tmp/
HOS chmod 644 /tmp/&&ckpt_trc.
PRO
PRO Preserved CKPT trace on /tmp
PRO ~~~~~~~~~~~~~~~~~~~~~~~
HOS ls -oX /tmp/&&ckpt_trc.
PRO
PRO If you want to copy CKPT trace file, execute scp command below, from a TERM session running on your Mac/PC:
PRO
PRO scp &&cs_host_name.:/tmp/&&ckpt_trc. &&cs_local_dir.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

172
csierra/cs_LGWR_chart.sql Normal file
View File

@@ -0,0 +1,172 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_LGWR_chart.sql
--
-- Purpose: Log Writer LGWR Slow Writes Duration Chart - from current LGWR trace
--
-- Author: Carlos Sierra
--
-- Version: 2023/01/03
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_LGWR_chart.sql
--
-- Notes: Developed and tested on 19c
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
-- @@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_LGWR_chart';
--
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Log Writer LGWR Slow Writes Duration between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF vaxis_title = 'Milliseconds';
DEF xaxis_title = '';
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
--DEF is_stacked = "isStacked: false,";
DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
--DEF chart_foot_note_2 = "<br>2)";
DEF chart_foot_note_2 = '<br>2) &&xaxis_title.';
DEF chart_foot_note_3 = "<br>";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'Write Duration', id:'01', type:'number'}
PRO ]
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION /* cs_LGWR_chart */ num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
lgwr AS (
SELECT v4.timestamp,
-- TO_CHAR(v4.timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') AS timestamp,
-- v4.payload_size AS payload_size_display,
-- v4.write_duration AS write_duration_display,
TO_NUMBER(REGEXP_REPLACE(v4.write_duration, '[^0-9]', '')) AS write_duration_ms,
TO_NUMBER(REGEXP_REPLACE(v4.payload_size, '[^0-9]', '')) AS payload_size_kb,
ROUND((TO_NUMBER(REGEXP_REPLACE(v4.payload_size, '[^0-9]', ''))) / NULLIF(TO_NUMBER(REGEXP_REPLACE(v4.write_duration, '[^0-9]', '')) / POWER(10,3), 0)) AS kbps
FROM
(
SELECT v3.line_number,
v3.timestamp,
v3.write_duration,
v3.payload_size,
ROW_NUMBER() OVER (PARTITION BY v3.timestamp ORDER BY v3.payload_size DESC) AS rn
FROM
(
SELECT v2.line_number,
LAST_VALUE(v2.timestamp) IGNORE NULLS OVER (ORDER BY v2.line_number ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS timestamp,
v2.write_duration,
v2.payload_size
FROM
(
SELECT v1.line_number,
CASE v1.line_type WHEN 'DATE' THEN CAST(TO_TIMESTAMP_TZ(v1.line_text, 'YYYY-MM-DD"T"HH24:MI:SS.FF6TZH:TZM') AS TIMESTAMP) END AS timestamp,
CASE v1.line_type WHEN 'WRITE' THEN SUBSTR(v1.line_text, 1, INSTR(v1.line_text, ', size ') - 1) END AS write_duration,
CASE v1.line_type WHEN 'WRITE' THEN SUBSTR(v1.line_text, INSTR(v1.line_text, ', size ') + 7) END AS payload_size
FROM
(
SELECT line_number,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN 'DATE' -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN 'DATE'
WHEN payload LIKE 'Warning: log write elapsed time %' THEN 'WRITE'
END AS line_type,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, TO_CHAR(SYSDATE, 'YYYY'))) -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, '20'))
WHEN payload LIKE 'Warning: log write elapsed time %' THEN REPLACE(payload, 'Warning: log write elapsed time ')
END AS line_text
FROM v$diag_trace_file_contents
WHERE trace_filename = (SELECT LOWER(b.name)||'_'||LOWER(p.pname)||'_'||p.spid||'.trc' AS lgwr_trc FROM v$diag_info d, v$process p, v$database b WHERE d.name = 'Diag Trace' AND p.pname = 'LGWR')
) v1
WHERE v1.line_type IN ('DATE', 'WRITE')
AND v1.line_text IS NOT NULL
) v2
) v3
WHERE v3.write_duration||payload_size IS NOT NULL
AND timestamp IS NOT NULL
) v4
WHERE v4.rn = 1
-- AND v4.timestamp > SYSTIMESTAMP - INTERVAL '1' MINUTE
-- ORDER BY v4.line_number
),
/****************************************************************************************/
list AS (
SELECT timestamp AS time,
write_duration_ms AS value_01
FROM lgwr
WHERE timestamp >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND timestamp <= TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
)
/****************************************************************************************/
SELECT /*+ MONITOR GATHER_PLAN_STATISTICS */
', [new Date('||
TO_CHAR(q.time, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(q.time, 'DD')|| /* day */
','||TO_CHAR(q.time, 'HH24')|| /* hour */
','||TO_CHAR(q.time, 'MI')|| /* minute */
','||TO_CHAR(q.time, 'SS')|| /* second */
')'||
','||num_format(q.value_01, 0)||
']'
FROM list q
ORDER BY
q.time
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

116
csierra/cs_LGWR_report.sql Normal file
View File

@@ -0,0 +1,116 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_LGWR_report.sql
--
-- Purpose: Log Writer LGWR Slow Writes Duration Report - from current LGWR trace
--
-- Author: Carlos Sierra
--
-- Version: 2023/01/03
--
-- Usage: Execute connected to PDB or CDB
--
-- Enter range of dates when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_LGWR_report.sql
--
-- Notes: Developed and tested on 19c
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_LGWR_report';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO
PRO Log Writer LGWR Slow Writes Duration
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
COL timestamp FOR A23 HEA 'Log Write|End|Timestamp' TRUNC;
COL write_duration_ms FOR 999,990 HEA 'Write|Duration|(ms)';
COL payload_size_kb FOR 999,999,990 HEA 'Payload|Size|KBs';
COL kbps FOR 999,999,990 HEA 'KBs|per|Sec';
--
SELECT v4.timestamp,
-- TO_CHAR(v4.timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') AS timestamp,
-- v4.payload_size AS payload_size_display,
-- v4.write_duration AS write_duration_display,
TO_NUMBER(REGEXP_REPLACE(v4.write_duration, '[^0-9]', '')) AS write_duration_ms,
TO_NUMBER(REGEXP_REPLACE(v4.payload_size, '[^0-9]', '')) AS payload_size_kb,
ROUND((TO_NUMBER(REGEXP_REPLACE(v4.payload_size, '[^0-9]', ''))) / NULLIF(TO_NUMBER(REGEXP_REPLACE(v4.write_duration, '[^0-9]', '')) / POWER(10,3), 0)) AS kbps
FROM
(
SELECT v3.line_number,
v3.timestamp,
v3.write_duration,
v3.payload_size,
ROW_NUMBER() OVER (PARTITION BY v3.timestamp ORDER BY v3.payload_size DESC) AS rn
FROM
(
SELECT v2.line_number,
LAST_VALUE(v2.timestamp) IGNORE NULLS OVER (ORDER BY v2.line_number ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS timestamp,
v2.write_duration,
v2.payload_size
FROM
(
SELECT v1.line_number,
CASE v1.line_type WHEN 'DATE' THEN CAST(TO_TIMESTAMP_TZ(v1.line_text, 'YYYY-MM-DD"T"HH24:MI:SS.FF6TZH:TZM') AS TIMESTAMP) END AS timestamp,
CASE v1.line_type WHEN 'WRITE' THEN SUBSTR(v1.line_text, 1, INSTR(v1.line_text, ', size ') - 1) END AS write_duration,
CASE v1.line_type WHEN 'WRITE' THEN SUBSTR(v1.line_text, INSTR(v1.line_text, ', size ') + 7) END AS payload_size
FROM
(
SELECT line_number,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN 'DATE' -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN 'DATE'
WHEN payload LIKE 'Warning: log write elapsed time %' THEN 'WRITE'
END AS line_type,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, TO_CHAR(SYSDATE, 'YYYY'))) -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, '20'))
WHEN payload LIKE 'Warning: log write elapsed time %' THEN REPLACE(payload, 'Warning: log write elapsed time ')
END AS line_text
FROM v$diag_trace_file_contents
WHERE trace_filename = (SELECT LOWER(b.name)||'_'||LOWER(p.pname)||'_'||p.spid||'.trc' AS lgwr_trc FROM v$diag_info d, v$process p, v$database b WHERE d.name = 'Diag Trace' AND p.pname = 'LGWR')
) v1
WHERE v1.line_type IN ('DATE', 'WRITE')
AND v1.line_text IS NOT NULL
) v2
) v3
WHERE v3.write_duration||payload_size IS NOT NULL
AND timestamp IS NOT NULL
) v4
WHERE v4.rn = 1
AND v4.timestamp >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND v4.timestamp <= TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
ORDER BY v4.timestamp
/
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."
--
@@cs_internal/cs_spool_tail.sql
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

108
csierra/cs_LGWR_trc.sql Normal file
View File

@@ -0,0 +1,108 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_LGWR_trc.sql
--
-- Purpose: Get log writer LGWR trace
--
-- Author: Carlos Sierra
--
-- Version: 2023/01/03
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_LGWR_trc.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
--
COL trace_dir NEW_V trace_dir FOR A100 NOPRI;
COL lgwr_trc NEW_V lgwr_trc FOR A30 NOPRI;
SELECT d.value AS trace_dir, LOWER('&&cs_db_name._')||LOWER(p.pname)||'_'||p.spid||'.trc' AS lgwr_trc FROM v$diag_info d, v$process p WHERE d.name = 'Diag Trace' AND p.pname = 'LGWR';
--
HOS cat &&trace_dir./&&lgwr_trc.
PRO
PRO LONG WRITES
PRO ~~~~~~~~~~~
COL timestamp FOR A23;
COL write_duration_display FOR A15;
COL payload_size_display FOR A15;
COL write_duration_ms FOR 999,999,999,990;
COL payload_size_kb FOR 999,999,999,990;
COL kbps FOR 999,990.000;
WITH
trace AS (
SELECT d.value AS trace_dir, LOWER(b.name)||'_'||LOWER(p.pname)||'_'||p.spid||'.trc' AS lgwr_trc FROM v$diag_info d, v$process p, v$database b WHERE d.name = 'Diag Trace' AND p.pname = 'LGWR'
),
relevant_lines AS (
SELECT line_number,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN 'DATE' -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN 'DATE'
WHEN payload LIKE 'Warning: log write elapsed time %' THEN 'WRITE'
END AS line_type,
CASE
-- WHEN payload LIKE CHR(10)||'*** '||TO_CHAR(SYSDATE, 'YYYY')||'%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, TO_CHAR(SYSDATE, 'YYYY'))) -- failed after 2023-01-01
WHEN payload LIKE CHR(10)||'*** ____-__-__T__:__:__%' THEN SUBSTR(SUBSTR(payload, 1, INSTR(payload, '(') - 2), INSTR(payload, '20'))
WHEN payload LIKE 'Warning: log write elapsed time %' THEN REPLACE(payload, 'Warning: log write elapsed time ')
END AS line_text
FROM v$diag_trace_file_contents
WHERE trace_filename = (SELECT lgwr_trc FROM trace)
),
parsed_lines AS (
SELECT line_number,
CASE line_type WHEN 'DATE' THEN CAST(TO_TIMESTAMP_TZ(line_text, 'YYYY-MM-DD"T"HH24:MI:SS.FF6TZH:TZM') AS TIMESTAMP) END AS timestamp,
CASE line_type WHEN 'WRITE' THEN SUBSTR(line_text, 1, INSTR(line_text, ', size ') - 1) END AS write_duration,
CASE line_type WHEN 'WRITE' THEN SUBSTR(line_text, INSTR(line_text, ', size ') + 7) END AS payload_size
FROM relevant_lines
WHERE line_type IN ('DATE', 'WRITE')
AND line_text IS NOT NULL
),
normalized_lines AS (
SELECT line_number,
LAST_VALUE(timestamp) IGNORE NULLS OVER (ORDER BY line_number ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS timestamp,
write_duration,
payload_size
FROM parsed_lines
),
filtered_lines AS (
SELECT line_number,
timestamp,
write_duration,
payload_size,
ROW_NUMBER() OVER (PARTITION BY timestamp ORDER BY payload_size DESC) AS rn
FROM normalized_lines
WHERE write_duration||payload_size IS NOT NULL
AND timestamp IS NOT NULL
)
SELECT timestamp,
-- payload_size AS payload_size_display,
-- write_duration AS write_duration_display,
TO_NUMBER(REGEXP_REPLACE(payload_size, '[^0-9]', '')) AS payload_size_kb,
TO_NUMBER(REGEXP_REPLACE(write_duration, '[^0-9]', '')) AS write_duration_ms,
(TO_NUMBER(REGEXP_REPLACE(payload_size, '[^0-9]', ''))) / NULLIF(TO_NUMBER(REGEXP_REPLACE(write_duration, '[^0-9]', '')) / POWER(10,3), 0) AS kbps
FROM filtered_lines
WHERE rn = 1
ORDER BY line_number
/
PRO
PRO &&trace_dir./&&lgwr_trc.
PRO
HOS cp &&trace_dir./&&lgwr_trc. /tmp/
HOS chmod 644 /tmp/&&lgwr_trc.
PRO
PRO Preserved LGWR trace on /tmp
PRO ~~~~~~~~~~~~~~~~~~~~~~~
HOS ls -oX /tmp/&&lgwr_trc.
PRO
PRO If you want to copy LGWR trace file, execute scp command below, from a TERM session running on your Mac/PC:
PRO
PRO scp &&cs_host_name.:/tmp/&&lgwr_trc. &&cs_local_dir.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,51 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_acs_disable.sql
--
-- Purpose: Disable Adaptive Cursor Sharing (ACS)
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/07
--
-- Usage: Connecting into PDB or CDB.
--
-- Confirm when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_acs_disable.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
--
PRO
PRO ***
PRO *** You are about to DISABLE Adaptive Cursor Sharing (ACS) for &&cs_con_name.
PRO ***
PRO
PRO 1. Enter "Yes" (case sensitive) to continue, else <ctrl>-C
DEF cs_confirm = '&1.';
UNDEF 1;
--
SET SERVEROUT ON;
BEGIN
IF '&&cs_confirm.' = 'Yes' THEN
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_adaptive_cursor_sharing" = FALSE';
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_extended_cursor_sharing_rel" = "NONE"';
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_extended_cursor_sharing" = "NONE"';
DBMS_OUTPUT.put_line('Done');
ELSE
DBMS_OUTPUT.put_line('Null');
END IF;
END;
/
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

51
csierra/cs_acs_enable.sql Normal file
View File

@@ -0,0 +1,51 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_acs_enable.sql
--
-- Purpose: Enable Adaptive Cursor Sharing (ACS)
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/07
--
-- Usage: Connecting into PDB or CDB.
--
-- Confirm when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_acs_enable.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
--
PRO
PRO ***
PRO *** You are about to ENABLE Adaptive Cursor Sharing (ACS) for &&cs_con_name.
PRO ***
PRO
PRO 1. Enter "Yes" (case sensitive) to continue, else <ctrl>-C
DEF cs_confirm = '&1.';
UNDEF 1;
--
SET SERVEROUT ON;
BEGIN
IF '&&cs_confirm.' = 'Yes' THEN
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_adaptive_cursor_sharing" = TRUE';
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_extended_cursor_sharing_rel" = "SIMPLE"';
EXECUTE IMMEDIATE 'ALTER SYSTEM SET "_optimizer_extended_cursor_sharing" = "UDO"';
DBMS_OUTPUT.put_line('Done');
ELSE
DBMS_OUTPUT.put_line('Null');
END IF;
END;
/
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,43 @@
----------------------------------------------------------------------------------------
--
-- File name: a.sql | as.sql | cs_active_sessions.sql
--
-- Purpose: Active Sessions including SQL Text and Exection Plan
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/16
--
-- Usage: Execute connected to PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_active_sessions.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_active_sessions';
DEF cs_script_acronym = 'a.sql | as.sql | ';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_active_sessions_internal.sql
--
PRO
PRO SQL> @&&cs_script_name..sql
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

44
csierra/cs_alert_log.sql Normal file
View File

@@ -0,0 +1,44 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_alert_log.sql
--
-- Purpose: Get alert log
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/05
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_alert_log.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
--
COL trace_dir NEW_V trace_dir FOR A100 NOPRI;
COL alert_log NEW_V alert_log FOR A30 NOPRI;
SELECT d.value trace_dir, 'alert_'||t.instance||'.log' alert_log FROM v$diag_info d, v$thread t WHERE d.name = 'Diag Trace';
HOS cp &&trace_dir./&&alert_log.* /tmp/
HOS chmod 644 /tmp/&&alert_log.*
PRO
PRO Current and prior alert logs on &&trace_dir.
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HOS ls -oX &&trace_dir./&&alert_log.*
PRO
PRO Preserved alert logs on /tmp
PRO ~~~~~~~~~~~~~~~~~~~~~~~
HOS ls -oX /tmp/alert*.log*
PRO
PRO If you want to copy alert log file(s), execute one scp command below, from a TERM session running on your Mac/PC:
PRO
PRO scp &&cs_host_name.:/tmp/&&alert_log. &&cs_local_dir.
PRO scp &&cs_host_name.:/tmp/&&alert_log.* &&cs_local_dir.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,73 @@
WITH relevant_segments AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
s.con_id,
s.owner,
s.segment_name,
s.partition_name,
s.segment_type,
s.tablespace_name,
s.bytes,
s.blocks,
CASE
WHEN s.segment_type LIKE 'TABLE%' THEN t.num_rows
END AS num_rows,
CASE
WHEN s.segment_type LIKE 'TABLE%' THEN s.segment_name
WHEN s.segment_type LIKE 'LOB%' AND s.segment_type <> 'LOBINDEX' THEN l.table_name
WHEN s.segment_type LIKE 'INDEX%' OR s.segment_type = 'LOBINDEX' THEN i.table_name
END AS table_name,
CASE
WHEN s.segment_type LIKE 'LOB%' AND s.segment_type <> 'LOBINDEX' THEN l.index_name
WHEN s.segment_type LIKE 'INDEX%' OR s.segment_type = 'LOBINDEX' THEN i.index_name
END AS index_name,
CASE
WHEN s.segment_type LIKE 'LOB%' AND s.segment_type <> 'LOBINDEX' THEN l.column_name
END AS column_name
FROM cdb_users u,
cdb_segments s,
cdb_tables t,
cdb_lobs l,
cdb_indexes i
WHERE u.oracle_maintained = 'N'
AND u.common = 'NO'
AND s.con_id = u.con_id
AND s.owner = u.username
AND s.bytes > 0
AND (s.segment_type LIKE 'TABLE%' OR s.segment_type LIKE 'LOB%' OR s.segment_type LIKE 'INDEX%')
AND t.con_id(+) = s.con_id
AND t.owner(+) = s.owner
AND t.table_name(+) = s.segment_name
AND l.con_id(+) = s.con_id
AND l.owner(+) = s.owner
AND l.segment_name(+) = s.segment_name
AND i.con_id(+) = s.con_id
AND i.owner(+) = s.owner
AND i.index_name(+) = s.segment_name
)
-- SELECT s.con_id,
-- s.owner,
-- s.segment_name,
-- s.partition_name,
-- s.segment_type,
-- s.tablespace_name,
-- s.bytes,
-- s.blocks,
-- s.num_rows,
-- s.table_name,
-- s.index_name,
-- s.column_name
-- FROM relevant_segments s
-- WHERE s.con_id = 3
-- AND s.table_name = 'ROUTE_TABLES_AD'
SELECT COUNT(*) AS cnt, SUM(bytes) AS bytes,
PERCENTILE_DISC(0.50) WITHIN GROUP (ORDER BY bytes) AS pctl_50,
PERCENTILE_DISC(0.70) WITHIN GROUP (ORDER BY bytes) AS pctl_70,
PERCENTILE_DISC(0.75) WITHIN GROUP (ORDER BY bytes) AS pctl_75,
PERCENTILE_DISC(0.80) WITHIN GROUP (ORDER BY bytes) AS pctl_80,
PERCENTILE_DISC(0.85) WITHIN GROUP (ORDER BY bytes) AS pctl_85,
PERCENTILE_DISC(0.90) WITHIN GROUP (ORDER BY bytes) AS pctl_90,
PERCENTILE_DISC(0.95) WITHIN GROUP (ORDER BY bytes) AS pctl_95,
PERCENTILE_DISC(0.99) WITHIN GROUP (ORDER BY bytes) AS pctl_99,
MAX(bytes) AS pctl_100
FROM relevant_segments
/

View File

@@ -0,0 +1,130 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_all_sysmetric_for_cdb_hist.sql
--
-- Purpose: All System Metrics as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (text report)
--
-- Author: Carlos Sierra
--
-- Version: 2021/04/06
--
-- Usage: Execute connected to CDB and pass range of AWR snapshots.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_all_sysmetric_for_cdb_hist.sql
--
-- Notes: Stand-alone script
--
-- Developed and tested on 12.1.0.2 and 19c.
--
---------------------------------------------------------------------------------------
--
DEF view_name = 'dba_hist_sysmetric_summary';
DEF common_predicate = "";
DEF script_name = 'cs_all_sysmetric_for_cdb_hist';
--
COL cs_date NEW_V cs_date NOPRI;
COL cs_host NEW_V cs_host NOPRI;
COL cs_db NEW_V cs_db NOPRI;
COL cs_con_name NEW_V cs_con_name NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_date, SYS_CONTEXT('USERENV','HOST') AS cs_host, UPPER(name) AS cs_db, SYS_CONTEXT('USERENV', 'CON_NAME') AS cs_con_name FROM v$database;
--
PRO
PRO Specify the number of days of snapshots to choose from
PRO
PRO Enter number of days: [{1}|0-60]
DEF num_days = '&1.'
UNDEF 1;
--
COL snap_id NEW_V snap_id FOR A7;
COL prior_snap_id NEW_V prior_snap_id FOR A7 NOPRI;
SELECT LPAD(TO_CHAR(snap_id), 7, ' ') AS snap_id, CAST(end_interval_time AS DATE) AS snap_time, LPAD(TO_CHAR(snap_id - 1), 7, ' ') AS prior_snap_id
FROM dba_hist_snapshot
WHERE instance_number = SYS_CONTEXT('USERENV','INSTANCE')
AND dbid = (SELECT dbid FROM v$database)
AND CAST(end_interval_time AS DATE) > SYSDATE - TO_NUMBER(NVL('&&num_days.', '1'))
ORDER BY
snap_id
/
--
PRO
PRO Enter begin snap_id: [{&&prior_snap_id.}]
DEF begin_snap_id = '&2.';
UNDEF 2;
COL begin_snap_id NEW_V begin_snap_id NOPRI;
SELECT NVL('&&begin_snap_id.', '&&prior_snap_id.') AS begin_snap_id FROM DUAL;
--
PRO
PRO Enter end snap_id: [{&&snap_id.}]
DEF end_snap_id = '&3.';
UNDEF 3;
COL end_snap_id NEW_V end_snap_id NOPRI;
SELECT NVL('&&end_snap_id.', '&&snap_id.') AS end_snap_id FROM DUAL;
--
COL cs_begin_time NEW_V cs_begin_time NOPRI;
COL cs_end_time NEW_V cs_end_time NOPRI;
COL cs_seconds NEW_V cs_seconds NOPRI;
SELECT TO_CHAR(MAX(CAST(end_interval_time AS DATE)), 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_begin_time FROM dba_hist_snapshot WHERE snap_id = TO_NUMBER('&&begin_snap_id.');
SELECT TO_CHAR(MAX(CAST(end_interval_time AS DATE)), 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_end_time FROM dba_hist_snapshot WHERE snap_id = TO_NUMBER('&&end_snap_id.');
SELECT TRIM(TO_CHAR(intsize/100, '999,999,990.00')) AS cs_seconds FROM &&view_name. WHERE snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.') AND ROWNUM = 1;
--
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
COL report_date_time NEW_V report_date_time NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24.MI.SS"Z"') AS report_date_time FROM DUAL;
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
ALTER SESSION SET container = CDB$ROOT;
--
SPO /tmp/&&script_name._&&report_date_time..txt
PRO /tmp/&&script_name._&&report_date_time..txt
PRO
PRO Date : &&cs_date.
PRO Host : &&cs_host.
PRO Database : &&cs_db.
--PRO Container: &&cs_con_name.
PRO Range : &&cs_begin_time. - &&cs_end_time. (&&cs_seconds. seconds)
--
COL metric_name FOR A45 TRUN;
COL metric_unit FOR A41 TRUN;
COL seconds FOR 9,900.00;
--
PRO
PRO System Metrics by Name (&&view_name.)
PRO ~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_name,
AVG(average) AS average,
MAX(maxval) AS maxval,
metric_unit
FROM &&view_name.
WHERE &&common_predicate. snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.')
GROUP BY
metric_name, metric_unit
ORDER BY
metric_name, metric_unit
/
PRO
PRO System Metrics by Unit and Name (&&view_name.)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_unit,
metric_name,
AVG(average) AS average,
MAX(maxval) AS maxval
FROM &&view_name.
WHERE &&common_predicate. snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.')
GROUP BY
metric_unit, metric_name
ORDER BY
metric_unit, metric_name
/
--
PRO
PRO SQL> @&&script_name..sql
SPO OFF;
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
ALTER SESSION SET CONTAINER = &&cs_con_name.;
--
PRO
PRO /tmp/&&script_name._&&report_date_time..txt
--

View File

@@ -0,0 +1,111 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_all_sysmetric_for_cdb_mem.sql
--
-- Purpose: All System Metrics as per V$SYSMETRIC Views for a CDB (text report)
--
-- Author: Carlos Sierra
--
-- Version: 2021/04/06
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_all_sysmetric_for_cdb_mem.sql
--
-- Notes: Developed and tested on 12.1.0.2 and 19c.
--
---------------------------------------------------------------------------------------
--
DEF view_name_prefix = 'v$sysmetric';
DEF common_predicate = "SYS_CONTEXT('USERENV', 'CON_NAME') = 'CDB$ROOT'";
DEF script_name = 'cs_all_sysmetric_for_cdb_mem';
--
COL cs_date NEW_V cs_date NOPRI;
COL cs_host NEW_V cs_host NOPRI;
COL cs_db NEW_V cs_db NOPRI;
COL cs_con_name NEW_V cs_con_name NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_date, SYS_CONTEXT('USERENV','HOST') AS cs_host, UPPER(name) AS cs_db, SYS_CONTEXT('USERENV', 'CON_NAME') AS cs_con_name FROM v$database;
--
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
COL report_date_time NEW_V report_date_time NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24.MI.SS"Z"') AS report_date_time FROM DUAL;
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
ALTER SESSION SET container = CDB$ROOT;
--
SPO /tmp/&&script_name._&&report_date_time..txt
PRO /tmp/&&script_name._&&report_date_time..txt
PRO
PRO Date : &&cs_date.
PRO Host : &&cs_host.
PRO Database : &&cs_db.
--PRO Container: &&cs_con_name.
--
COL metric_name FOR A45 TRUN;
COL metric_unit FOR A41 TRUN;
COL seconds FOR 9,900.00;
--
PRO
PRO System Metrics by Name (&&view_name_prefix. and &&view_name_prefix._summary)
PRO ~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
value AS average,
TO_NUMBER(NULL) AS maxval,
metric_unit
FROM &&view_name_prefix.
WHERE &&common_predicate.
UNION ALL
SELECT metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
average,
maxval,
metric_unit
FROM &&view_name_prefix._summary
WHERE &&common_predicate.
ORDER BY
1, 2
/
--
PRO
PRO System Metrics by Unit and Name (&&view_name_prefix. and &&view_name_prefix._summary)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_unit,
metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
value AS average,
TO_NUMBER(NULL) AS maxval
FROM &&view_name_prefix.
WHERE &&common_predicate.
UNION ALL
SELECT metric_unit,
metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
average,
maxval
FROM &&view_name_prefix._summary
WHERE &&common_predicate.
ORDER BY
1, 2, 3
/
--
PRO
PRO SQL> @&&script_name..sql
SPO OFF;
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
ALTER SESSION SET CONTAINER = &&cs_con_name.;
--
PRO
PRO /tmp/&&script_name._&&report_date_time..txt
--

View File

@@ -0,0 +1,122 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_all_sysmetric_for_pdb_hist.sql
--
-- Purpose: All System Metrics as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (text report)
--
-- Author: Carlos Sierra
--
-- Version: 2021/04/06
--
-- Usage: Execute connected to CDB and pass range of AWR snapshots.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_all_sysmetric_for_pdb_hist.sql
--
-- Notes: Stand-alone script
--
-- Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
DEF view_name = 'dba_hist_con_sysmetric_summ';
DEF common_predicate = "con_id = SYS_CONTEXT('USERENV', 'CON_ID') AND";
DEF script_name = 'cs_all_sysmetric_for_pdb_hist';
--
COL cs_date NEW_V cs_date NOPRI;
COL cs_host NEW_V cs_host NOPRI;
COL cs_db NEW_V cs_db NOPRI;
COL cs_con NEW_V cs_con NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_date, SYS_CONTEXT('USERENV','HOST') AS cs_host, UPPER(name) AS cs_db, SYS_CONTEXT('USERENV', 'CON_NAME') AS cs_con FROM v$database;
--
PRO
PRO Specify the number of days of snapshots to choose from
PRO
PRO Enter number of days: [{1}|0-60]
DEF num_days = '&1'
UNDEF 1;
--
COL snap_id NEW_V snap_id FOR A7;
COL prior_snap_id NEW_V prior_snap_id FOR A7 NOPRI;
SELECT LPAD(TO_CHAR(snap_id), 7, ' ') AS snap_id, CAST(end_interval_time AS DATE) AS snap_time, LPAD(TO_CHAR(snap_id - 1), 7, ' ') AS prior_snap_id
FROM dba_hist_snapshot
WHERE instance_number = SYS_CONTEXT('USERENV','INSTANCE')
AND dbid = (SELECT dbid FROM v$database)
AND CAST(end_interval_time AS DATE) > SYSDATE - TO_NUMBER(NVL('&&num_days.', '1'))
ORDER BY
snap_id
/
--
PRO
PRO Enter begin snap_id: [{&&prior_snap_id.}]
DEF begin_snap_id = '&2.';
UNDEF 2;
COL begin_snap_id NEW_V begin_snap_id NOPRI;
SELECT NVL('&&begin_snap_id.', '&&prior_snap_id.') AS begin_snap_id FROM DUAL;
--
PRO
PRO Enter end snap_id: [{&&snap_id.}]
DEF end_snap_id = '&3.';
UNDEF 3;
COL end_snap_id NEW_V end_snap_id NOPRI;
SELECT NVL('&&end_snap_id.', '&&snap_id.') AS end_snap_id FROM DUAL;
--
COL cs_begin_time NEW_V cs_begin_time NOPRI;
COL cs_end_time NEW_V cs_end_time NOPRI;
COL cs_seconds NEW_V cs_seconds NOPRI;
SELECT TO_CHAR(MAX(CAST(end_interval_time AS DATE)), 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_begin_time FROM dba_hist_snapshot WHERE snap_id = TO_NUMBER('&&begin_snap_id.');
SELECT TO_CHAR(MAX(CAST(end_interval_time AS DATE)), 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_end_time FROM dba_hist_snapshot WHERE snap_id = TO_NUMBER('&&end_snap_id.');
SELECT TRIM(TO_CHAR(intsize/100, '999,999,990.00')) AS cs_seconds FROM &&view_name. WHERE snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.') AND ROWNUM = 1;
--
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
COL report_date_time NEW_V report_date_time NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24.MI.SS"Z"') AS report_date_time FROM DUAL;
SPO /tmp/&&script_name._&&report_date_time..txt
PRO /tmp/&&script_name._&&report_date_time..txt
PRO
PRO Date : &&cs_date.
PRO Host : &&cs_host.
PRO Database : &&cs_db.
PRO Container: &&cs_con.
PRO Range : &&cs_begin_time. - &&cs_end_time. (&&cs_seconds. seconds)
--
COL metric_name FOR A45 TRUN;
COL metric_unit FOR A41 TRUN;
COL seconds FOR 9,900.00;
--
PRO
PRO System Metrics by Name (&&view_name.)
PRO ~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_name,
AVG(average) AS average,
MAX(maxval) AS maxval,
metric_unit
FROM &&view_name.
WHERE &&common_predicate. snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.')
GROUP BY
metric_name, metric_unit
ORDER BY
metric_name, metric_unit
/
PRO
PRO System Metrics by Unit and Name (&&view_name.)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_unit,
metric_name,
AVG(average) AS average,
MAX(maxval) AS maxval
FROM &&view_name.
WHERE &&common_predicate. snap_id > TO_NUMBER('&&begin_snap_id.') AND snap_id <= TO_NUMBER('&&end_snap_id.')
GROUP BY
metric_unit, metric_name
ORDER BY
metric_unit, metric_name
/
--
PRO
PRO SQL> @&&script_name..sql
SPO OFF;
PRO
PRO /tmp/&&script_name._&&report_date_time..txt
--

View File

@@ -0,0 +1,104 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_all_sysmetric_for_pdb_mem.sql
--
-- Purpose: All System Metrics as per V$CON_SYSMETRIC Views for a PDB (text report)
--
-- Author: Carlos Sierra
--
-- Version: 2021/04/06
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_all_sysmetric_for_pdb_mem.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
DEF view_name_prefix = 'v$con_sysmetric';
DEF common_predicate = "con_id = SYS_CONTEXT('USERENV', 'CON_ID')";
DEF script_name = 'cs_all_sysmetric_for_pdb_mem';
--
COL cs_date NEW_V cs_date NOPRI;
COL cs_host NEW_V cs_host NOPRI;
COL cs_db NEW_V cs_db NOPRI;
COL cs_con NEW_V cs_con NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24:MI:SS') AS cs_date, SYS_CONTEXT('USERENV','HOST') AS cs_host, UPPER(name) AS cs_db, SYS_CONTEXT('USERENV', 'CON_NAME') AS cs_con FROM v$database;
--
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
COL report_date_time NEW_V report_date_time NOPRI;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD"T"HH24.MI.SS"Z"') AS report_date_time FROM DUAL;
--
SPO /tmp/&&script_name._&&report_date_time..txt
PRO /tmp/&&script_name._&&report_date_time..txt
PRO
PRO Date : &&cs_date.
PRO Host : &&cs_host.
PRO Database : &&cs_db.
PRO Container: &&cs_con.
--
COL metric_name FOR A45 TRUN;
COL metric_unit FOR A41 TRUN;
COL seconds FOR 9,900.00;
--
PRO
PRO System Metrics by Name (&&view_name_prefix. and &&view_name_prefix._summary)
PRO ~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
value AS average,
TO_NUMBER(NULL) AS maxval,
metric_unit
FROM &&view_name_prefix.
WHERE &&common_predicate.
UNION ALL
SELECT metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
average,
maxval,
metric_unit
FROM &&view_name_prefix._summary
WHERE &&common_predicate.
ORDER BY
1, 2
/
--
PRO
PRO System Metrics by Unit and Name (&&view_name_prefix. and &&view_name_prefix._summary)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT metric_unit,
metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
value AS average,
TO_NUMBER(NULL) AS maxval
FROM &&view_name_prefix.
WHERE &&common_predicate.
UNION ALL
SELECT metric_unit,
metric_name,
intsize_csec/100 AS seconds,
begin_time,
end_time,
average,
maxval
FROM &&view_name_prefix._summary
WHERE &&common_predicate.
ORDER BY
1, 2, 3
/
--
PRO
PRO SQL> @&&script_name..sql
SPO OFF;
PRO
PRO /tmp/&&script_name._&&report_date_time..txt
--

277
csierra/cs_amw_report.sql Normal file
View File

@@ -0,0 +1,277 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_amw_report.sql
--
-- Purpose: Automatic Maintenance Window Report
--
-- Author: Carlos Sierra
--
-- Version: 2021/09/20
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_amw_report.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
--@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_amw_report';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql
@@cs_internal/cs_spool_id.sql
--
COL pdb_name FOR A30 TRUNC;
COL task_name FOR A30;
COL parameter_name FOR A30;
COL parameter_value FOR A30;
PRO
PRO dba_advisor_parameters
PRO ~~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.task_name, t.parameter_name, t.parameter_value FROM cdb_advisor_parameters t, v$containers c WHERE t.task_name IN ('SYS_AUTO_SPM_EVOLVE_TASK', 'SYS_AI_SPM_EVOLVE_TASK', 'SYS_AUTO_SQL_TUNING_TASK') AND t.parameter_name IN ('ACCEPT_PLANS', 'ACCEPT_SQL_PROFILES') AND c.con_id = t.con_id ORDER BY c.name, t.task_name, t.parameter_name, t.parameter_value;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_advisor_parameters t, v$containers c WHERE t.task_name LIKE ''%TASK'' AND t.parameter_name LIKE ''ACCEPT%'' AND c.con_id = t.con_id ORDER BY c.name, t.task_name, t.parameter_name, t.parameter_value"
--
-- COL pdb_name FOR A30 TRUNC;
-- COL task_name FOR A30;
-- COL enabled FOR A8;
-- PRO
-- PRO dba_autotask_schedule_control
-- PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.task_name, t.enabled FROM cdb_autotask_schedule_control t, v$containers c WHERE t.task_name IN ('Auto SPM Task', 'Auto STS Capture Task') AND c.con_id = t.con_id ORDER BY c.name, t.task_name;
-- @@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_schedule_control t, v$containers c WHERE t.task_name LIKE ''Auto % Task'' AND c.con_id = t.con_id ORDER BY c.name, t.task_name"
--
COL pdb_name FOR A30 TRUNC;
COL client_name FOR A40;
COL status FOR A8;
COL mean_job_duration FOR A30;
COL window_duration_last_7_days FOR A30;
COL window_duration_last_30_days FOR A30;
COL window_group FOR A20;
COL last_change FOR A25;
PRO
PRO dba_autotask_client
PRO ~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.client_name, t.status, t.window_group, t.mean_job_duration, t.window_duration_last_7_days, t.window_duration_last_30_days, t.last_change FROM cdb_autotask_client t, v$containers c WHERE t.client_name IN ('auto optimizer stats collection', 'sql tuning advisor', 'auto space advisor') AND c.con_id = t.con_id ORDER BY c.name, t.client_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_client t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name"
--
COL pdb_name FOR A30 TRUNC;
COL client_name FOR A40;
COL status FOR A8;
COL window_start_time FOR A30;
COL window_end_time FOR A30;
COL window_duration FOR A30;
COL window_name FOR A20;
PRO
PRO dba_autotask_client_history
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, t.client_name, t.window_start_time, t.window_end_time, t.window_duration, t.window_name, t.jobs_created, t.jobs_started, t.jobs_completed FROM cdb_autotask_client_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.window_start_time;
-- @@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_client_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.window_start_time"
--
COL client_name FOR A40;
COL job_name FOR A25;
COL job_scheduler_status FOR A10 HEA 'STATUS';
COL task_name FOR A30;
COL task_operation FOR A30;
COL task_target_type FOR A20;
COL task_target_name FOR A20;
COL task_priority FOR A20;
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
PRO
PRO dba_autotask_client_job (from CDB$ROOT)
PRO ~~~~~~~~~~~~~~~~~~~~~~~
-- SELECT client_name, job_name, job_scheduler_status, task_name, task_operation, task_target_type, task_target_name, task_priority FROM dba_autotask_client_job;
@@cs_internal/cs_pr_internal "SELECT * FROM dba_autotask_client_job"
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
COL pdb_name FOR A30 TRUNC;
COL client_name FOR A40;
COL window_start_time FOR A30;
COL window_duration FOR A30;
COL window_name FOR A20;
COL job_name FOR A25;
COL job_status FOR A10 HEA 'STATUS';
COL job_start_time FOR A30;
COL job_duration FOR A30;
COL delay_mins FOR 999,999,990;
COL job_error FOR 9999999990;
COL job_info FOR A80;
PRO
PRO dba_autotask_job_history
PRO ~~~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, t.client_name, t.window_start_time, t.window_duration, t.window_name, t.job_name, t.job_status, t.job_start_time, t.job_duration, EXTRACT(DAY FROM (t.job_start_time - t.window_start_time) * 24 * 60) AS delay_mins, t.job_error, t.job_info
FROM cdb_autotask_job_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.window_start_time;
-- @@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_job_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.window_start_time"
--
COL pdb_name FOR A30 TRUNC;
COL client_name FOR A40;
COL operation_name FOR A30;
COL operation_tag FOR A15;
COL attributes FOR A60;
COL status FOR A10;
COL last_change FOR A30;
COL priority_override FOR A20;
COL use_resource_estimates FOR A25;
PRO
PRO dba_autotask_operation
PRO ~~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.client_name, t.operation_name, t.operation_tag, t.attributes, t.status, t.last_change, t.priority_override, t.use_resource_estimates FROM cdb_autotask_operation t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.operation_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_operation t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.client_name, t.operation_name"
--
COL pdb_name FOR A30 TRUNC;
COL start_time FOR A30;
COL duration FOR A30;
COL window_name FOR A20;
PRO
PRO dba_autotask_schedule
PRO ~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, t.start_time, t.duration, t.window_name FROM cdb_autotask_schedule t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.start_time;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_schedule t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.start_time"
--
COL pdb_name FOR A30 TRUNC;
COL status FOR A10;
COL last_change FOR A30;
PRO
PRO dba_autotask_status
PRO ~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.status, t.last_change FROM cdb_autotask_status t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_status t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name"
--
PRO
PRO dba_autotask_task
PRO ~~~~~~~~~~~~~~~~~
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_task t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name"
--
COL pdb_name FOR A30 TRUNC;
COL window_name FOR A20;
COL window_active FOR A15;
COL autotask_status FOR A15;
COL optimizer_stats FOR A20;
COL sql_tune_advisor FOR A20;
COL segment_advisor FOR A20;
COL health_monitor FOR A20;
PRO
PRO dba_autotask_window_clients
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.window_name, t.window_active, t.autotask_status, t.optimizer_stats, t.sql_tune_advisor, t.segment_advisor, t.health_monitor FROM cdb_autotask_window_clients t, v$containers c WHERE t.window_name IN ('MONDAY_WINDOW', 'TUESDAY_WINDOW', 'WEDNESDAY_WINDOW', 'THURSDAY_WINDOW', 'FRIDAY_WINDOW', 'SATURDAY_WINDOW', 'SUNDAY_WINDOW') AND c.con_id = t.con_id ORDER BY c.name, t.window_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_window_clients t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.window_name"
--
COL pdb_name FOR A30 TRUNC;
COL window_start_time FOR A30;
COL window_end_time FOR A30;
COL window_name FOR A20;
PRO
PRO dba_autotask_window_history
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, t.window_start_time, t.window_end_time, t.window_name FROM cdb_autotask_window_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.window_start_time;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_autotask_window_history t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.window_start_time"
--
COL pdb_name FOR A30 TRUNC;
COL attribute_name FOR A30;
COL value FOR A30;
PRO
PRO dba_scheduler_global_attribute
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.attribute_name, t.value FROM cdb_scheduler_global_attribute t, v$containers c WHERE t.attribute_name IN ('DEFAULT_TIMEZONE', 'LOG_HISTORY', 'MAX_JOB_SLAVE_PROCESSES', 'MAX_JOB_SLAVE_PROCESSES', 'CURRENT_OPEN_WINDOW') AND c.con_id = t.con_id ORDER BY c.name, t.attribute_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_scheduler_global_attribute t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.attribute_name"
--
COL pdb_name FOR A30 TRUNC;
COL group_name FOR A30;
COL comments FOR A40;
PRO
PRO dba_scheduler_groups
PRO ~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, g.group_name, g.enabled, g.number_of_members, g.comments FROM cdb_scheduler_groups g, v$containers c WHERE g.group_type = 'WINDOW' AND c.con_id = g.con_id ORDER BY c.name, g.group_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, g.* FROM cdb_scheduler_groups g, v$containers c WHERE g.group_type = ''WINDOW'' AND c.con_id = g.con_id ORDER BY c.name, g.group_name"
--
COL pdb_name FOR A30 TRUNC;
COL owner FOR A30;
COL group_name FOR A30;
COL member_name FOR A30;
PRO
PRO dba_scheduler_group_members
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, g.owner, g.group_name, g.member_name FROM cdb_scheduler_group_members g, v$containers c WHERE c.con_id = g.con_id ORDER BY c.name, g.owner, g.group_name, g.member_name;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, g.owner, g.group_name, g.member_name FROM cdb_scheduler_group_members g, v$containers c WHERE c.con_id = g.con_id ORDER BY c.name, g.owner, g.group_name, g.member_name"
--
COL pdb_name FOR A30 TRUNC;
COL owner FOR A20;
COL job_name FOR A30;
COL job_action FOR A60;
COL start_date FOR A25;
COL repeat_interval FOR A50;
COL job_class FOR A30;
COL enabled FOR A10;
COL state FOR A10;
COL last_start_date FOR A25;
COL last_run_duration FOR A30;
COL next_run_date FOR A25;
COL comments FOR A80;
--
PRO
PRO dba_scheduler_jobs
PRO ~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, s.owner, s.job_name, s.job_type, s.job_action, s.start_date, s.repeat_interval, s.job_class, s.enabled, s.state, s.last_start_date, s.last_run_duration, s.next_run_date, s.comments FROM cdb_scheduler_jobs s, v$containers c WHERE c.con_id = s.con_id ORDER BY c.name, s.owner, s.job_name;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, s.* FROM cdb_scheduler_jobs s, v$containers c WHERE c.con_id = s.con_id ORDER BY c.name, s.owner, s.job_name"
--
COL pdb_name FOR A30 TRUNC;
COL owner FOR A20;
COL program_name FOR A30;
COL program_type FOR A16;
COL program_action FOR A60;
COL enabled FOR A7;
COL detached FOR A8;
COL comments FOR A80;
PRO
PRO dba_scheduler_programs
PRO ~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, s.owner, s.program_name, s.program_type, s.program_action, s.number_of_arguments, s.enabled, s.detached, s.priority, s.weight, s.comments FROM cdb_scheduler_programs s, v$containers c WHERE c.con_id = s.con_id ORDER BY c.name, s.owner, s.program_name;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, s.* FROM cdb_scheduler_programs s, v$containers c WHERE c.con_id = s.con_id ORDER BY c.name, s.owner, s.program_name"
--
COL pdb_name FOR A30 TRUNC;
COL window_name FOR A20;
COL enabled FOR A8;
COL resource_plan FOR A30;
COL duration FOR A20;
COL repeat_interval FOR A70;
COL last_start_date FOR A25;
COL next_start_date FOR A25;
PRO
PRO dba_scheduler_windows
PRO ~~~~~~~~~~~~~~~~~~~~~
-- SELECT c.name AS pdb_name, t.window_name, t.enabled, t.active, t.resource_plan, t.duration, t.repeat_interval, t.last_start_date, t.next_start_date FROM cdb_scheduler_windows t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.window_name;
@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_scheduler_windows t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.window_name"
--
COL pdb_name FOR A30 TRUNC;
COL log_date FOR A25;
COL req_start_date FOR A25;
COL actual_start_date FOR A25;
COL window_duration FOR A20;
COL actual_duration FOR A20;
COL window_name FOR A20;
COL additional_info FOR A80;
PRO
PRO dba_scheduler_window_details
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT c.name AS pdb_name, t.log_date, t.req_start_date, t.actual_start_date, t.window_duration, t.actual_duration, t.window_name, t.additional_info FROM cdb_scheduler_window_details t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.log_date;
--@@cs_internal/cs_pr_internal "SELECT c.name AS pdb_name, t.* FROM cdb_scheduler_window_details t, v$containers c WHERE c.con_id = t.con_id ORDER BY c.name, t.log_date"
--
PRO
PRO SQL> @&&cs_script_name..sql
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,15 @@
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
COL owner FOR A30;
COL table_name FOR A30;
COL num_rows FOR 999,999,999,999;
COL blocks FOR 9,999,999,999;
SELECT u.common, t.owner, t.table_name, t.num_rows, t.blocks, t.last_analyzed, t.tablespace_name
FROM dba_tables t, dba_users u
WHERE u.username = t.owner
AND u.oracle_maintained = 'N'
ORDER BY
u.common DESC,
t.owner,
t.table_name
/

1607
csierra/cs_ash_analytics.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_awr_block_chains_report.sql
--
-- Purpose: ASH Block Chains Report from AWR
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/04
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_awr_block_chains_report.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_awr_block_chains_report';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '24';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To report on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO THRESHOLD : "&&times_cpu_cores.x NUM_CPU_CORES"
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
-- DEF times_cpu_cores = '1';
DEF include_hist = 'Y';
DEF include_mem = 'N';
--
@@cs_internal/cs_ash_block_chains.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
--
@@cs_internal/cs_spool_tail.sql
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,144 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_awr_peaks_bubble.sql
--
-- Purpose: ASH Peaks Bubble from AWR
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_awr_peaks_bubble.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_awr_peaks_bubble';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To chart on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
PRO
PRO 4. Dimension [{GLOBAL}|SQL_ID|WAIT_CLASS|TIMED_EVENT|PDB]
DEF dimension = '&4.';
UNDEF 4;
COL dimension NEW_V dimension NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&dimension.')) IN ('GLOBAL', 'SQL_ID', 'WAIT_CLASS', 'TIMED_EVENT', 'PDB') THEN UPPER(TRIM('&&dimension.')) ELSE 'GLOBAL' END AS dimension FROM DUAL
/
COL grouping_expression NEW_V grouping_expression NOPRI;
SELECT CASE '&&dimension.'
WHEN 'GLOBAL' THEN q'[object_type]'
WHEN 'SQL_ID' THEN q'[statement_id||' '||SUBSTR(remarks, 1, 50)]'
WHEN 'WAIT_CLASS' THEN q'[CASE operation WHEN 'ON CPU' THEN operation ELSE options END]'
WHEN 'TIMED_EVENT' THEN q'[CASE operation WHEN 'ON CPU' THEN operation ELSE options||' - '||object_node END]'
WHEN 'PDB' THEN q'[object_owner||'('||plan_id||')']'
END AS grouping_expression
FROM DUAL
/
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF include_hist = 'Y';
DEF include_mem = 'N';
SET SERVEROUT OFF;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
--
SELECT '&&cs_file_prefix._&&cs_script_name._&&dimension.' cs_file_name FROM DUAL;
--
DEF report_title = "Peaks duration of Active Sessions in Concurrency contention exceeding &&times_cpu_cores.x CPU_CORES by top value - &&dimension.";
DEF chart_title = "&&report_title.";
DEF xaxis_title = "between &&cs_sample_time_from. and &&cs_sample_time_to.";
-- DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
-- DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}, 3:{}, 4:{}, 5:{}";
DEF vaxis_title = "Maximum Active Sessions";
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
--DEF is_stacked = "isStacked: false,";
DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = "<br>2) Bubble size indicates duration of contention. Label shows the top#1 contributor.";
DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores." "&&dimension."';
--
DEF spool_chart_1st_column = 'ID';
@@cs_internal/cs_spool_head_chart.sql
PRO , 'Time', 'Total Maximum Active Sessions', 'Top#1 &&dimension.', 'Approximate duration in seconds'
PRO ]
--
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
-- SELECT ', [''#'||ROW_NUMBER() OVER (ORDER BY cost DESC, timestamp)||' '||cost||''''||
SELECT ', ['''''||
', new Date('||
TO_CHAR(t.timestamp, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(t.timestamp, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(t.timestamp, 'DD')|| /* day */
','||TO_CHAR(t.timestamp, 'HH24')|| /* hour */
','||TO_CHAR(t.timestamp, 'MI')|| /* minute */
','||TO_CHAR(t.timestamp, 'SS')|| /* second */
')'||
', '||num_format(t.cardinality, 0)|| -- sessions_peak
', '''||&&grouping_expression.||''''||
', '||num_format(t.cost, 0)|| -- seconds
']'
FROM plan_table t
ORDER BY
t.cost DESC
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter|Bubble]
DEF cs_chart_type = 'Bubble';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,175 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_awr_peaks_chart.sql
--
-- Purpose: ASH Peaks Chart from AWR
--
-- Author: Carlos Sierra
--
-- Version: 2021/12/03
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_awr_peaks_chart.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_awr_peaks_chart';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To chart on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
DEF include_hist = 'Y';
DEF include_mem = 'N';
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = "Active Sessions Peaks";
DEF chart_title = "&&report_title.";
DEF xaxis_title = "between &&cs_sample_time_from. and &&cs_sample_time_to.";
-- DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
-- DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}, 3:{}, 4:{}, 5:{}";
DEF vaxis_title = "Sum of Active Sessions per sampled time";
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
--DEF vaxis_baseline = "";
DEF chart_foot_note_2 = "<br>2)";
DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'Sessions Peak', id:'1', type:'number'}
PRO ,{label:'Before Peak', id:'2', type:'number'}
PRO ,{label:'After Peak', id:'3', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
threshold AS (
SELECT /*+ MATERIALIZE NO_MERGE */ &&times_cpu_cores. * value AS value FROM v$osstat WHERE stat_name = 'NUM_CPU_CORES' AND ROWNUM >= 1 /* MATERIALIZE */
),
active_sessions_time_series AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS active_sessions
FROM dba_hist_active_sess_history h
WHERE '&&include_hist.' = 'Y'
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.')
AND ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
h.sample_time
UNION
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS active_sessions
FROM v$active_session_history h
WHERE '&&include_mem.' = 'Y'
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
h.sample_time
),
time_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
SUM(active_sessions) AS active_sessions,
LAG(SUM(active_sessions)) OVER (ORDER BY sample_time) AS lag_active_sessions,
LEAD(SUM(active_sessions)) OVER (ORDER BY sample_time) AS lead_active_sessions
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time
),
t AS (
SELECT /*+ MATERIALIZE NO_MERGE */
t.sample_time,
CASE WHEN t.active_sessions >= threshold.value THEN t.active_sessions END AS peak_value,
CASE WHEN t.active_sessions < threshold.value AND t.lead_active_sessions >= threshold.value THEN t.active_sessions END AS before_value,
CASE WHEN t.active_sessions < threshold.value AND t.lag_active_sessions >= threshold.value THEN t.active_sessions END AS after_value
FROM threshold,
time_dim t
WHERE (t.active_sessions >= threshold.value OR t.lag_active_sessions >= threshold.value OR t.lead_active_sessions >= threshold.value)
AND ROWNUM >= 1 /* MATERIALIZE */
)
SELECT ', [new Date('||
TO_CHAR(t.sample_time, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(t.sample_time, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(t.sample_time, 'DD')|| /* day */
','||TO_CHAR(t.sample_time, 'HH24')|| /* hour */
','||TO_CHAR(t.sample_time, 'MI')|| /* minute */
','||TO_CHAR(t.sample_time, 'SS')|| /* second */
')'||
','||num_format(t.peak_value, 0)||
','||num_format(t.before_value, 0)||
','||num_format(t.after_value, 0)||
']'
FROM t
ORDER BY
t.sample_time
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,71 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_awr_peaks_report.sql
--
-- Purpose: ASH Peaks Report from AWR
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_awr_peaks_report.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_awr_peaks_report';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '24';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To report on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO THRESHOLD : "&&times_cpu_cores.x NUM_CPU_CORES"
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
-- DEF times_cpu_cores = '1';
DEF include_hist = 'Y';
DEF include_mem = 'N';
PRO
PRO Sum of Active Sessions per sampled time (when greater than &&times_cpu_cores.x CPU Cores)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
@@cs_internal/cs_active_sessions_peaks_internal_v6.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,125 @@
----------------------------------------------------------------------------------------
--
-- File name: ah.sql | cs_ash_awr_sample_report.sql
--
-- Purpose: ASH Samples from AWR
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter optional parameters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_awr_sample_report.sql
--
-- Notes: *** Requires Oracle Diagnostics Pack License ***
--
-- Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
SET PAGES 5000;
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_awr_sample_report';
DEF cs_script_acronym = 'ah.sql | ';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '24';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Machine (opt):
DEF cs2_machine = '&3.';
UNDEF 3;
--
PRO
PRO 4. SQL_ID (opt):
DEF cs_sql_id = '&4.';
UNDEF 4;
--
PRO
PRO 5. SID,SERIAL (opt):
DEF cs_sid_serial = '&5.';
UNDEF 5;
--
PRO
PRO 6. Only LOB DEDUP TX 4 waiting sessions [{N}|Y]:
DEF cs_only_dedup = '&6.';
UNDEF 6;
COL cs_only_dedup NEW_V cs_only_dedup NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) ELSE 'N' END AS cs_only_dedup FROM DUAL
/
--
PRO
PRO 7. Include PL/SQL Library Entry Point [{N}|Y]:
DEF cs_pl_sql = '&7.';
UNDEF 7;
COL cs_pl_sql NEW_V cs_pl_sql NOPRI;
COL cs_pl_sql_pri NEW_V cs_pl_sql_pri NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) ELSE 'N' END AS cs_pl_sql, CASE SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) WHEN 'Y' THEN 'PRI' ELSE 'NOPRI' END AS cs_pl_sql_pri FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup." "&&cs_pl_sql."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO MACHINE : "&&cs2_machine."
PRO SQL_ID : "&&cs_sql_id."
PRO SID,SERIAL : "&&cs_sid_serial."
PRO ONLY_DEDUP : "&&cs_only_dedup."
PRO INCL_PL_SQL : "&&cs_pl_sql."
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF times_cpu_cores = '1';
DEF include_hist = 'Y';
DEF include_mem = 'N';
PRO
PRO Sum of Active Sessions per sampled time (spikes greater than &&cs_num_cpu_cores. CPU Cores)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
@@cs_internal/cs_active_sessions_peaks_internal_v6.sql
--
DEF times_cpu_cores = '0';
DEF include_hist = 'Y';
DEF include_mem = 'N';
PRO
PRO Sum of Active Sessions per sampled time
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
--
DEF times_cpu_cores = '1';
DEF include_hist = 'Y';
DEF include_mem = 'N';
-- @@cs_internal/cs_ash_block_chains.sql
--
--DEF ash_view = 'v$active_session_history';
--DEF ash_additional_predicate = '';
DEF ash_view = 'dba_hist_active_sess_history';
DEF ash_additional_predicate = ' AND h.dbid = &&cs_dbid. AND h.instance_number = &&cs_instance_number. AND h.snap_id BETWEEN &&cs_snap_id_from. AND &&cs_snap_id_to. ';
--
@@cs_internal/cs_ash_sample_detail.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup." "&&cs_pl_sql."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,67 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_mem_block_chains_report.sql
--
-- Purpose: ASH Block Chains Report from MEM
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/04
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_mem_block_chains_report.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_mem_block_chains_report';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '3';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To report on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO THRESHOLD : "&&times_cpu_cores.x NUM_CPU_CORES"
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
-- DEF times_cpu_cores = '1';
DEF include_hist = 'N';
DEF include_mem = 'Y';
--
@@cs_internal/cs_ash_block_chains.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
--
@@cs_internal/cs_spool_tail.sql
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,144 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_mem_peaks_bubble.sql
--
-- Purpose: ASH Peaks Bubble from MEM
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_mem_peaks_bubble.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_mem_peaks_bubble';
DEF cs_hours_range_default = '3';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To chart on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
PRO
PRO 4. Dimension [{GLOBAL}|SQL_ID|WAIT_CLASS|TIMED_EVENT|PDB]
DEF dimension = '&4.';
UNDEF 4;
COL dimension NEW_V dimension NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&dimension.')) IN ('GLOBAL', 'SQL_ID', 'WAIT_CLASS', 'TIMED_EVENT', 'PDB') THEN UPPER(TRIM('&&dimension.')) ELSE 'GLOBAL' END AS dimension FROM DUAL
/
COL grouping_expression NEW_V grouping_expression NOPRI;
SELECT CASE '&&dimension.'
WHEN 'GLOBAL' THEN q'[object_type]'
WHEN 'SQL_ID' THEN q'[statement_id||' '||SUBSTR(remarks, 1, 50)]'
WHEN 'WAIT_CLASS' THEN q'[CASE operation WHEN 'ON CPU' THEN operation ELSE options END]'
WHEN 'TIMED_EVENT' THEN q'[CASE operation WHEN 'ON CPU' THEN operation ELSE options||' - '||object_node END]'
WHEN 'PDB' THEN q'[object_owner||'('||plan_id||')']'
END AS grouping_expression
FROM DUAL
/
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF include_hist = 'N';
DEF include_mem = 'Y';
SET SERVEROUT OFF;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
--
SELECT '&&cs_file_prefix._&&cs_script_name._&&dimension.' cs_file_name FROM DUAL;
--
DEF report_title = "Peaks duration of Active Sessions in Concurrency contention exceeding &&times_cpu_cores.x CPU_CORES by top value - &&dimension.";
DEF chart_title = "&&report_title.";
DEF xaxis_title = "between &&cs_sample_time_from. and &&cs_sample_time_to.";
-- DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
-- DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}, 3:{}, 4:{}, 5:{}";
DEF vaxis_title = "Maximum Active Sessions";
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
--DEF is_stacked = "isStacked: false,";
DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = "<br>2) Bubble size indicates duration of contention. Label shows the top#1 contributor.";
DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores." "&&dimension."';
--
DEF spool_chart_1st_column = 'ID';
@@cs_internal/cs_spool_head_chart.sql
PRO , 'Time', 'Total Maximum Active Sessions', 'Top#1 &&dimension.', 'Approximate duration in seconds'
PRO ]
--
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
-- SELECT ', [''#'||ROW_NUMBER() OVER (ORDER BY cost DESC, timestamp)||' '||cost||''''||
SELECT ', ['''''||
', new Date('||
TO_CHAR(t.timestamp, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(t.timestamp, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(t.timestamp, 'DD')|| /* day */
','||TO_CHAR(t.timestamp, 'HH24')|| /* hour */
','||TO_CHAR(t.timestamp, 'MI')|| /* minute */
','||TO_CHAR(t.timestamp, 'SS')|| /* second */
')'||
', '||num_format(t.cardinality, 0)|| -- sessions_peak
', '''||&&grouping_expression.||''''||
', '||num_format(t.cost, 0)|| -- seconds
']'
FROM plan_table t
ORDER BY
t.cost DESC
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter|Bubble]
DEF cs_chart_type = 'Bubble';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,175 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_mem_peaks_chart.sql
--
-- Purpose: ASH Peaks Chart from MEM
--
-- Author: Carlos Sierra
--
-- Version: 2021/12/03
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_mem_peaks_chart.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_mem_peaks_chart';
DEF cs_hours_range_default = '3';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To chart on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
DEF include_hist = 'N';
DEF include_mem = 'Y';
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = "Active Sessions Peaks";
DEF chart_title = "&&report_title.";
DEF xaxis_title = "between &&cs_sample_time_from. and &&cs_sample_time_to.";
-- DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
-- DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}, 3:{}, 4:{}, 5:{}";
DEF vaxis_title = "Sum of Active Sessions per sampled time";
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
--DEF vaxis_baseline = "";
DEF chart_foot_note_2 = "<br>2)";
DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'Sessions Peak', id:'1', type:'number'}
PRO ,{label:'Before Peak', id:'2', type:'number'}
PRO ,{label:'After Peak', id:'3', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
threshold AS (
SELECT /*+ MATERIALIZE NO_MERGE */ &&times_cpu_cores. * value AS value FROM v$osstat WHERE stat_name = 'NUM_CPU_CORES' AND ROWNUM >= 1 /* MATERIALIZE */
),
active_sessions_time_series AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS active_sessions
FROM dba_hist_active_sess_history h
WHERE '&&include_hist.' = 'Y'
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.')
AND ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
h.sample_time
UNION
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS active_sessions
FROM v$active_session_history h
WHERE '&&include_mem.' = 'Y'
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
h.sample_time
),
time_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
SUM(active_sessions) AS active_sessions,
LAG(SUM(active_sessions)) OVER (ORDER BY sample_time) AS lag_active_sessions,
LEAD(SUM(active_sessions)) OVER (ORDER BY sample_time) AS lead_active_sessions
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time
),
t AS (
SELECT /*+ MATERIALIZE NO_MERGE */
t.sample_time,
CASE WHEN t.active_sessions >= threshold.value THEN t.active_sessions END AS peak_value,
CASE WHEN t.active_sessions < threshold.value AND t.lead_active_sessions >= threshold.value THEN t.active_sessions END AS before_value,
CASE WHEN t.active_sessions < threshold.value AND t.lag_active_sessions >= threshold.value THEN t.active_sessions END AS after_value
FROM threshold,
time_dim t
WHERE (t.active_sessions >= threshold.value OR t.lag_active_sessions >= threshold.value OR t.lead_active_sessions >= threshold.value)
AND ROWNUM >= 1 /* MATERIALIZE */
)
SELECT ', [new Date('||
TO_CHAR(t.sample_time, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(t.sample_time, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(t.sample_time, 'DD')|| /* day */
','||TO_CHAR(t.sample_time, 'HH24')|| /* hour */
','||TO_CHAR(t.sample_time, 'MI')|| /* minute */
','||TO_CHAR(t.sample_time, 'SS')|| /* second */
')'||
','||num_format(t.peak_value, 0)||
','||num_format(t.before_value, 0)||
','||num_format(t.after_value, 0)||
']'
FROM t
ORDER BY
t.sample_time
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,71 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_ash_mem_peaks_report.sql
--
-- Purpose: ASH Peaks Report from MEM
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_mem_peaks_report.sql
--
-- Notes: Developed and tested on 19c.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_mem_peaks_report';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '3';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO To report on Active Sessions over 1x the number of CPU Cores, then pass "1" (default) as Threshold value below
PRO
PRO 3. Threshold: [{1}|0-10]
DEF times_cpu_cores = '&3.';
UNDEF 3;
COL times_cpu_cores NEW_V times_cpu_cores NOPRI;
SELECT CASE WHEN TO_NUMBER(REPLACE(UPPER('&&times_cpu_cores.'), 'X')) BETWEEN 0 AND 10 THEN REPLACE(UPPER('&&times_cpu_cores.'), 'X') ELSE '1' END AS times_cpu_cores FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO THRESHOLD : "&&times_cpu_cores.x NUM_CPU_CORES"
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
-- DEF times_cpu_cores = '1';
DEF include_hist = 'N';
DEF include_mem = 'Y';
PRO
PRO Sum of Active Sessions per sampled time (when greater than &&times_cpu_cores.x CPU Cores)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
@@cs_internal/cs_active_sessions_peaks_internal_v6.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&times_cpu_cores."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,125 @@
----------------------------------------------------------------------------------------
--
-- File name: am.sql | cs_ash_mem_sample_report.sql
--
-- Purpose: ASH Samples from MEM
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter optional parameters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_mem_sample_report.sql
--
-- Notes: *** Requires Oracle Diagnostics Pack License ***
--
-- Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
SET PAGES 5000;
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_mem_sample_report';
DEF cs_script_acronym = 'am.sql | ';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '3';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Machine (opt):
DEF cs2_machine = '&3.';
UNDEF 3;
--
PRO
PRO 4. SQL_ID (opt):
DEF cs_sql_id = '&4.';
UNDEF 4;
--
PRO
PRO 5. SID,SERIAL (opt):
DEF cs_sid_serial = '&5.';
UNDEF 5;
--
PRO
PRO 6. Only LOB DEDUP TX 4 waiting sessions [{N}|Y]:
DEF cs_only_dedup = '&6.';
UNDEF 6;
COL cs_only_dedup NEW_V cs_only_dedup NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) ELSE 'N' END AS cs_only_dedup FROM DUAL
/
--
PRO
PRO 7. Include PL/SQL Library Entry Point [{N}|Y]:
DEF cs_pl_sql = '&7.';
UNDEF 7;
COL cs_pl_sql NEW_V cs_pl_sql NOPRI;
COL cs_pl_sql_pri NEW_V cs_pl_sql_pri NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) ELSE 'N' END AS cs_pl_sql, CASE SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) WHEN 'Y' THEN 'PRI' ELSE 'NOPRI' END AS cs_pl_sql_pri FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO MACHINE : "&&cs2_machine."
PRO SQL_ID : "&&cs_sql_id."
PRO SID,SERIAL : "&&cs_sid_serial."
PRO ONLY_DEDUP : "&&cs_only_dedup."
PRO INCL_PL_SQL : "&&cs_pl_sql."
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF times_cpu_cores = '1';
DEF include_hist = 'N';
DEF include_mem = 'Y';
PRO
PRO Sum of Active Sessions per sampled time (spikes greater than &&cs_num_cpu_cores. CPU Cores)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
@@cs_internal/cs_active_sessions_peaks_internal_v6.sql
--
DEF times_cpu_cores = '0';
DEF include_hist = 'N';
DEF include_mem = 'Y';
PRO
PRO Sum of Active Sessions per sampled time
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5.sql
--
DEF times_cpu_cores = '1';
DEF include_hist = 'N';
DEF include_mem = 'Y';
-- @@cs_internal/cs_ash_block_chains.sql
--
DEF ash_view = 'v$active_session_history';
DEF ash_additional_predicate = '';
-- DEF ash_view = 'dba_hist_active_sess_history';
-- DEF ash_additional_predicate = ' AND h.dbid = &&cs_dbid. AND h.instance_number = &&cs_instance_number. AND h.snap_id BETWEEN &&cs_snap_id_from. AND &&cs_snap_id_to. ';
--
@@cs_internal/cs_ash_sample_detail.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,116 @@
----------------------------------------------------------------------------------------
--
-- File name: ahs.sql | cs_ash_snap_sample_report.sql
--
-- Purpose: ASH Samples from iod_active_session_history Snapshot
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/04
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter optional parameters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_ash_snap_sample_report.sql
--
-- Notes: *** Requires Oracle Diagnostics Pack License ***
--
-- Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
SET PAGES 5000;
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_ash_snap_sample_report';
DEF cs_script_acronym = 'ahs.sql | ';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '24';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Machine (opt):
DEF cs2_machine = '&3.';
UNDEF 3;
--
PRO
PRO 4. SQL_ID (opt):
DEF cs_sql_id = '&4.';
UNDEF 4;
--
PRO
PRO 5. SID,SERIAL (opt):
DEF cs_sid_serial = '&5.';
UNDEF 5;
--
PRO
PRO 6. Only LOB DEDUP TX 4 waiting sessions [{N}|Y]:
DEF cs_only_dedup = '&6.';
UNDEF 6;
COL cs_only_dedup NEW_V cs_only_dedup NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_only_dedup.')), 1, 1) ELSE 'N' END AS cs_only_dedup FROM DUAL
/
--
PRO
PRO 7. Include PL/SQL Library Entry Point [{N}|Y]:
DEF cs_pl_sql = '&7.';
UNDEF 7;
COL cs_pl_sql NEW_V cs_pl_sql NOPRI;
COL cs_pl_sql_pri NEW_V cs_pl_sql_pri NOPRI;
SELECT CASE WHEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) IN ('N', 'Y') THEN SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) ELSE 'N' END AS cs_pl_sql, CASE SUBSTR(TRIM(UPPER('&&cs_pl_sql.')), 1, 1) WHEN 'Y' THEN 'PRI' ELSE 'NOPRI' END AS cs_pl_sql_pri FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup." "&&cs_pl_sql."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO MACHINE : "&&cs2_machine."
PRO SQL_ID : "&&cs_sql_id."
PRO SID,SERIAL : "&&cs_sid_serial."
PRO ONLY_DEDUP : "&&cs_only_dedup."
PRO INCL_PL_SQL : "&&cs_pl_sql."
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF ash_view = '&&cs_tools_schema..iod_active_session_history';
DEF ash_additional_predicate = '';
--
DEF times_cpu_cores = '1';
PRO
PRO Sum of Active Sessions per sampled time (spikes greater than &&cs_num_cpu_cores. CPU Cores)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5_s.sql
@@cs_internal/cs_active_sessions_peaks_internal_v6.sql
--
DEF times_cpu_cores = '0';
PRO
PRO Sum of Active Sessions per sampled time
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUT ON;
@@cs_internal/cs_active_sessions_peaks_internal_v5_s.sql
--
DEF times_cpu_cores = '1';
-- @@cs_internal/cs_ash_block_chains_s.sql
@@cs_internal/cs_ash_sample_detail.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_machine." "&&cs_sql_id." "&&cs_sid_serial." "&&cs_only_dedup." "&&cs_pl_sql."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,4 @@
REM Merges a snapshot of v$active_session_history into C##IOD.iod_active_session_history
select count(*) from c##iod.iod_active_session_history;
EXEC C##IOD.IOD_SESS.snap_ash(p_force => 'Y');
select count(*) from c##iod.iod_active_session_history;

View File

@@ -0,0 +1,852 @@
----------------------------------------------------------------------------------------
--
-- File name: aas.sql | cs_average_active_sessions.sql
--
-- Purpose: Average Active Sessions (ASH Analytics on dbc_active_session)
--
-- Author: Carlos Sierra
--
-- Version: 2021/11/25
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_average_active_sessions.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_average_active_sessions';
DEF cs_script_acronym = 'aas.sql | ';
--
DEF cs_hours_range_default = '336';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
COL cs2_granularity_list NEW_V cs2_granularity_list NOPRI;
COL cs2_default_granularity NEW_V cs2_default_granularity NOPRI;
SELECT CASE
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 12 THEN '[{1m}|5m|15m|1h|1d|m|h|d]' -- < 12h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 60 THEN '[{5m}|1m|15m|1h|1d|m|h|d]' -- < 60h (2.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 180 THEN '[{15m}|1m|5m|1h|1d|m|h|d]' -- < 180h (7.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 720 THEN '[{1h}|1m|5m|15m|1d|m|h|d]' -- < 720h (30d) (up to 720 samples)
ELSE '[{1d}|1m|5m|15m|1h|1d|m|h|d]'
END AS cs2_granularity_list,
CASE
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 12 THEN '1m' -- < 12h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 60 THEN '5m' -- < 60h (2.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 180 THEN '15m' -- < 180h (7.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 720 THEN '1h' -- < 720h (30d) (up to 720 samples)
ELSE '1d'
END AS cs2_default_granularity
FROM DUAL
/
PRO
PRO 3. Granularity: &&cs2_granularity_list.
DEF cs2_granularity = '&3.';
UNDEF 3;
COL cs2_granularity NEW_V cs2_granularity NOPRI;
SELECT NVL(LOWER(TRIM('&&cs2_granularity.')), '&&cs2_default_granularity.') cs2_granularity FROM DUAL;
SELECT CASE
WHEN '&&cs2_granularity.' = 'm' THEN '1m'
WHEN '&&cs2_granularity.' = 'h' THEN '1h'
WHEN '&&cs2_granularity.' = 'd' THEN '1d'
WHEN '&&cs2_granularity.' IN ('1m', '5m', '15m', '1h', '1d') THEN '&&cs2_granularity.'
ELSE '&&cs2_default_granularity.'
END cs2_granularity
FROM DUAL
/
--
COL cs2_fmt NEW_V cs2_fmt NOPRI;
SELECT CASE '&&cs2_granularity.'
WHEN '1m' THEN 'MI' -- (1/24/60) 1 minute
WHEN '5m' THEN 'MI' -- (5/24/60) 5 minutes
WHEN '15m' THEN 'MI' -- (15/24/60) 15 minutes
WHEN '1h' THEN 'HH' -- (1/24) 1 hour
WHEN '1d' THEN 'DD' -- 1 day
ELSE 'XX' -- error
END cs2_fmt
FROM DUAL
/
--
COL cs2_plus_days NEW_V cs2_plus_days NOPRI;
SELECT CASE '&&cs2_granularity.'
WHEN '1m' THEN '(1/24/60)' -- (1/24/60) 1 minute
WHEN '5m' THEN '(5/24/60)' -- (5/24/60) 5 minutes
WHEN '15m' THEN '(15/24/60)' -- (15/24/60) 15 minutes
WHEN '1h' THEN '(1/24)' -- (1/24) 1 hour
WHEN '1d' THEN '1' -- 1 day
ELSE 'XX' -- error
END cs2_plus_days
FROM DUAL
/
--
PRO
PRO 4. Reporting Dimension: [{event}|wait_class|machine|sql_id|plan_hash_value|module|pdb_name|host_name]
DEF cs2_dimension = '&4.';
UNDEF 4;
COL cs2_dimension NEW_V cs2_dimension NOPRI;
-- SELECT NVL(LOWER(TRIM('&&cs2_dimension.')), 'event') cs2_dimension FROM DUAL;
SELECT CASE WHEN LOWER(TRIM('&&cs2_dimension.')) IN ('event', 'wait_class', 'machine', 'sql_id', 'plan_hash_value', 'module', 'pdb_name', 'host_name') THEN LOWER(TRIM('&&cs2_dimension.')) ELSE 'event' END cs2_dimension FROM DUAL;
--
COL use_oem_colors_series NEW_V use_oem_colors_series NOPRI;
SELECT CASE '&&cs2_dimension.' WHEN 'wait_class' THEN NULL ELSE '//' END AS use_oem_colors_series FROM DUAL;
--
COL cs2_samples NEW_V cs2_samples NOPRI;
SELECT TO_CHAR(CEIL((TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') - TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.')) / &&cs2_plus_days.)) AS cs2_samples FROM DUAL
/
--
COL aas FOR 999,990.000 HEA 'Average Active|Sessions (AAS)';
COL db_seconds FOR 999,999,990 HEA 'DB Seconds';
COL session_state FOR A13 HEA 'Session|State';
BREAK ON REPORT;
COMPUTE SUM OF aas db_seconds ON REPORT;
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.session_state,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
GROUP BY
h.session_state
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
session_state
FROM ash_dbc
GROUP BY
session_state
ORDER BY
1 DESC
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 5. Session State (opt):
DEF cs2_session_state = '&5.';
UNDEF 5;
DEF cs2_instruct_to_skip = '(opt)';
COL cs2_instruct_to_skip NEW_V cs2_instruct_to_skip NOPRI;
SELECT '(hit "Return" to skip this patameter since Session State is "ON CPU")' AS cs2_instruct_to_skip FROM DUAL WHERE '&&cs2_session_state.' = 'ON CPU'
/
--
COL wait_class HEA 'Wait Class';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.session_state,
h.wait_class,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND NVL('&&cs2_session_state.', 'X') <> 'ON CPU'
GROUP BY
h.session_state,
h.wait_class
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
wait_class,
session_state
FROM ash_dbc
GROUP BY
wait_class,
session_state
ORDER BY
1 DESC
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 6. Wait Class &&cs2_instruct_to_skip.:
DEF cs2_wait_class = '&6.';
UNDEF 6;
--
COL cs2_group NEW_V cs2_group NOPRI;
SELECT CASE '&&cs2_dimension.'
WHEN 'wait_class' THEN q'[CASE h.session_state WHEN 'ON CPU' THEN h.session_state ELSE h.wait_class END]'
WHEN 'event' THEN CASE WHEN '&&cs2_wait_class.' IS NULL THEN q'[CASE h.session_state WHEN 'ON CPU' THEN h.session_state ELSE h.wait_class||' - '||h.event END]' ELSE q'[h.event]' END
WHEN 'machine' THEN q'[h.machine]'
WHEN 'sql_id' THEN q'[h.sql_id]'
WHEN 'plan_hash_value' THEN q'[TO_CHAR(h.sql_plan_hash_value)]'
WHEN 'module' THEN q'[h.module]'
WHEN 'pdb_name' THEN q'[h.pdb_name]'
WHEN 'host_name' THEN q'[h.host_name]'
END AS cs2_group
FROM DUAL
/
--
COL event HEA 'Event';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.event,
h.wait_class,
h.session_state,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND NVL('&&cs2_session_state.', 'X') <> 'ON CPU'
AND ('&&cs2_wait_class.' IS NULL OR h.wait_class = '&&cs2_wait_class.')
GROUP BY
h.event,
h.wait_class,
h.session_state
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
event,
wait_class,
session_state
FROM ash_dbc
GROUP BY
event,
wait_class,
session_state
ORDER BY
1 DESC
FETCH FIRST 30 ROWS ONLY
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 7. Event &&cs2_instruct_to_skip.:
DEF cs2_event = '&7.';
UNDEF 7;
--
COL machine HEA 'Machine';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.machine,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND ('&&cs2_wait_class.' IS NULL OR h.wait_class = '&&cs2_wait_class.')
AND ('&&cs2_event.' IS NULL OR h.event LIKE CHR(37)||'&&cs2_event.'||CHR(37))
GROUP BY
h.machine
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
machine
FROM ash_dbc
GROUP BY
machine
ORDER BY
1 DESC
FETCH FIRST 30 ROWS ONLY
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 8. Machine (opt):
DEF cs2_machine = '&8.';
UNDEF 8;
--
PRO
PRO 9. SQL Text piece (e.g.: ScanQuery, getValues, TableName, IndexName):
DEF cs2_sql_text_piece = '&9.';
UNDEF 9;
--
COL sql_text FOR A60 TRUNC;
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sql_id,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND ('&&cs2_wait_class.' IS NULL OR h.wait_class = '&&cs2_wait_class.')
AND ('&&cs2_event.' IS NULL OR h.event LIKE CHR(37)||'&&cs2_event.'||CHR(37))
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT /*+ NO_MERGE */ t.sql_id FROM sql_txt t))
GROUP BY
h.sql_id
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
sql_id,
(SELECT s.sql_text FROM sql_txt s WHERE s.sql_id = a.sql_id AND ROWNUM = 1) AS sql_text
FROM ash_dbc a
GROUP BY
sql_id
ORDER BY
1 DESC
FETCH FIRST 30 ROWS ONLY
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 10. SQL_ID (opt):
DEF cs2_sql_id = '&10.';
UNDEF 10;
--
DEF spool_id_chart_footer_script = 'cs_ash_analytics_footer.sql';
COL rn FOR 999;
COL dimension_group FOR A64 TRUNC;
DEF series_01 = ' ';
DEF series_02 = ' ';
DEF series_03 = ' ';
DEF series_04 = ' ';
DEF series_05 = ' ';
DEF series_06 = ' ';
DEF series_07 = ' ';
DEF series_08 = ' ';
DEF series_09 = ' ';
DEF series_10 = ' ';
DEF series_11 = ' ';
DEF series_12 = ' ';
DEF series_13 = ' ';
COL series_01 NEW_V series_01 FOR A64 TRUNC NOPRI;
COL series_02 NEW_V series_02 FOR A64 TRUNC NOPRI;
COL series_03 NEW_V series_03 FOR A64 TRUNC NOPRI;
COL series_04 NEW_V series_04 FOR A64 TRUNC NOPRI;
COL series_05 NEW_V series_05 FOR A64 TRUNC NOPRI;
COL series_06 NEW_V series_06 FOR A64 TRUNC NOPRI;
COL series_07 NEW_V series_07 FOR A64 TRUNC NOPRI;
COL series_08 NEW_V series_08 FOR A64 TRUNC NOPRI;
COL series_09 NEW_V series_09 FOR A64 TRUNC NOPRI;
COL series_10 NEW_V series_10 FOR A64 TRUNC NOPRI;
COL series_11 NEW_V series_11 FOR A64 TRUNC NOPRI;
COL series_12 NEW_V series_12 FOR A64 TRUNC NOPRI;
COL series_13 NEW_V series_13 FOR A64 TRUNC NOPRI;
DEF aas_01 = ' ';
DEF aas_02 = ' ';
DEF aas_03 = ' ';
DEF aas_04 = ' ';
DEF aas_05 = ' ';
DEF aas_06 = ' ';
DEF aas_07 = ' ';
DEF aas_08 = ' ';
DEF aas_09 = ' ';
DEF aas_10 = ' ';
DEF aas_11 = ' ';
DEF aas_12 = ' ';
DEF aas_13 = ' ';
COL aas_01 NEW_V aas_01 FOR A9 TRUNC NOPRI;
COL aas_02 NEW_V aas_02 FOR A9 TRUNC NOPRI;
COL aas_03 NEW_V aas_03 FOR A9 TRUNC NOPRI;
COL aas_04 NEW_V aas_04 FOR A9 TRUNC NOPRI;
COL aas_05 NEW_V aas_05 FOR A9 TRUNC NOPRI;
COL aas_06 NEW_V aas_06 FOR A9 TRUNC NOPRI;
COL aas_07 NEW_V aas_07 FOR A9 TRUNC NOPRI;
COL aas_08 NEW_V aas_08 FOR A9 TRUNC NOPRI;
COL aas_09 NEW_V aas_09 FOR A9 TRUNC NOPRI;
COL aas_10 NEW_V aas_10 FOR A9 TRUNC NOPRI;
COL aas_11 NEW_V aas_11 FOR A9 TRUNC NOPRI;
COL aas_12 NEW_V aas_12 FOR A9 TRUNC NOPRI;
COL aas_13 NEW_V aas_13 FOR A9 TRUNC NOPRI;
--
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
FUNCTION get_sql_text (p_sql_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_sql_text VARCHAR2(4000);
BEGIN
SELECT MAX(REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM v$sql
WHERE sql_id = p_sql_id
AND ROWNUM = 1;
--
IF l_sql_text IS NOT NULL THEN
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END IF;
--
SELECT MAX(REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM dba_hist_sqltext
WHERE sql_id = p_sql_id
AND dbid = &&cs_dbid.
AND ROWNUM = 1;
--
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END get_sql_text;
--
wait_classes AS (
SELECT 1 AS rn, 'ON CPU' AS dimension_group FROM DUAL
UNION SELECT 2 AS rn, 'User I/O' AS dimension_group FROM DUAL
UNION SELECT 3 AS rn, 'System I/O' AS dimension_group FROM DUAL
UNION SELECT 4 AS rn, 'Cluster' AS dimension_group FROM DUAL
UNION SELECT 5 AS rn, 'Commit' AS dimension_group FROM DUAL
UNION SELECT 6 AS rn, 'Concurrency' AS dimension_group FROM DUAL
UNION SELECT 7 AS rn, 'Application' AS dimension_group FROM DUAL
UNION SELECT 8 AS rn, 'Administrative' AS dimension_group FROM DUAL
UNION SELECT 9 AS rn, 'Configuration' AS dimension_group FROM DUAL
UNION SELECT 10 AS rn, 'Network' AS dimension_group FROM DUAL
UNION SELECT 11 AS rn, 'Queueing' AS dimension_group FROM DUAL
UNION SELECT 12 AS rn, 'Scheduler' AS dimension_group FROM DUAL
UNION SELECT 13 AS rn, 'Other' AS dimension_group FROM DUAL
),
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
&&cs2_group. AS dimension_group,
10 * SUM(h.sum_samples) AS db_seconds
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND ('&&cs2_wait_class.' IS NULL OR h.wait_class = '&&cs2_wait_class.')
AND ('&&cs2_event.' IS NULL OR h.event LIKE CHR(37)||'&&cs2_event.'||CHR(37))
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT /*+ NO_MERGE */ t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
GROUP BY
&&cs2_group.
),
ash_by_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
dimension_group,
ROW_NUMBER() OVER(ORDER BY SUM(db_seconds) DESC) AS rn
FROM ash_dbc a
GROUP BY
dimension_group
),
top AS (
SELECT /*+ MATERIALIZE NO_MERGE */
rn, -- up to 12
aas,
db_seconds,
SUBSTR(CASE
WHEN TRIM(dimension_group) IS NULL THEN '"null"'
WHEN '&&cs2_dimension.' = 'sql_id' THEN dimension_group||' '||get_sql_text(dimension_group)
ELSE dimension_group
END, 1, 64) AS dimension_group
FROM ash_by_dim
WHERE rn < (SELECT MAX(rn) FROM wait_classes) -- 13
),
max_top AS (
SELECT /*+ MATERIALIZE NO_MERGE */ MAX(rn) AS max_rn FROM top
),
bottom AS (
SELECT /*+ MATERIALIZE NO_MERGE */
(1 + max_top.max_rn) AS bottom_rn, -- up to 13
ROUND(SUM(a.db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(a.db_seconds) AS db_seconds,
'"all others"' AS dimension_group
FROM ash_by_dim a, max_top
WHERE a.rn >= max_top.max_rn
GROUP BY
max_top.max_rn
),
wait_classes2 AS (
SELECT /*+ MATERIALIZE NO_MERGE */
w.rn,
NVL(t.aas, 0) AS aas,
NVL(t.db_seconds, 0) AS db_seconds,
w.dimension_group
FROM wait_classes w,
top t
WHERE '&&cs2_dimension.' = 'wait_class'
AND t.dimension_group(+) = w.dimension_group
),
top_and_bottom AS (
SELECT rn, aas, db_seconds, dimension_group
FROM top
WHERE '&&cs2_dimension.' <> 'wait_class'
UNION ALL
SELECT rn, aas, db_seconds, dimension_group
FROM wait_classes2
WHERE '&&cs2_dimension.' = 'wait_class'
UNION ALL
SELECT bottom_rn AS rn, aas, db_seconds, dimension_group
FROM bottom
WHERE '&&cs2_dimension.' <> 'wait_class'
),
list AS (
SELECT /*+ MATERIALIZE NO_MERGE */
rn, LPAD(TRIM(TO_CHAR(ROUND(aas, 3), '9,990.000')), 9) AS aas, db_seconds, dimension_group
FROM top_and_bottom
)
SELECT rn, aas, db_seconds, dimension_group,
COALESCE((SELECT dimension_group FROM list WHERE rn = 1), ' ') AS series_01,
COALESCE((SELECT dimension_group FROM list WHERE rn = 2), ' ') AS series_02,
COALESCE((SELECT dimension_group FROM list WHERE rn = 3), ' ') AS series_03,
COALESCE((SELECT dimension_group FROM list WHERE rn = 4), ' ') AS series_04,
COALESCE((SELECT dimension_group FROM list WHERE rn = 5), ' ') AS series_05,
COALESCE((SELECT dimension_group FROM list WHERE rn = 6), ' ') AS series_06,
COALESCE((SELECT dimension_group FROM list WHERE rn = 7), ' ') AS series_07,
COALESCE((SELECT dimension_group FROM list WHERE rn = 8), ' ') AS series_08,
COALESCE((SELECT dimension_group FROM list WHERE rn = 9), ' ') AS series_09,
COALESCE((SELECT dimension_group FROM list WHERE rn = 10), ' ') AS series_10,
COALESCE((SELECT dimension_group FROM list WHERE rn = 11), ' ') AS series_11,
COALESCE((SELECT dimension_group FROM list WHERE rn = 12), ' ') AS series_12,
COALESCE((SELECT dimension_group FROM list WHERE rn = 13), ' ') AS series_13,
(SELECT aas FROM list WHERE rn = 1) AS aas_01,
(SELECT aas FROM list WHERE rn = 2) AS aas_02,
(SELECT aas FROM list WHERE rn = 3) AS aas_03,
(SELECT aas FROM list WHERE rn = 4) AS aas_04,
(SELECT aas FROM list WHERE rn = 5) AS aas_05,
(SELECT aas FROM list WHERE rn = 6) AS aas_06,
(SELECT aas FROM list WHERE rn = 7) AS aas_07,
(SELECT aas FROM list WHERE rn = 8) AS aas_08,
(SELECT aas FROM list WHERE rn = 9) AS aas_09,
(SELECT aas FROM list WHERE rn = 10) AS aas_10,
(SELECT aas FROM list WHERE rn = 11) AS aas_11,
(SELECT aas FROM list WHERE rn = 12) AS aas_12,
(SELECT aas FROM list WHERE rn = 13) AS aas_13
FROM list
ORDER BY
rn
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Average Active Sessions by "&&cs2_dimension." between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF vaxis_title = 'Average Active Sessions (AAS)';
DEF xaxis_title = '';
--
COL xaxis_title NEW_V xaxis_title NOPRI;
SELECT
CASE WHEN '&&cs2_session_state.' IS NOT NULL THEN 'State:"&&cs2_session_state." ' END||
CASE WHEN '&&cs2_wait_class.' IS NOT NULL THEN 'Wait:"&&cs2_wait_class." ' END||
CASE WHEN '&&cs2_event.' IS NOT NULL THEN 'Event:"%&&cs2_event.%" ' END||
CASE WHEN '&&cs2_machine.' IS NOT NULL THEN 'Machine:"%&&cs2_machine.%" ' END||
CASE WHEN '&&cs2_sql_text_piece.' IS NOT NULL THEN 'Text:"%&&cs2_sql_text_piece.%" ' END||
CASE WHEN '&&cs2_sql_id.' IS NOT NULL THEN 'SQL_ID:"&&cs2_sql_id." ' END AS xaxis_title
FROM DUAL;
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
--DEF is_stacked = "isStacked: false,";
DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
--DEF chart_foot_note_2 = "<br>2)";
DEF chart_foot_note_2 = '<br>2) &&xaxis_title.';
DEF chart_foot_note_3 = "<br>";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_granularity." "&&cs2_dimension." "&&cs2_session_state." "&&cs2_wait_class." "&&cs2_event." "&&cs2_machine." "&&cs2_sql_text_piece." "&&cs2_sql_id."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&series_01.', id:'01', type:'number'}
PRO ,{label:'&&series_02.', id:'02', type:'number'}
PRO ,{label:'&&series_03.', id:'03', type:'number'}
PRO ,{label:'&&series_04.', id:'04', type:'number'}
PRO ,{label:'&&series_05.', id:'05', type:'number'}
PRO ,{label:'&&series_06.', id:'06', type:'number'}
PRO ,{label:'&&series_07.', id:'07', type:'number'}
PRO ,{label:'&&series_08.', id:'08', type:'number'}
PRO ,{label:'&&series_09.', id:'09', type:'number'}
PRO ,{label:'&&series_10.', id:'10', type:'number'}
PRO ,{label:'&&series_11.', id:'11', type:'number'}
PRO ,{label:'&&series_12.', id:'12', type:'number'}
PRO ,{label:'&&series_13.', id:'13', type:'number'}
PRO ]
SET HEA OFF PAGES 0;
/****************************************************************************************/
@@cs_internal/&&cs_set_container_to_cdb_root.
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
FUNCTION ceil_timestamp (p_timestamp IN TIMESTAMP)
RETURN DATE
IS
BEGIN
IF '&&cs2_granularity.' = '5m' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'HH') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 5) * 5 / (24 * 60) + &&cs2_plus_days.;
ELSIF '&&cs2_granularity.' = '15m' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'HH') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 15) * 15 / (24 * 60) + &&cs2_plus_days.;
ELSE -- 1m, 1h, 1d
RETURN TRUNC(CAST(p_timestamp AS DATE) + &&cs2_plus_days., '&&cs2_fmt.');
END IF;
END ceil_timestamp;
/****************************************************************************************/
FUNCTION get_sql_text (p_sql_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_sql_text VARCHAR2(4000);
BEGIN
SELECT MAX(REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM v$sql
WHERE sql_id = p_sql_id
AND ROWNUM = 1;
--
IF l_sql_text IS NOT NULL THEN
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END IF;
--
SELECT MAX(REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM dba_hist_sqltext
WHERE sql_id = p_sql_id
AND dbid = &&cs_dbid.
AND ROWNUM = 1;
--
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END get_sql_text;
/****************************************************************************************/
sample AS (
SELECT ceil_timestamp(TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') + ((LEVEL - 1) * &&cs2_plus_days.)) AS time FROM DUAL CONNECT BY LEVEL <= TO_NUMBER('&&cs2_samples.')
),
wait_classes AS (
SELECT 1 AS rn, 'ON CPU' AS dimension_group FROM DUAL
UNION SELECT 2 AS rn, 'User I/O' AS dimension_group FROM DUAL
UNION SELECT 3 AS rn, 'System I/O' AS dimension_group FROM DUAL
UNION SELECT 4 AS rn, 'Cluster' AS dimension_group FROM DUAL
UNION SELECT 5 AS rn, 'Commit' AS dimension_group FROM DUAL
UNION SELECT 6 AS rn, 'Concurrency' AS dimension_group FROM DUAL
UNION SELECT 7 AS rn, 'Application' AS dimension_group FROM DUAL
UNION SELECT 8 AS rn, 'Administrative' AS dimension_group FROM DUAL
UNION SELECT 9 AS rn, 'Configuration' AS dimension_group FROM DUAL
UNION SELECT 10 AS rn, 'Network' AS dimension_group FROM DUAL
UNION SELECT 11 AS rn, 'Queueing' AS dimension_group FROM DUAL
UNION SELECT 12 AS rn, 'Scheduler' AS dimension_group FROM DUAL
UNION SELECT 13 AS rn, 'Other' AS dimension_group FROM DUAL
),
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_dbc AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.end_time,
h.sum_samples,
h.max_samples,
CASE
WHEN TRIM(&&cs2_group.) IS NULL THEN '"null"'
WHEN '&&cs2_dimension.' = 'sql_id' THEN
CASE
WHEN &&cs2_group. = SUBSTR(q'[&&series_01.]', 1, INSTR(q'[&&series_01.]', ' ') - 1) THEN q'[&&series_01.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_02.]', 1, INSTR(q'[&&series_02.]', ' ') - 1) THEN q'[&&series_02.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_03.]', 1, INSTR(q'[&&series_03.]', ' ') - 1) THEN q'[&&series_03.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_04.]', 1, INSTR(q'[&&series_04.]', ' ') - 1) THEN q'[&&series_04.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_05.]', 1, INSTR(q'[&&series_05.]', ' ') - 1) THEN q'[&&series_05.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_06.]', 1, INSTR(q'[&&series_06.]', ' ') - 1) THEN q'[&&series_06.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_07.]', 1, INSTR(q'[&&series_07.]', ' ') - 1) THEN q'[&&series_07.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_08.]', 1, INSTR(q'[&&series_08.]', ' ') - 1) THEN q'[&&series_08.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_09.]', 1, INSTR(q'[&&series_09.]', ' ') - 1) THEN q'[&&series_09.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_10.]', 1, INSTR(q'[&&series_10.]', ' ') - 1) THEN q'[&&series_10.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_11.]', 1, INSTR(q'[&&series_11.]', ' ') - 1) THEN q'[&&series_11.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_12.]', 1, INSTR(q'[&&series_12.]', ' ') - 1) THEN q'[&&series_12.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_13.]', 1, INSTR(q'[&&series_13.]', ' ') - 1) THEN q'[&&series_13.]'
ELSE '"all others"' END
WHEN '&&cs2_dimension.' IN ('wait_class', 'event', 'machine', 'plan_hash_value', 'module', 'pdb_name', 'host_name') THEN
CASE
WHEN &&cs2_group. = q'[&&series_01.]' THEN q'[&&series_01.]'
WHEN &&cs2_group. = q'[&&series_02.]' THEN q'[&&series_02.]'
WHEN &&cs2_group. = q'[&&series_03.]' THEN q'[&&series_03.]'
WHEN &&cs2_group. = q'[&&series_04.]' THEN q'[&&series_04.]'
WHEN &&cs2_group. = q'[&&series_05.]' THEN q'[&&series_05.]'
WHEN &&cs2_group. = q'[&&series_06.]' THEN q'[&&series_06.]'
WHEN &&cs2_group. = q'[&&series_07.]' THEN q'[&&series_07.]'
WHEN &&cs2_group. = q'[&&series_08.]' THEN q'[&&series_08.]'
WHEN &&cs2_group. = q'[&&series_09.]' THEN q'[&&series_09.]'
WHEN &&cs2_group. = q'[&&series_10.]' THEN q'[&&series_10.]'
WHEN &&cs2_group. = q'[&&series_11.]' THEN q'[&&series_11.]'
WHEN &&cs2_group. = q'[&&series_12.]' THEN q'[&&series_12.]'
WHEN &&cs2_group. = q'[&&series_13.]' THEN q'[&&series_13.]'
ELSE '"all others"' END
ELSE '"all others"' END AS dimension_group
FROM &&cs_tools_schema..dbc_active_session h
WHERE h.end_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.end_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.db_domain = LOWER(SYS_CONTEXT('USERENV', 'DB_DOMAIN'))
AND h.db_name = UPPER(SYS_CONTEXT('USERENV', 'DB_NAME'))
AND '&&cs_con_name.' IN (h.pdb_name, 'CDB$ROOT')
AND ('&&cs2_session_state.' IS NULL OR h.session_state = '&&cs2_session_state.')
AND ('&&cs2_wait_class.' IS NULL OR h.wait_class = '&&cs2_wait_class.')
AND ('&&cs2_event.' IS NULL OR h.event LIKE CHR(37)||'&&cs2_event.'||CHR(37))
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT /*+ NO_MERGE */ t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
),
ash_dbc_denorm AS (
SELECT /*+ MATERIALIZE NO_MERGE */
ceil_timestamp(h.end_time) AS time,
SUM(CASE WHEN h.dimension_group = q'[&&series_01.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_01,
SUM(CASE WHEN h.dimension_group = q'[&&series_02.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_02,
SUM(CASE WHEN h.dimension_group = q'[&&series_03.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_03,
SUM(CASE WHEN h.dimension_group = q'[&&series_04.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_04,
SUM(CASE WHEN h.dimension_group = q'[&&series_05.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_05,
SUM(CASE WHEN h.dimension_group = q'[&&series_06.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_06,
SUM(CASE WHEN h.dimension_group = q'[&&series_07.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_07,
SUM(CASE WHEN h.dimension_group = q'[&&series_08.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_08,
SUM(CASE WHEN h.dimension_group = q'[&&series_09.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_09,
SUM(CASE WHEN h.dimension_group = q'[&&series_10.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_10,
SUM(CASE WHEN h.dimension_group = q'[&&series_11.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_11,
SUM(CASE WHEN h.dimension_group = q'[&&series_12.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_12,
SUM(CASE WHEN h.dimension_group = q'[&&series_13.]' THEN 10 * sum_samples ELSE 0 END) AS db_secs_13
FROM ash_dbc h
GROUP BY
ceil_timestamp(h.end_time)
),
ash_denorm AS (
SELECT time, (time - LAG(time, 1, time) OVER (ORDER BY time)) * 24 * 3600 AS interval_secs, db_secs_01, db_secs_02, db_secs_03, db_secs_04, db_secs_05, db_secs_06, db_secs_07, db_secs_08, db_secs_09, db_secs_10, db_secs_11, db_secs_12, db_secs_13 FROM ash_dbc_denorm
),
/****************************************************************************************/
my_query AS (
SELECT s.time, a.interval_secs, a.db_secs_01, a.db_secs_02, a.db_secs_03, a.db_secs_04, a.db_secs_05, a.db_secs_06, a.db_secs_07, a.db_secs_08, a.db_secs_09, a.db_secs_10, a.db_secs_11, a.db_secs_12, a.db_secs_13,
ROW_NUMBER() OVER (ORDER BY s.time ASC NULLS LAST) AS rn_asc,
ROW_NUMBER() OVER (ORDER BY s.time DESC NULLS LAST) AS rn_desc
FROM ash_denorm a,
sample s
WHERE a.interval_secs > 0
AND a.time(+) = s.time
)
SELECT ', [new Date('||
TO_CHAR(q.time, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(q.time, 'DD')|| /* day */
','||TO_CHAR(q.time, 'HH24')|| /* hour */
','||TO_CHAR(q.time, 'MI')|| /* minute */
','||TO_CHAR(q.time, 'SS')|| /* second */
')'||
','||num_format(q.db_secs_01 / q.interval_secs, 3)||
','||num_format(q.db_secs_02 / q.interval_secs, 3)||
','||num_format(q.db_secs_03 / q.interval_secs, 3)||
','||num_format(q.db_secs_04 / q.interval_secs, 3)||
','||num_format(q.db_secs_05 / q.interval_secs, 3)||
','||num_format(q.db_secs_06 / q.interval_secs, 3)||
','||num_format(q.db_secs_07 / q.interval_secs, 3)||
','||num_format(q.db_secs_08 / q.interval_secs, 3)||
','||num_format(q.db_secs_09 / q.interval_secs, 3)||
','||num_format(q.db_secs_10 / q.interval_secs, 3)||
','||num_format(q.db_secs_11 / q.interval_secs, 3)||
','||num_format(q.db_secs_12 / q.interval_secs, 3)||
','||num_format(q.db_secs_13 / q.interval_secs, 3)||
']'
FROM my_query q
WHERE 1 = 1
-- AND q.rn_asc > 1 AND q.rn_desc > 1
AND q.db_secs_01 + q.db_secs_02 + q.db_secs_03 + q.db_secs_04 + q.db_secs_05 + q.db_secs_06 + q.db_secs_07 + q.db_secs_08 + q.db_secs_09 + q.db_secs_10 + q.db_secs_11 + q.db_secs_12 + q.db_secs_13 > 0
ORDER BY
q.time
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'SteppedArea';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '&&use_oem_colors_series.';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

55
csierra/cs_binds.sql Normal file
View File

@@ -0,0 +1,55 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_binds.sql
--
-- Purpose: Binds for a given SQL_ID
--
-- Author: Carlos Sierra
--
-- Version: 2023/04/27
--
-- Usage: Execute connected to PDB.
--
-- Enter SQL_ID when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_binds.sql
--
-- Notes: *** Requires Oracle Diagnostics Pack License ***
--
-- Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_binds';
DEF cs_binds_days = '365';
--
PRO 1. SQL_ID:
DEF cs_sql_id = '&1.';
UNDEF 1;
--
SELECT '&&cs_file_prefix._&&cs_script_name._&&cs_sql_id.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_signature.sql
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sql_id."
@@cs_internal/cs_spool_id.sql
@@cs_internal/cs_spool_id_list_sql_id.sql
@@cs_internal/cs_print_sql_text.sql
@@cs_internal/cs_binds_xml.sql
@@cs_internal/cs_bind_capture_hist.sql
@@cs_internal/cs_bind_capture_mem.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sql_id."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,458 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_blocked_sessions_ash_awr_report.sql
--
-- Purpose: Top Session Blockers by multiple Dimensions as per ASH from AWR (text report)
--
-- Author: Carlos Sierra
--
-- Version: 2022/02/04
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_ash_awr_report.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_ash_awr_report';
DEF cs_hours_range_default = '24';
DEF cs_top_n = '20';
DEF cs_min_perc = '0.1';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
-- @@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
DEF times_cpu_cores = '1';
DEF include_hist = 'Y';
DEF include_mem = 'Y';
@@cs_internal/cs_ash_block_chains.sql
--
COL time FOR A19 HEA 'SAMPLE TIME';
COL blocked FOR 999,990 HEA 'BLOCKED|SESSIONS|COUNT';
COL percent FOR 999,990.000 HEA 'CONTRIBUTION|PERCENT %'
COL blocker FOR A12 HEA 'ROOT|BLOCKER|SID_SERIAL#';
COL blocker_machine FOR A64 HEA 'ROOT BLOCKER MACHINE';
COL blocker_module FOR A64 HEA 'ROOT BLOCKER MODULE';
COL blocker_status FOR A80 HEA 'ROOT BLOCKER TIMED EVENT';
COL blocker_sql_id FOR A13 HEA 'ROOT|BLOCKER|SQL_ID';
COL blocker_sql_text FOR A80 TRUNC HEA 'ROOT BLOCKER SQL_TEXT';
COL wait_class_event FOR A80 TRUNC HEA 'BLOCKEE(S) WAIT CLASS AND EVENT';
--
BREAK ON REPORT;
COMPUTE SUM OF percent ON REPORT;
--
PRO
PRO Root Blocker contribution percent by SQL_ID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 FROM detail
666666 GROUP BY
666666 blocker_sql_id,
666666 blocker_sql_text
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Timed Event (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_status
666666 FROM detail
666666 GROUP BY
666666 blocker_status
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Module (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_module
666666 FROM detail
666666 GROUP BY
666666 blocker_module
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Machine (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_machine
666666 FROM detail
666666 GROUP BY
666666 blocker_machine
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by SID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker
666666 FROM detail
666666 GROUP BY
666666 blocker
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Timed Event and SQL_ID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 FROM detail
666666 GROUP BY
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Module, Timed Event and SQL_ID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 FROM detail
666666 GROUP BY
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by Machine, Module, Timed Event and SQL_ID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker_machine,
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 FROM detail
666666 GROUP BY
666666 blocker_machine,
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Root Blocker contribution percent by SID, Machine, Module, Timed Event and SQL_ID (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 detail AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 b.time,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 b.module blocker_module,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ),
666666 summary AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 100 * SUM(blocked) / SUM(SUM(blocked)) OVER () percent,
666666 blocker,
666666 blocker_machine,
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 FROM detail
666666 GROUP BY
666666 blocker,
666666 blocker_machine,
666666 blocker_module,
666666 blocker_status,
666666 blocker_sql_id,
666666 blocker_sql_text
666666 )
666666 SELECT *
666666 FROM summary
666666 WHERE percent > &&cs_min_perc.
666666 ORDER BY
666666 1 DESC
666666 FETCH FIRST &&cs_top_n. ROWS ONLY;
SET TERM ON;
/
--
PRO
PRO Sample of Blocked Sessions (between &&cs_sample_time_from. and &&cs_sample_time_to. UTC)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 SELECT b.time,
666666 b.wait_class_event,
666666 b.sessions_blocked blocked,
666666 b.blocker_session_id||','||b.blocker_session_serial# blocker,
666666 b.machine blocker_machine,
666666 b.module blocker_module,
666666 --CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN b.blocker_status ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 CASE b.blocker_status WHEN 'INACTIVE or UNKNOWN' THEN (CASE b.machine WHEN '&&cs_host_name.' THEN 'UNKNOWN' ELSE 'INACTIVE' END) ELSE ('ACTIVE '||CASE b.blocker_session_state WHEN 'ON CPU' THEN b.blocker_session_state ELSE 'WAITING ON '||b.blocker_wait_class||' - '||b.blocker_event END) END blocker_status,
666666 b.blocker_sql_id,
666666 (SELECT s.sql_text FROM v$sql s WHERE s.sql_id = b.blocker_sql_id AND ROWNUM = 1) blocker_sql_text
666666 FROM blockers_and_blockees b
666666 WHERE b.sessions_blocked > 0
666666 ORDER BY
666666 b.time,
666666 b.blocker_session_id;
SET TERM ON;
/
--
PRO
PRO "INACTIVE" means: Database is waiting for Application Host to release LOCK, while "UNKNOWN" could be a BACKGROUND session on CDB$ROOT.
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."
--
@@cs_internal/cs_spool_tail.sql
--
-- @@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,206 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_blocked_sessions_by_machine_ash_awr_chart.sql
--
-- Purpose: Top Session Blockers by Machine of Root Blocker as per ASH from AWR (time series chart)
--
-- Author: Carlos Sierra
--
-- Version: 2021/02/10
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_by_machine_ash_awr_chart.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_by_machine_ash_awr_chart';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Root Blocker State: [{ANY}|ACTIVE|INACTIVE|ACTIVE ON CPU|ACTIVE WAITING|UNKNOWN]
DEF root_blocker_state = '&3.';
UNDEF 3;
COL root_blocker_state NEW_V root_blocker_state NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&root_blocker_state.')) IN ('ANY', 'ACTIVE', 'INACTIVE', 'ACTIVE ON CPU', 'ACTIVE WAITING', 'UNKNOWN') THEN UPPER(TRIM('&&root_blocker_state.')) ELSE 'ANY' END AS root_blocker_state FROM DUAL
/
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL machine_01 NEW_V machine_01 NOPRI;
COL machine_02 NEW_V machine_02 NOPRI;
COL machine_03 NEW_V machine_03 NOPRI;
COL machine_04 NEW_V machine_04 NOPRI;
COL machine_05 NEW_V machine_05 NOPRI;
COL machine_06 NEW_V machine_06 NOPRI;
COL machine_07 NEW_V machine_07 NOPRI;
COL machine_08 NEW_V machine_08 NOPRI;
COL machine_09 NEW_V machine_09 NOPRI;
COL machine_10 NEW_V machine_10 NOPRI;
COL machine_11 NEW_V machine_11 NOPRI;
COL machine_12 NEW_V machine_12 NOPRI;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 machine,
666666 ROW_NUMBER() OVER (ORDER BY SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) DESC NULLS LAST) top_sum
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 --AND machine <> 'unknown'
666666 GROUP BY
666666 machine
666666 )
666666 SELECT MAX(CASE top_sum WHEN 01 THEN machine END) machine_01,
666666 MAX(CASE top_sum WHEN 02 THEN machine END) machine_02,
666666 MAX(CASE top_sum WHEN 03 THEN machine END) machine_03,
666666 MAX(CASE top_sum WHEN 04 THEN machine END) machine_04,
666666 MAX(CASE top_sum WHEN 05 THEN machine END) machine_05,
666666 MAX(CASE top_sum WHEN 06 THEN machine END) machine_06,
666666 MAX(CASE top_sum WHEN 07 THEN machine END) machine_07,
666666 MAX(CASE top_sum WHEN 08 THEN machine END) machine_08,
666666 MAX(CASE top_sum WHEN 09 THEN machine END) machine_09,
666666 MAX(CASE top_sum WHEN 10 THEN machine END) machine_10,
666666 MAX(CASE top_sum WHEN 11 THEN machine END) machine_11,
666666 MAX(CASE top_sum WHEN 12 THEN machine END) machine_12
666666 FROM by_sessions_sum
666666 WHERE top_sum BETWEEN 1 AND 12;
SET TERM ON;
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Sessions Blocked by Machine of Root Blocker between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF xaxis_title = 'Root Blocker State: &&root_blocker_state.';
DEF vaxis_title = 'Blocked Sessions Count';
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = '<br>2) "INACTIVE" means: Database is waiting for Application Host to release LOCK.';
DEF chart_foot_note_3 = "<br>";
--DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&root_blocker_state."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&machine_01.', id:'01', type:'number'}
PRO ,{label:'&&machine_02.', id:'02', type:'number'}
PRO ,{label:'&&machine_03.', id:'03', type:'number'}
PRO ,{label:'&&machine_04.', id:'04', type:'number'}
PRO ,{label:'&&machine_05.', id:'05', type:'number'}
PRO ,{label:'&&machine_06.', id:'06', type:'number'}
PRO ,{label:'&&machine_07.', id:'07', type:'number'}
PRO ,{label:'&&machine_08.', id:'08', type:'number'}
PRO ,{label:'&&machine_09.', id:'09', type:'number'}
PRO ,{label:'&&machine_10.', id:'10', type:'number'}
PRO ,{label:'&&machine_11.', id:'11', type:'number'}
PRO ,{label:'&&machine_12.', id:'12', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 time,
666666 machine,
666666 SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) AS sessions_blocked
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 --AND machine <> 'unknown'
666666 GROUP BY
666666 time,
666666 machine
666666 )
666666 SELECT ', [new Date('||
666666 TO_CHAR(q.time, 'YYYY')|| /* year */
666666 ','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
666666 ','||TO_CHAR(q.time, 'DD')|| /* day */
666666 ','||TO_CHAR(q.time, 'HH24')|| /* hour */
666666 ','||TO_CHAR(q.time, 'MI')|| /* minute */
666666 ','||TO_CHAR(q.time, 'SS')|| /* second */
666666 ')'||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_01.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_02.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_03.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_04.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_05.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_06.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_07.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_08.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_09.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_10.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_11.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.machine WHEN '&&machine_12.' THEN q.sessions_blocked ELSE 0 END))||
666666 ']'
666666 FROM by_sessions_sum q
666666 GROUP BY
666666 q.time
666666 ORDER BY
666666 q.time;
SET TERM ON;
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,206 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_blocked_sessions_by_module_ash_awr_chart.sql
--
-- Purpose: Top Session Blockers by Module of Root Blocker as per ASH from AWR (time series chart)
--
-- Author: Carlos Sierra
--
-- Version: 2021/02/10
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_by_module_ash_awr_chart.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_by_module_ash_awr_chart';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Root Blocker State: [{ANY}|ACTIVE|INACTIVE|ACTIVE ON CPU|ACTIVE WAITING|UNKNOWN]
DEF root_blocker_state = '&3.';
UNDEF 3;
COL root_blocker_state NEW_V root_blocker_state NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&root_blocker_state.')) IN ('ANY', 'ACTIVE', 'INACTIVE', 'ACTIVE ON CPU', 'ACTIVE WAITING', 'UNKNOWN') THEN UPPER(TRIM('&&root_blocker_state.')) ELSE 'ANY' END AS root_blocker_state FROM DUAL
/
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL module_01 NEW_V module_01 NOPRI;
COL module_02 NEW_V module_02 NOPRI;
COL module_03 NEW_V module_03 NOPRI;
COL module_04 NEW_V module_04 NOPRI;
COL module_05 NEW_V module_05 NOPRI;
COL module_06 NEW_V module_06 NOPRI;
COL module_07 NEW_V module_07 NOPRI;
COL module_08 NEW_V module_08 NOPRI;
COL module_09 NEW_V module_09 NOPRI;
COL module_10 NEW_V module_10 NOPRI;
COL module_11 NEW_V module_11 NOPRI;
COL module_12 NEW_V module_12 NOPRI;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 module,
666666 ROW_NUMBER() OVER (ORDER BY SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) DESC NULLS LAST) top_sum
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 --AND module <> 'unknown'
666666 GROUP BY
666666 module
666666 )
666666 SELECT MAX(CASE top_sum WHEN 01 THEN module END) module_01,
666666 MAX(CASE top_sum WHEN 02 THEN module END) module_02,
666666 MAX(CASE top_sum WHEN 03 THEN module END) module_03,
666666 MAX(CASE top_sum WHEN 04 THEN module END) module_04,
666666 MAX(CASE top_sum WHEN 05 THEN module END) module_05,
666666 MAX(CASE top_sum WHEN 06 THEN module END) module_06,
666666 MAX(CASE top_sum WHEN 07 THEN module END) module_07,
666666 MAX(CASE top_sum WHEN 08 THEN module END) module_08,
666666 MAX(CASE top_sum WHEN 09 THEN module END) module_09,
666666 MAX(CASE top_sum WHEN 10 THEN module END) module_10,
666666 MAX(CASE top_sum WHEN 11 THEN module END) module_11,
666666 MAX(CASE top_sum WHEN 12 THEN module END) module_12
666666 FROM by_sessions_sum
666666 WHERE top_sum BETWEEN 1 AND 12;
SET TERM ON;
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Sessions Blocked by Module of Root Blocker between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF xaxis_title = 'Root Blocker State: &&root_blocker_state.';
DEF vaxis_title = 'Blocked Sessions Count';
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = '<br>2) "INACTIVE" means: Database is waiting for Application Host to release LOCK.';
DEF chart_foot_note_3 = "<br>";
--DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&root_blocker_state."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&module_01.', id:'01', type:'number'}
PRO ,{label:'&&module_02.', id:'02', type:'number'}
PRO ,{label:'&&module_03.', id:'03', type:'number'}
PRO ,{label:'&&module_04.', id:'04', type:'number'}
PRO ,{label:'&&module_05.', id:'05', type:'number'}
PRO ,{label:'&&module_06.', id:'06', type:'number'}
PRO ,{label:'&&module_07.', id:'07', type:'number'}
PRO ,{label:'&&module_08.', id:'08', type:'number'}
PRO ,{label:'&&module_09.', id:'09', type:'number'}
PRO ,{label:'&&module_10.', id:'10', type:'number'}
PRO ,{label:'&&module_11.', id:'11', type:'number'}
PRO ,{label:'&&module_12.', id:'12', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 time,
666666 module,
666666 SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) AS sessions_blocked
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 --AND module <> 'unknown'
666666 GROUP BY
666666 time,
666666 module
666666 )
666666 SELECT ', [new Date('||
666666 TO_CHAR(q.time, 'YYYY')|| /* year */
666666 ','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
666666 ','||TO_CHAR(q.time, 'DD')|| /* day */
666666 ','||TO_CHAR(q.time, 'HH24')|| /* hour */
666666 ','||TO_CHAR(q.time, 'MI')|| /* minute */
666666 ','||TO_CHAR(q.time, 'SS')|| /* second */
666666 ')'||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_01.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_02.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_03.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_04.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_05.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_06.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_07.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_08.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_09.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_10.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_11.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.module WHEN '&&module_12.' THEN q.sessions_blocked ELSE 0 END))||
666666 ']'
666666 FROM by_sessions_sum q
666666 GROUP BY
666666 q.time
666666 ORDER BY
666666 q.time;
SET TERM ON;
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,204 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_blocked_sessions_by_sid_ash_awr_chart.sql
--
-- Purpose: Top Session Blockers by SID of Root Blocker as per ASH from AWR (time series chart)
--
-- Author: Carlos Sierra
--
-- Version: 2021/02/10
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_by_sid_ash_awr_chart.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_by_sid_ash_awr_chart';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO 3. Root Blocker State: [{ANY}|ACTIVE|INACTIVE|ACTIVE ON CPU|ACTIVE WAITING|UNKNOWN]
DEF root_blocker_state = '&3.';
UNDEF 3;
COL root_blocker_state NEW_V root_blocker_state NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&root_blocker_state.')) IN ('ANY', 'ACTIVE', 'INACTIVE', 'ACTIVE ON CPU', 'ACTIVE WAITING', 'UNKNOWN') THEN UPPER(TRIM('&&root_blocker_state.')) ELSE 'ANY' END AS root_blocker_state FROM DUAL
/
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL sid_serial_01 NEW_V sid_serial_01 NOPRI;
COL sid_serial_02 NEW_V sid_serial_02 NOPRI;
COL sid_serial_03 NEW_V sid_serial_03 NOPRI;
COL sid_serial_04 NEW_V sid_serial_04 NOPRI;
COL sid_serial_05 NEW_V sid_serial_05 NOPRI;
COL sid_serial_06 NEW_V sid_serial_06 NOPRI;
COL sid_serial_07 NEW_V sid_serial_07 NOPRI;
COL sid_serial_08 NEW_V sid_serial_08 NOPRI;
COL sid_serial_09 NEW_V sid_serial_09 NOPRI;
COL sid_serial_10 NEW_V sid_serial_10 NOPRI;
COL sid_serial_11 NEW_V sid_serial_11 NOPRI;
COL sid_serial_12 NEW_V sid_serial_12 NOPRI;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 blocker_session_id, blocker_session_serial#,
666666 ROW_NUMBER() OVER (ORDER BY SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) DESC NULLS LAST) top_sum
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 GROUP BY
666666 blocker_session_id, blocker_session_serial#
666666 )
666666 SELECT MAX(CASE top_sum WHEN 01 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_01,
666666 MAX(CASE top_sum WHEN 02 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_02,
666666 MAX(CASE top_sum WHEN 03 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_03,
666666 MAX(CASE top_sum WHEN 04 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_04,
666666 MAX(CASE top_sum WHEN 05 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_05,
666666 MAX(CASE top_sum WHEN 06 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_06,
666666 MAX(CASE top_sum WHEN 07 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_07,
666666 MAX(CASE top_sum WHEN 08 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_08,
666666 MAX(CASE top_sum WHEN 09 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_09,
666666 MAX(CASE top_sum WHEN 10 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_10,
666666 MAX(CASE top_sum WHEN 11 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_11,
666666 MAX(CASE top_sum WHEN 12 THEN blocker_session_id||','||blocker_session_serial# END) sid_serial_12
666666 FROM by_sessions_sum
666666 WHERE top_sum BETWEEN 1 AND 12;
SET TERM ON;
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Sessions Blocked by SID of Root Blocker between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF xaxis_title = 'Root Blocker State: &&root_blocker_state.';
DEF vaxis_title = 'Blocked Sessions Count';
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = '<br>2) "INACTIVE" means: Database is waiting for Application Host to release LOCK, while "UNKNOWN" could be a BACKGROUND session on CDB$ROOT.';
DEF chart_foot_note_3 = "<br>";
--DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&root_blocker_state."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&sid_serial_01.', id:'01', type:'number'}
PRO ,{label:'&&sid_serial_02.', id:'02', type:'number'}
PRO ,{label:'&&sid_serial_03.', id:'03', type:'number'}
PRO ,{label:'&&sid_serial_04.', id:'04', type:'number'}
PRO ,{label:'&&sid_serial_05.', id:'05', type:'number'}
PRO ,{label:'&&sid_serial_06.', id:'06', type:'number'}
PRO ,{label:'&&sid_serial_07.', id:'07', type:'number'}
PRO ,{label:'&&sid_serial_08.', id:'08', type:'number'}
PRO ,{label:'&&sid_serial_09.', id:'09', type:'number'}
PRO ,{label:'&&sid_serial_10.', id:'10', type:'number'}
PRO ,{label:'&&sid_serial_11.', id:'11', type:'number'}
PRO ,{label:'&&sid_serial_12.', id:'12', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 ,
666666 by_sessions_sum AS (
666666 SELECT /*+ MATERIALIZE NO_MERGE */
666666 time,
666666 blocker_session_id||','||blocker_session_serial# AS sid_serial,
666666 SUM(CASE '&&root_blocker_state.'
666666 WHEN 'ANY' THEN sessions_blocked
666666 WHEN 'ACTIVE' THEN active_on_cpu + active_waiting
666666 WHEN 'INACTIVE' THEN inactive
666666 WHEN 'ACTIVE ON CPU' THEN active_on_cpu
666666 WHEN 'ACTIVE WAITING' THEN active_waiting
666666 WHEN 'UNKNOWN' THEN unknown
666666 END
666666 ) AS sessions_blocked
666666 FROM blockers_and_blockees
666666 WHERE sessions_blocked > 0
666666 GROUP BY
666666 time,
666666 blocker_session_id||','||blocker_session_serial#
666666 )
666666 SELECT ', [new Date('||
666666 TO_CHAR(q.time, 'YYYY')|| /* year */
666666 ','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
666666 ','||TO_CHAR(q.time, 'DD')|| /* day */
666666 ','||TO_CHAR(q.time, 'HH24')|| /* hour */
666666 ','||TO_CHAR(q.time, 'MI')|| /* minute */
666666 ','||TO_CHAR(q.time, 'SS')|| /* second */
666666 ')'||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_01.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_02.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_03.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_04.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_05.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_06.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_07.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_08.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_09.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_10.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_11.' THEN q.sessions_blocked ELSE 0 END))||
666666 ','||num_format(SUM(CASE q.sid_serial WHEN '&&sid_serial_12.' THEN q.sessions_blocked ELSE 0 END))||
666666 ']'
666666 FROM by_sessions_sum q
666666 GROUP BY
666666 q.time
666666 ORDER BY
666666 q.time;
SET TERM ON;
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,111 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_blocked_sessions_by_state_ash_awr_chart.sql
--
-- Purpose: Top Session Blockers by State of Root Blocker as per ASH from AWR (time series chart)
--
-- Author: Carlos Sierra
--
-- Version: 2021/01/17
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_by_state_ash_awr_chart.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_by_state_ash_awr_chart';
DEF cs_hours_range_default = '24';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Blocked Sessions by State of Root Blocker between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF xaxis_title = '';
DEF vaxis_title = 'Blocked Sessions Count';
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: false,";
--DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
DEF chart_foot_note_2 = '<br>2) "INACTIVE" means: Database is waiting for Application Host to release LOCK, while "UNKNOWN" could be a BACKGROUND session on CDB$ROOT.';
DEF chart_foot_note_3 = "<br>";
--DEF chart_foot_note_3 = "";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'ACTIVE ON CPU', id:'1', type:'number'}
PRO ,{label:'ACTIVE WAITING', id:'2', type:'number'}
PRO ,{label:'INACTIVE', id:'3', type:'number'}
PRO ,{label:'UNKNOWN', id:'4', type:'number'}
PRO ]
--
SET HEA OFF PAGES 0;
--
SET TERM OFF;
GET cs_internal/cs_blocked_sessions_ash_awr_internal.sql NOLIST
.
666666 SELECT ', [new Date('||
666666 TO_CHAR(q.time, 'YYYY')|| /* year */
666666 ','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
666666 ','||TO_CHAR(q.time, 'DD')|| /* day */
666666 ','||TO_CHAR(q.time, 'HH24')|| /* hour */
666666 ','||TO_CHAR(q.time, 'MI')|| /* minute */
666666 ','||TO_CHAR(q.time, 'SS')|| /* second */
666666 ')'||
666666 ','||num_format(SUM(q.active_on_cpu))|| -- ACTIVE ON CPU
666666 ','||num_format(SUM(q.active_waiting))|| -- ACTIVE WAITING
666666 ','||num_format(SUM(q.inactive))|| -- INACTIVE
666666 ','||num_format(SUM(q.unknown))|| -- UNKNOWN
666666 ']'
666666 FROM blockers_and_blockees q
666666 WHERE q.sessions_blocked > 0
666666 GROUP BY
666666 q.time
666666 ORDER BY
666666 q.time;
SET TERM ON;
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Scatter';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '//';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,232 @@
----------------------------------------------------------------------------------------
--
-- File name: bs.sql | cs_blocked_sessions_report.sql
--
-- Purpose: Blocked Sessions Report
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/25
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter optional parameters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_blocked_sessions_report.sql
--
-- Notes: Developed and tested on 19c
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
SET PAGES 5000;
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_blocked_sessions_report';
DEF cs_script_acronym = 'bs.sql | ';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF cs_hours_range_default = '24';
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
COL snap_time NEW_V snap_time;
@@cs_internal/&&cs_set_container_to_cdb_root.
SELECT snap_time,
COUNT(*) AS sessions,
SUM(CASE WHEN blocking_session_status = 'VALID' OR final_blocking_session_status = 'VALID' THEN 1 ELSE 0 END) AS blockees,
SUM(CASE WHEN blocking_session_status = 'VALID' OR final_blocking_session_status = 'VALID' THEN 0 ELSE 1 END) AS final_blockers
FROM &&cs_tools_schema..iod_blocked_session
WHERE snap_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND snap_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
GROUP BY
snap_time
ORDER BY
snap_time
/
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
PRO
PRO 3. Snap Time:
DEF cs_snap_time = '&3.';
UNDEF 3;
SELECT NVL('&&cs_snap_time.', '&&snap_time.') AS snap_time FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&snap_time."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO SNAP_TIME : "&&snap_time."
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL sql_text FOR A70 HEA 'SQL Text' TRUNC;
COL procedure_name FOR A70 HEA 'PL/SQL Library Entry Point' TRUNC;
COL module_action_program FOR A70 HEA 'Module Action Program' TRUNC;
COL sample_date_time FOR A23 HEA 'Sample Date and Time';
COL samples FOR 9999,999 HEA 'Active|Sessions';
COL on_cpu_or_wait_class FOR A14 HEA 'ON CPU or|Wait Class';
COL on_cpu_or_wait_event FOR A50 HEA 'ON CPU or Timed Event';
COL sid FOR A10 HEA 'Session';
COL machine FOR A60 HEA 'Machine or Application Server';
COL con_id FOR 999999;
COL plans FOR 99999 HEA 'Plans';
COL sessions FOR 9999,999 HEA 'Sessions|this SQL';
COL pdb_name FOR A30 HEA 'PDB Name' TRUNC;
COL sql_id FOR A13 HEA 'SQL_ID';
COL blocking_session_status FOR A11 HEA 'Blocker|Session|Status';
COL sql_plan_hash_value FOR 9999999999 HEA 'Plan|Hash Value';
COL sql_plan_line_id FOR 9999 HEA 'Plan|Line';
COL sql_child_number FOR 999999 HEA 'Child|Number';
COL sql_exec_id FOR 99999999 HEA 'Exec ID';
COL xid FOR A16 HEA 'Transaction ID';
COL current_obj# FOR 9999999999 HEA 'Current|Obj#';
COL current_file# FOR 9999999999 HEA 'Current|File#';
COL current_block# FOR 9999999999 HEA 'Current|Block#';
COL current_row# FOR 9999999999 HEA 'Current|Row#';
COL in_connection_mgmt FOR A6 HEA 'In|Connec|Mgmt';
COL in_parse FOR A6 HEA 'In|Parse';
COL in_hard_parse FOR A6 HEA 'In|Hard|Parse';
COL in_sql_execution FOR A6 HEA 'In|SQL|Exec';
COL in_plsql_execution FOR A6 HEA 'In|PLSQL|Exec';
COL in_plsql_rpc FOR A6 HEA 'In|PLSQL|RPC';
COL in_plsql_compilation FOR A6 HEA 'In|PLSQL|Compil';
COL in_java_execution FOR A6 HEA 'In|Java|Exec';
COL in_bind FOR A6 HEA 'In|Bind';
COL in_cursor_close FOR A6 HEA 'In|Cursor|Close';
COL in_sequence_load FOR A6 HEA 'In|Seq|Load';
COL top_level_sql_id FOR A13 HEA 'Top Level|SQL_ID';
COL blocking_session FOR A10 HEA 'Blocker|Session';
COL blocking2_session FOR A10 HEA 'Blocker(2)|Session';
COL blocking3_session FOR A10 HEA 'Blocker(3)|Session';
COL blocking4_session FOR A10 HEA 'Blocker(4)|Session';
COL blocking5_session FOR A10 HEA 'Blocker(5)|Session';
COL blocking_machine FOR A60 HEA 'Machine or Application Server (blocker)';
COL deadlock FOR A4 HEA 'Dead|Lock';
COL lock_type FOR A4 HEA 'Lock';
COL lock_mode FOR A4 HEA 'Mode';
COL p1_p2_p3 FOR A100 HEA 'P1, P2, P3';
COL current_object_name FOR A40 HEA 'Current|Object Name (Object Type)' TRUNC;
COL secs_waited FOR 990.000 HEA 'Secs|Waited';
COL spid FOR A6;
COL pname FOR A5;
--
BREAK ON sample_date_time SKIP PAGE ON machine SKIP 1;
--
PRO
PRO
PRO Blockee(s) and Blocker(s) Sessions as of &&snap_time. (&&cs_tools_schema..iod_blocked_session)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WITH
sqlstats AS (
SELECT /*+ MATERIALIZE NO_MERGE */ DISTINCT s.sql_id, s.sql_text FROM v$sqlstats s WHERE ROWNUM >= 1
),
procedures AS (
SELECT DISTINCT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') MATERIALIZE NO_MERGE */ p.con_id, p.object_id, p.subprogram_id, p.owner, p.object_name, p.procedure_name FROM cdb_procedures p WHERE ROWNUM >= 1
),
snapped_sessions AS (
SELECT /*+ MATERIALIZE NO_MERGE */ h.*, c.name AS pdb_name
FROM &&cs_tools_schema..iod_blocked_session h, v$containers c
WHERE 1 = 1
AND (TO_NUMBER('&&cs_con_id.') IN (0, 1, h.con_id) OR h.con_id IN (0, 1))
AND h.snap_time >= TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.snap_time < TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.snap_time = TO_DATE('&&snap_time.', '&&cs_datetime_full_format.')
AND c.con_id(+) = h.con_id
AND ROWNUM >= 1
),
sess AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sid,
MAX(machine) machine
FROM snapped_sessions
WHERE ROWNUM >= 1
GROUP BY
sid
)
SELECT /*+ MONITOR GATHER_PLAN_STATISTICS ORDERED */
TO_CHAR(h.snap_time, '&&cs_datetime_full_format.') AS sample_date_time,
h.machine,
h.con_id,
h.pdb_name,
's:'||h.sid AS sid,
h.blocking_session_status,
CASE WHEN h.sid IN (b.blocking_session, b2.blocking_session) THEN 'DL?' END deadlock,
CASE WHEN h.blocking_session IS NOT NULL THEN 'b:'||h.blocking_session END blocking_session,
CASE WHEN b.blocking_session IS NOT NULL THEN 'b2:'||b.blocking_session END blocking2_session,
CASE WHEN b2.blocking_session IS NOT NULL THEN 'b3:'||b2.blocking_session END blocking3_session,
CASE WHEN b3.blocking_session IS NOT NULL THEN 'b4:'||b3.blocking_session END blocking4_session,
CASE WHEN b4.blocking_session IS NOT NULL THEN 'b5:'||b4.blocking_session END blocking5_session,
CASE
WHEN b4.blocking_session IS NOT NULL THEN (SELECT s.machine FROM sess s WHERE s.sid = b4.blocking_session)
WHEN b3.blocking_session IS NOT NULL THEN (SELECT s.machine FROM sess s WHERE s.sid = b3.blocking_session)
WHEN b2.blocking_session IS NOT NULL THEN (SELECT s.machine FROM sess s WHERE s.sid = b2.blocking_session)
WHEN b.blocking_session IS NOT NULL THEN (SELECT s.machine FROM sess s WHERE s.sid = b.blocking_session)
WHEN h.blocking_session IS NOT NULL THEN (SELECT s.machine FROM sess s WHERE s.sid = h.blocking_session)
END blocking_machine,
h.sql_id,
h.sql_child_number,
h.sql_exec_id,
h.taddr AS xid,
h.wait_class||' - '||h.event on_cpu_or_wait_event,
st.sql_text,
pr.owner||
CASE WHEN pr.object_name IS NOT NULL THEN '.'||pr.object_name END||
CASE WHEN pr.procedure_name IS NOT NULL THEN '.'||pr.procedure_name END
AS procedure_name,
CASE WHEN TRIM(h.module) IS NOT NULL THEN 'm:'||TRIM(h.module)||' ' END||
CASE WHEN TRIM(h.action) IS NOT NULL THEN 'a:'||TRIM(h.action)||' ' END||
CASE WHEN TRIM(h.program) IS NOT NULL THEN 'p:'||TRIM(h.program) END
AS module_action_program,
h.row_wait_obj# current_obj#,
h.row_wait_file# current_file#,
h.row_wait_block# current_block#,
h.row_wait_row# current_row#,
CASE WHEN h.event LIKE 'enq:%' AND h.p1text LIKE 'name|mode%' AND h.p1 > 0 THEN CHR(BITAND(h.p1,-16777216)/16777215)||CHR(BITAND(h.p1, 16711680)/65535) END AS lock_type,
CASE WHEN h.event LIKE 'enq:%' AND h.p1text LIKE 'name|mode%' AND h.p1 > 0 THEN TO_CHAR(BITAND(h.p1, 65535)) END AS lock_mode,
NVL2(TRIM(h.p1text), h.p1text||':'||h.p1, NULL)||NVL2(TRIM(h.p2text), ', '||h.p2text||':'||h.p2, NULL)||NVL2(TRIM(h.p3text), ', '||h.p3text||':'||h.p3, NULL) p1_p2_p3
FROM snapped_sessions h,
snapped_sessions b,
snapped_sessions b2,
snapped_sessions b3,
snapped_sessions b4,
sqlstats st,
procedures pr
WHERE b.sid(+) = h.blocking_session
AND b2.sid(+) = b.blocking_session
AND b3.sid(+) = b2.blocking_session
AND b4.sid(+) = b3.blocking_session
AND st.sql_id(+) = h.sql_id
AND pr.con_id(+) = h.con_id
AND pr.object_id(+) = h.plsql_entry_object_id
AND pr.subprogram_id(+) = h.plsql_entry_subprogram_id
ORDER BY
h.snap_time,
CASE WHEN h.machine LIKE '%iod-%' THEN 1 ELSE 2 END,
h.machine,
h.con_id,
h.sid,
h.serial#,
h.sql_id
/
--
PRO
PRO Note: for furher details on a session, execute at CDB: SELECT * FROM &&cs_tools_schema..iod_blocked_session WHERE snap_time = TO_DATE('&&snap_time.', '&&cs_datetime_full_format.') AND sid = &&double_ampersand.sid.; followed by @pr.sql
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&snap_time."
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

96
csierra/cs_burn_cpu.sql Normal file
View File

@@ -0,0 +1,96 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_burn_cpu.sql
--
-- Purpose: Burn CPU in multiple cores/threads for some time
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter number of CPUs to burn and duration in seconds
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_burn_cpu.sql 36 60
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
PRO
PRO **************
PRO ***
PRO *** Be sure job_queue_processes is set to a large number during the use of this script
PRO ***
PRO **************
PRO
PRO CPUs to burn: [{2}|1-100]
DEF cpus_to_burn = '&1.';
UNDEF 1;
COL cpus_to_burn NEW_V cpus_to_burn NOPRI;
SELECT CASE WHEN TO_NUMBER('&&cpus_to_burn.') BETWEEN 1 AND 100 THEN '&&cpus_to_burn.' WHEN TO_NUMBER('&&cpus_to_burn.') > 100 THEN '100' ELSE '2' END AS cpus_to_burn FROM DUAL;
PRO
PRO Seconds: [{60}|1-3600]
DEF seconds = '&2.';
UNDEF 2;
COL seconds NEW_V seconds NOPRI;
SELECT CASE WHEN TO_NUMBER('&&seconds.') BETWEEN 1 AND 3600 THEN '&&seconds.' WHEN TO_NUMBER('&&seconds.') > 3600 THEN '3600' ELSE '60' END AS seconds FROM DUAL;
--
BEGIN
FOR i IN (SELECT job_name
FROM dba_scheduler_jobs
WHERE job_name LIKE 'CS_BURN_CPU%'
AND state = 'RUNNING')
LOOP
DBMS_SCHEDULER.stop_job(i.job_name);
END LOOP;
--
FOR i IN (SELECT job_name
FROM dba_scheduler_jobs
WHERE job_name LIKE 'CS_BURN_CPU%'
AND state = 'SCHEDULED')
LOOP
DBMS_SCHEDULER.drop_job(i.job_name);
END LOOP;
END;
/
--
DECLARE
w CLOB := q'[
DECLARE -- job_instance
d DATE := SYSDATE + (&&seconds./24/3600);
x NUMBER;
BEGIN
WHILE SYSDATE < d
LOOP
x := DBMS_RANDOM.normal;
END LOOP;
END;
]';
BEGIN
FOR i IN 1 .. &&cpus_to_burn.
LOOP
DBMS_SCHEDULER.create_job (
job_name => 'CS_BURN_CPU_'||LPAD(i, 3, '0'),
job_type => 'PLSQL_BLOCK',
job_action => REPLACE(w, 'job_instance', i),
enabled => TRUE
);
END LOOP;
END;
/
--
PRO wait...
EXEC DBMS_LOCK.sleep(5);
COL job_name FOR A16 TRUNC;
COL last_start_date FOR A36 TRUNC;
SELECT job_name, state, last_start_date,
(CAST(last_start_date AS DATE) + (&&seconds./24/3600) - SYSDATE) * (24*3600) AS secs_to_finish
FROM dba_scheduler_jobs
WHERE job_name LIKE 'CS_BURN_CPU%' ORDER BY job_name;
--
PRO
PRO Use "/" to check on status of these &&cpus_to_burn. CS_BURN_CPU jobs

View File

@@ -0,0 +1,14 @@
SET TERM ON HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
--
COL owner FOR A30;
COL table_name FOR A30;
--
SELECT t.owner, t.table_name, num_rows
FROM dba_users u, dba_tables t
WHERE u.common = 'YES'
AND u.oracle_maintained = 'N'
AND t.owner = u.username
ORDER BY
t.owner, t.table_name
/

914
csierra/cs_cpu_demand.sql Normal file
View File

@@ -0,0 +1,914 @@
----------------------------------------------------------------------------------------
--
-- File name: cpu.sql | cs_cpu_demand.sql
--
-- Purpose: Poor-man's version of ASH Analytics for CPU Demand (ON CPU + Scheduler)
--
-- Author: Carlos Sierra
--
-- Version: 2022/04/01
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_cpu_demand.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_cpu_demand';
DEF cs_script_acronym = 'cpu.sql | ';
--
DEF cs_hours_range_default = '3';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL cs_ash_cut_off_date NEW_V cs_ash_cut_off_date NOPRI;
SELECT TO_CHAR(CAST(PERCENTILE_DISC(0.05) WITHIN GROUP (ORDER BY sample_time) AS DATE) + (1/24), 'YYYY-MM-DD"T"HH24:MI') AS cs_ash_cut_off_date FROM v$active_session_history;
--SELECT TO_CHAR(TRUNC(TRUNC(SYSDATE, 'HH') + FLOOR(TO_NUMBER(TO_CHAR(SYSDATE, 'MI')) / 15) * 15 / (24*60), 'MI'), 'YYYY-MM-DD"T"HH24:MI') AS cs_ash_cut_off_date FROM DUAL;
--
COL cs2_granularity_list NEW_V cs2_granularity_list NOPRI;
COL cs2_default_granularity NEW_V cs2_default_granularity NOPRI;
SELECT CASE
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3660 <= 0.2 AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') < TO_DATE('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI') THEN '[{10s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 12m (up to 72 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3660 <= 0.2 THEN '[{1s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 12m (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 1 AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') < TO_DATE('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI') THEN '[{10s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 1h (up to 360 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 1 THEN '[{5s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 1h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 2 THEN '[{10s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 2h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 3 THEN '[{15s}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 3h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 12 THEN '[{1m}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 12h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 60 THEN '[{5m}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 60h (2.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 180 THEN '[{15m}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 180h (7.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 720 THEN '[{1h}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]' -- < 720h (30d) (up to 720 samples)
ELSE '[{1d}|1s|5s|10s|15s|1m|5m|15m|1h|1d|s|m|h|d]'
END AS cs2_granularity_list,
CASE
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 0.2 AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') < TO_DATE('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI') THEN '10s' -- < 12m (up to 72 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 0.2 THEN '1s' -- < 12m (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 1 AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') < TO_DATE('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI') THEN '10s' -- < 1h (up to 360 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 1 THEN '5s' -- < 1h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 2 THEN '10s' -- < 2h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 3 THEN '15s' -- < 3h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 12 THEN '1m' -- < 12h (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 60 THEN '5m' -- < 60h (2.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 180 THEN '15m' -- < 180h (7.5d) (up to 720 samples)
WHEN TO_NUMBER('&&cs_from_to_seconds.') / 3600 <= 720 THEN '1h' -- < 720h (30d) (up to 720 samples)
ELSE '1d'
END AS cs2_default_granularity
FROM DUAL
/
PRO
PRO 3. Granularity: &&cs2_granularity_list.
DEF cs2_granularity = '&3.';
UNDEF 3;
COL cs2_granularity NEW_V cs2_granularity NOPRI;
SELECT NVL(LOWER(TRIM('&&cs2_granularity.')), '&&cs2_default_granularity.') cs2_granularity FROM DUAL;
SELECT CASE
WHEN '&&cs2_granularity.' = 's' THEN '1s'
WHEN '&&cs2_granularity.' = 'm' THEN '1m'
WHEN '&&cs2_granularity.' = 'h' THEN '1h'
WHEN '&&cs2_granularity.' = 'd' THEN '1d'
WHEN '&&cs2_granularity.' IN ('1s', '5s', '10s', '15s', '1m', '5m', '15m', '1h', '1d') THEN '&&cs2_granularity.'
ELSE '&&cs2_default_granularity.'
END cs2_granularity
FROM DUAL
/
--
COL cs2_fmt NEW_V cs2_fmt NOPRI;
SELECT CASE '&&cs2_granularity.'
WHEN '1s' THEN 'SS' -- (1/24/3600) 1 second
WHEN '5s' THEN 'SS' -- (5/24/3600) 5 seconds
WHEN '10s' THEN 'SS' -- (10/24/3600) 10 seconds
WHEN '15s' THEN 'SS' -- (15/24/3600) 15 seconds
WHEN '1m' THEN 'MI' -- (1/24/60) 1 minute
WHEN '5m' THEN 'MI' -- (5/24/60) 5 minutes
WHEN '15m' THEN 'MI' -- (15/24/60) 15 minutes
WHEN '1h' THEN 'HH' -- (1/24) 1 hour
WHEN '1d' THEN 'DD' -- 1 day
ELSE 'XX' -- error
END cs2_fmt
FROM DUAL
/
--
COL cs2_plus_days NEW_V cs2_plus_days NOPRI;
SELECT CASE '&&cs2_granularity.'
WHEN '1s' THEN '(1/24/3600)' -- (1/24/3600) 1 second
WHEN '5s' THEN '(5/24/3600)' -- (5/24/3600) 5 seconds
WHEN '10s' THEN '(10/24/3600)' -- (10/24/3600) 10 seconds
WHEN '15s' THEN '(15/24/3600)' -- (15/24/3600) 15 seconds
WHEN '1m' THEN '(1/24/60)' -- (1/24/60) 1 minute
WHEN '5m' THEN '(5/24/60)' -- (5/24/60) 5 minutes
WHEN '15m' THEN '(15/24/60)' -- (15/24/60) 15 minutes
WHEN '1h' THEN '(1/24)' -- (1/24) 1 hour
WHEN '1d' THEN '1' -- 1 day
ELSE 'XX' -- error
END cs2_plus_days
FROM DUAL
/
--
COL cs2_samples NEW_V cs2_samples NOPRI;
SELECT TO_CHAR(CEIL((TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') - TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.')) / &&cs2_plus_days.)) AS cs2_samples FROM DUAL
/
--
PRO
PRO 4. Reporting Dimension: [{event}|wait_class|machine|sql_id|plan_hash_value|top_level_sql_id|blocking_session|current_obj#|module|pdb_name|p1|p2|p3]
DEF cs2_dimension = '&4.';
UNDEF 4;
COL cs2_dimension NEW_V cs2_dimension NOPRI;
SELECT NVL(LOWER(TRIM('&&cs2_dimension.')), 'event') cs2_dimension FROM DUAL;
SELECT CASE WHEN '&&cs2_dimension.' IN ('event', 'wait_class', 'machine', 'sql_id', 'plan_hash_value', 'top_level_sql_id', 'blocking_session', 'current_obj#', 'module', 'pdb_name', 'p1', 'p2', 'p3') THEN '&&cs2_dimension.' ELSE 'event' END cs2_dimension FROM DUAL;
--
COL use_oem_colors_series NEW_V use_oem_colors_series NOPRI;
SELECT CASE '&&cs2_dimension.' WHEN 'wait_class' THEN NULL ELSE '//' END AS use_oem_colors_series FROM DUAL;
--
COL cs2_group NEW_V cs2_group NOPRI;
SELECT CASE '&&cs2_dimension.'
WHEN 'wait_class' THEN q'[CASE h.session_state WHEN 'ON CPU' THEN h.session_state ELSE h.wait_class END]'
WHEN 'event' THEN q'[CASE h.session_state WHEN 'ON CPU' THEN h.session_state ELSE h.wait_class||' - '||h.event END]'
WHEN 'machine' THEN q'[h.machine]'
WHEN 'sql_id' THEN q'[h.sql_id]'
WHEN 'plan_hash_value' THEN q'[TO_CHAR(h.sql_plan_hash_value)]'
WHEN 'top_level_sql_id' THEN q'[h.top_level_sql_id]'
-- WHEN 'blocking_session' THEN q'[h.blocking_session||CASE WHEN h.blocking_session IS NOT NULL THEN ','||h.blocking_session_serial# END]' -- 19c: ORA-00979: not a GROUP BY expression
WHEN 'blocking_session' THEN q'[TO_CHAR(h.blocking_session)]'
-- WHEN 'current_obj#' THEN q'[h.current_obj#||CASE WHEN h.current_obj# IS NOT NULL THEN ' ('||h.con_id||')' END]' -- 19c: ORA-00979: not a GROUP BY expression
WHEN 'current_obj#' THEN q'[TO_CHAR(h.current_obj#)]'
WHEN 'module' THEN q'[h.module]'
WHEN 'pdb_name' THEN q'[TO_CHAR(h.con_id)]'
WHEN 'p1' THEN q'[h.p1text||':'||h.p1]'
WHEN 'p2' THEN q'[h.p2text||':'||h.p2]'
WHEN 'p3' THEN q'[h.p3text||':'||h.p3]'
END AS cs2_group
FROM DUAL
/
--
COL aas FOR 999,990.000 HEA 'Average Active|Sessions (AAS)';
COL db_seconds FOR 999,999,990 HEA 'DB Seconds';
BREAK ON REPORT;
COMPUTE SUM OF aas db_seconds ON REPORT;
--
COL machine HEA 'Machine';
--
WITH
ash_awr AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.machine,
10 * COUNT(*) AS db_seconds
FROM dba_hist_active_sess_history h
WHERE h.sample_time <= TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.') + 1
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
GROUP BY
h.machine
),
ash_mem AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.machine,
1 * COUNT(*) AS db_seconds
FROM v$active_session_history h
WHERE h.sample_time > TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
GROUP BY
h.machine
),
ash_all AS (
SELECT machine, db_seconds FROM ash_awr
UNION ALL
SELECT machine, db_seconds FROM ash_mem
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
machine
FROM ash_all
GROUP BY
machine
ORDER BY
1 DESC
FETCH FIRST 30 ROWS ONLY
/
--
PRO
PRO 5. Machine (opt):
DEF cs2_machine = '&5.';
UNDEF 5;
--
PRO
PRO 6. SQL Text piece (e.g.: ScanQuery, getValues, TableName, IndexName):
DEF cs2_sql_text_piece = '&6.';
UNDEF 6;
--
COL sql_text FOR A60 TRUNC;
--
WITH
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_awr AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sql_id,
10 * COUNT(*) AS db_seconds
FROM dba_hist_active_sess_history h
WHERE h.sample_time <= TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.') + 1
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
GROUP BY
h.sql_id
),
ash_mem AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sql_id,
1 * COUNT(*) AS db_seconds
FROM v$active_session_history h
WHERE h.sample_time > TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
GROUP BY
h.sql_id
),
ash_all AS (
SELECT sql_id, db_seconds FROM ash_awr
UNION ALL
SELECT sql_id, db_seconds FROM ash_mem
)
SELECT ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
sql_id,
(SELECT s.sql_text FROM sql_txt s WHERE s.sql_id = a.sql_id AND ROWNUM = 1) AS sql_text
FROM ash_all a
GROUP BY
sql_id
ORDER BY
1 DESC
FETCH FIRST 30 ROWS ONLY
/
--
PRO
PRO 7. SQL_ID (opt):
DEF cs2_sql_id = '&7.';
UNDEF 7;
--
DEF spool_id_chart_footer_script = 'cs_ash_analytics_footer.sql';
COL rn FOR 999;
COL dimension_group FOR A64 TRUNC;
DEF series_01 = ' ';
DEF series_02 = ' ';
DEF series_03 = ' ';
DEF series_04 = ' ';
DEF series_05 = ' ';
DEF series_06 = ' ';
DEF series_07 = ' ';
DEF series_08 = ' ';
DEF series_09 = ' ';
DEF series_10 = ' ';
DEF series_11 = ' ';
DEF series_12 = ' ';
DEF series_13 = ' ';
COL series_01 NEW_V series_01 FOR A64 TRUNC NOPRI;
COL series_02 NEW_V series_02 FOR A64 TRUNC NOPRI;
COL series_03 NEW_V series_03 FOR A64 TRUNC NOPRI;
COL series_04 NEW_V series_04 FOR A64 TRUNC NOPRI;
COL series_05 NEW_V series_05 FOR A64 TRUNC NOPRI;
COL series_06 NEW_V series_06 FOR A64 TRUNC NOPRI;
COL series_07 NEW_V series_07 FOR A64 TRUNC NOPRI;
COL series_08 NEW_V series_08 FOR A64 TRUNC NOPRI;
COL series_09 NEW_V series_09 FOR A64 TRUNC NOPRI;
COL series_10 NEW_V series_10 FOR A64 TRUNC NOPRI;
COL series_11 NEW_V series_11 FOR A64 TRUNC NOPRI;
COL series_12 NEW_V series_12 FOR A64 TRUNC NOPRI;
COL series_13 NEW_V series_13 FOR A64 TRUNC NOPRI;
DEF aas_01 = ' ';
DEF aas_02 = ' ';
DEF aas_03 = ' ';
DEF aas_04 = ' ';
DEF aas_05 = ' ';
DEF aas_06 = ' ';
DEF aas_07 = ' ';
DEF aas_08 = ' ';
DEF aas_09 = ' ';
DEF aas_10 = ' ';
DEF aas_11 = ' ';
DEF aas_12 = ' ';
DEF aas_13 = ' ';
COL aas_01 NEW_V aas_01 FOR A9 TRUNC NOPRI;
COL aas_02 NEW_V aas_02 FOR A9 TRUNC NOPRI;
COL aas_03 NEW_V aas_03 FOR A9 TRUNC NOPRI;
COL aas_04 NEW_V aas_04 FOR A9 TRUNC NOPRI;
COL aas_05 NEW_V aas_05 FOR A9 TRUNC NOPRI;
COL aas_06 NEW_V aas_06 FOR A9 TRUNC NOPRI;
COL aas_07 NEW_V aas_07 FOR A9 TRUNC NOPRI;
COL aas_08 NEW_V aas_08 FOR A9 TRUNC NOPRI;
COL aas_09 NEW_V aas_09 FOR A9 TRUNC NOPRI;
COL aas_10 NEW_V aas_10 FOR A9 TRUNC NOPRI;
COL aas_11 NEW_V aas_11 FOR A9 TRUNC NOPRI;
COL aas_12 NEW_V aas_12 FOR A9 TRUNC NOPRI;
COL aas_13 NEW_V aas_13 FOR A9 TRUNC NOPRI;
--
WITH
FUNCTION get_sql_text (p_sql_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_sql_text VARCHAR2(4000);
BEGIN
SELECT MAX(REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM v$sql
WHERE sql_id = p_sql_id
AND ROWNUM = 1;
--
IF l_sql_text IS NOT NULL THEN
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END IF;
--
SELECT MAX(REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM dba_hist_sqltext
WHERE sql_id = p_sql_id
AND dbid = &&cs_dbid.
AND ROWNUM = 1;
--
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END get_sql_text;
--
FUNCTION get_pdb_name (p_con_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_pdb_name VARCHAR2(4000);
BEGIN
SELECT name
INTO l_pdb_name
FROM v$containers
WHERE con_id = TO_NUMBER(p_con_id);
--
RETURN l_pdb_name;
END get_pdb_name;
--
wait_classes AS (
SELECT 1 AS rn, 'ON CPU' AS dimension_group FROM DUAL
UNION SELECT 2 AS rn, 'User I/O' AS dimension_group FROM DUAL
UNION SELECT 3 AS rn, 'System I/O' AS dimension_group FROM DUAL
UNION SELECT 4 AS rn, 'Cluster' AS dimension_group FROM DUAL
UNION SELECT 5 AS rn, 'Commit' AS dimension_group FROM DUAL
UNION SELECT 6 AS rn, 'Concurrency' AS dimension_group FROM DUAL
UNION SELECT 7 AS rn, 'Application' AS dimension_group FROM DUAL
UNION SELECT 8 AS rn, 'Administrative' AS dimension_group FROM DUAL
UNION SELECT 9 AS rn, 'Configuration' AS dimension_group FROM DUAL
UNION SELECT 10 AS rn, 'Network' AS dimension_group FROM DUAL
UNION SELECT 11 AS rn, 'Queueing' AS dimension_group FROM DUAL
UNION SELECT 12 AS rn, 'Scheduler' AS dimension_group FROM DUAL
UNION SELECT 13 AS rn, 'Other' AS dimension_group FROM DUAL
),
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_awr AS (
SELECT /*+ MATERIALIZE NO_MERGE */
&&cs2_group. AS dimension_group,
10 * COUNT(*) AS db_seconds
FROM dba_hist_active_sess_history h
WHERE h.sample_time <= TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.') + 1
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
GROUP BY
&&cs2_group.
),
ash_mem AS (
SELECT /*+ MATERIALIZE NO_MERGE */
&&cs2_group. AS dimension_group,
1 * COUNT(*) AS db_seconds
FROM v$active_session_history h
WHERE h.sample_time > TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
GROUP BY
&&cs2_group.
),
ash_all AS (
SELECT dimension_group, db_seconds FROM ash_awr
UNION ALL
SELECT dimension_group, db_seconds FROM ash_mem
),
ash_by_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
ROUND(SUM(db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(db_seconds) AS db_seconds,
dimension_group,
ROW_NUMBER() OVER(ORDER BY SUM(db_seconds) DESC) AS rn
FROM ash_all a
GROUP BY
dimension_group
),
top AS (
SELECT /*+ MATERIALIZE NO_MERGE */
rn, -- up to 12
aas,
db_seconds,
SUBSTR(CASE
WHEN TRIM(dimension_group) IS NULL /*OR TRIM(dimension_group) = ','*/ THEN '"null"'
WHEN '&&cs2_dimension.' IN ('sql_id', 'top_level_sql_id') THEN dimension_group||' '||get_sql_text(dimension_group)
WHEN '&&cs2_dimension.' = 'pdb_name' THEN dimension_group||' '||get_pdb_name(dimension_group)
ELSE dimension_group
END, 1, 64) AS dimension_group
FROM ash_by_dim
WHERE rn < (SELECT MAX(rn) FROM wait_classes) -- 13
),
max_top AS (
SELECT /*+ MATERIALIZE NO_MERGE */ MAX(rn) AS max_rn FROM top
),
bottom AS (
SELECT /*+ MATERIALIZE NO_MERGE */
(1 + max_top.max_rn) AS bottom_rn, -- up to 13
ROUND(SUM(a.db_seconds) / TO_NUMBER('&&cs_from_to_seconds.'), 3) AS aas,
SUM(a.db_seconds) AS db_seconds,
'"all others"' AS dimension_group
FROM ash_by_dim a, max_top
WHERE a.rn >= max_top.max_rn
GROUP BY
max_top.max_rn
),
wait_classes2 AS (
SELECT /*+ MATERIALIZE NO_MERGE */
w.rn,
NVL(t.aas, 0) AS aas,
NVL(t.db_seconds, 0) AS db_seconds,
w.dimension_group
FROM wait_classes w,
top t
WHERE '&&cs2_dimension.' = 'wait_class'
AND t.dimension_group(+) = w.dimension_group
),
top_and_bottom AS (
SELECT rn, aas, db_seconds, dimension_group
FROM top
WHERE '&&cs2_dimension.' <> 'wait_class'
UNION ALL
SELECT rn, aas, db_seconds, dimension_group
FROM wait_classes2
WHERE '&&cs2_dimension.' = 'wait_class'
UNION ALL
SELECT bottom_rn AS rn, aas, db_seconds, dimension_group
FROM bottom
WHERE '&&cs2_dimension.' <> 'wait_class'
),
list AS (
SELECT /*+ MATERIALIZE NO_MERGE */
rn, LPAD(TRIM(TO_CHAR(ROUND(aas, 3), '9,990.000')), 9) AS aas, db_seconds, dimension_group
FROM top_and_bottom
)
SELECT rn, aas, db_seconds, dimension_group,
COALESCE((SELECT dimension_group FROM list WHERE rn = 1), ' ') AS series_01,
COALESCE((SELECT dimension_group FROM list WHERE rn = 2), ' ') AS series_02,
COALESCE((SELECT dimension_group FROM list WHERE rn = 3), ' ') AS series_03,
COALESCE((SELECT dimension_group FROM list WHERE rn = 4), ' ') AS series_04,
COALESCE((SELECT dimension_group FROM list WHERE rn = 5), ' ') AS series_05,
COALESCE((SELECT dimension_group FROM list WHERE rn = 6), ' ') AS series_06,
COALESCE((SELECT dimension_group FROM list WHERE rn = 7), ' ') AS series_07,
COALESCE((SELECT dimension_group FROM list WHERE rn = 8), ' ') AS series_08,
COALESCE((SELECT dimension_group FROM list WHERE rn = 9), ' ') AS series_09,
COALESCE((SELECT dimension_group FROM list WHERE rn = 10), ' ') AS series_10,
COALESCE((SELECT dimension_group FROM list WHERE rn = 11), ' ') AS series_11,
COALESCE((SELECT dimension_group FROM list WHERE rn = 12), ' ') AS series_12,
COALESCE((SELECT dimension_group FROM list WHERE rn = 13), ' ') AS series_13,
(SELECT aas FROM list WHERE rn = 1) AS aas_01,
(SELECT aas FROM list WHERE rn = 2) AS aas_02,
(SELECT aas FROM list WHERE rn = 3) AS aas_03,
(SELECT aas FROM list WHERE rn = 4) AS aas_04,
(SELECT aas FROM list WHERE rn = 5) AS aas_05,
(SELECT aas FROM list WHERE rn = 6) AS aas_06,
(SELECT aas FROM list WHERE rn = 7) AS aas_07,
(SELECT aas FROM list WHERE rn = 8) AS aas_08,
(SELECT aas FROM list WHERE rn = 9) AS aas_09,
(SELECT aas FROM list WHERE rn = 10) AS aas_10,
(SELECT aas FROM list WHERE rn = 11) AS aas_11,
(SELECT aas FROM list WHERE rn = 12) AS aas_12,
(SELECT aas FROM list WHERE rn = 13) AS aas_13
FROM list
ORDER BY
rn
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = 'Average Active Sessions ON CPU and Scheduler between &&cs_sample_time_from. and &&cs_sample_time_to. UTC';
DEF chart_title = '&&report_title.';
DEF vaxis_title = 'Average Active Sessions (AAS)';
DEF xaxis_title = '';
--
COL xaxis_title NEW_V xaxis_title NOPRI;
SELECT
'RGN:"&&cs_rgn." '||
CASE WHEN '&&cs_con_name.' = 'CDB$ROOT' THEN UPPER('CDB:"&&cs_db_name." ') ELSE 'PDB:"&&cs_con_name." ' END||
CASE WHEN '&&cs2_machine.' IS NOT NULL THEN 'Machine:"%&&cs2_machine.%" ' END||
CASE WHEN '&&cs2_sql_text_piece.' IS NOT NULL THEN 'Text:"%&&cs2_sql_text_piece.%" ' END||
CASE WHEN '&&cs2_sql_id.' IS NOT NULL THEN 'SQL_ID:"&&cs2_sql_id." ' END AS xaxis_title
FROM DUAL;
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
--DEF is_stacked = "isStacked: false,";
DEF is_stacked = "isStacked: true,";
--DEF vaxis_baseline = ", baseline:&&cs_num_cpu_cores., baselineColor:'red'";
DEF vaxis_baseline = "";
--DEF chart_foot_note_2 = "<br>2)";
DEF chart_foot_note_2 = '<br>2) &&xaxis_title.';
DEF chart_foot_note_3 = "<br>";
DEF chart_foot_note_4 = "";
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_granularity." "&&cs2_dimension." "&&cs2_machine." "&&cs2_sql_text_piece." "&&cs2_sql_id."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&series_01.', id:'01', type:'number'}
PRO ,{label:'&&series_02.', id:'02', type:'number'}
PRO ,{label:'&&series_03.', id:'03', type:'number'}
PRO ,{label:'&&series_04.', id:'04', type:'number'}
PRO ,{label:'&&series_05.', id:'05', type:'number'}
PRO ,{label:'&&series_06.', id:'06', type:'number'}
PRO ,{label:'&&series_07.', id:'07', type:'number'}
PRO ,{label:'&&series_08.', id:'08', type:'number'}
PRO ,{label:'&&series_09.', id:'09', type:'number'}
PRO ,{label:'&&series_10.', id:'10', type:'number'}
PRO ,{label:'&&series_11.', id:'11', type:'number'}
PRO ,{label:'&&series_12.', id:'12', type:'number'}
PRO ,{label:'&&series_13.', id:'13', type:'number'}
PRO ]
SET HEA OFF PAGES 0;
/****************************************************************************************/
WITH
FUNCTION num_format (p_number IN NUMBER, p_round IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
BEGIN
IF p_number IS NULL OR ROUND(p_number, p_round) <= 0 THEN
RETURN 'null';
ELSE
RETURN TO_CHAR(ROUND(p_number, p_round));
END IF;
END num_format;
/****************************************************************************************/
FUNCTION ceil_timestamp (p_timestamp IN TIMESTAMP)
RETURN DATE
IS
BEGIN
IF '&&cs2_granularity.' = '1s' THEN
RETURN CAST(p_timestamp AS DATE);
ELSIF '&&cs2_granularity.' = '5s' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'MI') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 5) * 5 / (24 * 60 * 60) + &&cs2_plus_days.;
ELSIF '&&cs2_granularity.' = '10s' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'MI') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 10) * 10 / (24 * 60 * 60) + &&cs2_plus_days.;
ELSIF '&&cs2_granularity.' = '15s' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'MI') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 15) * 15 / (24 * 60 * 60) + &&cs2_plus_days.;
ELSIF '&&cs2_granularity.' = '5m' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'HH') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 5) * 5 / (24 * 60) + &&cs2_plus_days.;
ELSIF '&&cs2_granularity.' = '15m' THEN
RETURN TRUNC(CAST(p_timestamp AS DATE), 'HH') + FLOOR(TO_NUMBER(TO_CHAR(CAST(p_timestamp AS DATE), '&&cs2_fmt.')) / 15) * 15 / (24 * 60) + &&cs2_plus_days.;
ELSE -- 1s, 1m, 1h, 1d
RETURN TRUNC(CAST(p_timestamp AS DATE) + &&cs2_plus_days., '&&cs2_fmt.');
END IF;
END ceil_timestamp;
/****************************************************************************************/
FUNCTION get_sql_text (p_sql_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_sql_text VARCHAR2(4000);
BEGIN
SELECT MAX(REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM v$sql
WHERE sql_id = p_sql_id
AND ROWNUM = 1;
--
IF l_sql_text IS NOT NULL THEN
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END IF;
--
SELECT MAX(REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32))) AS sql_text
INTO l_sql_text
FROM dba_hist_sqltext
WHERE sql_id = p_sql_id
AND dbid = &&cs_dbid.
AND ROWNUM = 1;
--
RETURN REPLACE(REPLACE(l_sql_text, ':'), '''');
END get_sql_text;
/****************************************************************************************/
FUNCTION get_pdb_name (p_con_id IN VARCHAR2)
RETURN VARCHAR2
IS
l_pdb_name VARCHAR2(4000);
BEGIN
SELECT name
INTO l_pdb_name
FROM v$containers
WHERE con_id = TO_NUMBER(p_con_id);
--
RETURN l_pdb_name;
END get_pdb_name;
/****************************************************************************************/
sample AS (
SELECT ceil_timestamp(TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') + ((LEVEL - 1) * &&cs2_plus_days.)) AS time FROM DUAL CONNECT BY LEVEL <= TO_NUMBER('&&cs2_samples.')
),
wait_classes AS (
SELECT 1 AS rn, 'ON CPU' AS dimension_group FROM DUAL
UNION SELECT 2 AS rn, 'User I/O' AS dimension_group FROM DUAL
UNION SELECT 3 AS rn, 'System I/O' AS dimension_group FROM DUAL
UNION SELECT 4 AS rn, 'Cluster' AS dimension_group FROM DUAL
UNION SELECT 5 AS rn, 'Commit' AS dimension_group FROM DUAL
UNION SELECT 6 AS rn, 'Concurrency' AS dimension_group FROM DUAL
UNION SELECT 7 AS rn, 'Application' AS dimension_group FROM DUAL
UNION SELECT 8 AS rn, 'Administrative' AS dimension_group FROM DUAL
UNION SELECT 9 AS rn, 'Configuration' AS dimension_group FROM DUAL
UNION SELECT 10 AS rn, 'Network' AS dimension_group FROM DUAL
UNION SELECT 11 AS rn, 'Queueing' AS dimension_group FROM DUAL
UNION SELECT 12 AS rn, 'Scheduler' AS dimension_group FROM DUAL
UNION SELECT 13 AS rn, 'Other' AS dimension_group FROM DUAL
),
sql_txt AS (
SELECT /*+ MATERIALIZE NO_MERGE */ sql_id, MAX(sql_text) AS sql_text
FROM (
SELECT sql_id, REPLACE(REPLACE(SUBSTR(sql_text, 1, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM v$sql
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(sql_text) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND ROWNUM >= 1
UNION ALL
SELECT sql_id, REPLACE(REPLACE(DBMS_LOB.substr(sql_text, 100), CHR(10), CHR(32)), CHR(9), CHR(32)) AS sql_text
FROM dba_hist_sqltext
WHERE '&&cs2_sql_text_piece.' IS NOT NULL
AND UPPER(DBMS_LOB.substr(sql_text, 100)) LIKE CHR(37)||UPPER('&&cs2_sql_text_piece.')||CHR(37)
AND dbid = &&cs_dbid.
AND ROWNUM >= 1
)
GROUP BY sql_id
),
ash_awr AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
CASE
WHEN TRIM(&&cs2_group.) IS NULL THEN '"null"'
WHEN '&&cs2_dimension.' IN ('sql_id', 'top_level_sql_id', 'pdb_name') THEN
CASE
WHEN &&cs2_group. = SUBSTR(q'[&&series_01.]', 1, INSTR(q'[&&series_01.]', ' ') - 1) THEN q'[&&series_01.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_02.]', 1, INSTR(q'[&&series_02.]', ' ') - 1) THEN q'[&&series_02.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_03.]', 1, INSTR(q'[&&series_03.]', ' ') - 1) THEN q'[&&series_03.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_04.]', 1, INSTR(q'[&&series_04.]', ' ') - 1) THEN q'[&&series_04.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_05.]', 1, INSTR(q'[&&series_05.]', ' ') - 1) THEN q'[&&series_05.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_06.]', 1, INSTR(q'[&&series_06.]', ' ') - 1) THEN q'[&&series_06.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_07.]', 1, INSTR(q'[&&series_07.]', ' ') - 1) THEN q'[&&series_07.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_08.]', 1, INSTR(q'[&&series_08.]', ' ') - 1) THEN q'[&&series_08.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_09.]', 1, INSTR(q'[&&series_09.]', ' ') - 1) THEN q'[&&series_09.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_10.]', 1, INSTR(q'[&&series_10.]', ' ') - 1) THEN q'[&&series_10.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_11.]', 1, INSTR(q'[&&series_11.]', ' ') - 1) THEN q'[&&series_11.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_12.]', 1, INSTR(q'[&&series_12.]', ' ') - 1) THEN q'[&&series_12.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_13.]', 1, INSTR(q'[&&series_13.]', ' ') - 1) THEN q'[&&series_13.]'
ELSE '"all others"' END
WHEN '&&cs2_dimension.' IN ('wait_class', 'event', 'machine', 'plan_hash_value', 'blocking_session', 'current_obj#', 'module', 'p1', 'p2', 'p3') THEN
CASE
WHEN &&cs2_group. = q'[&&series_01.]' THEN q'[&&series_01.]'
WHEN &&cs2_group. = q'[&&series_02.]' THEN q'[&&series_02.]'
WHEN &&cs2_group. = q'[&&series_03.]' THEN q'[&&series_03.]'
WHEN &&cs2_group. = q'[&&series_04.]' THEN q'[&&series_04.]'
WHEN &&cs2_group. = q'[&&series_05.]' THEN q'[&&series_05.]'
WHEN &&cs2_group. = q'[&&series_06.]' THEN q'[&&series_06.]'
WHEN &&cs2_group. = q'[&&series_07.]' THEN q'[&&series_07.]'
WHEN &&cs2_group. = q'[&&series_08.]' THEN q'[&&series_08.]'
WHEN &&cs2_group. = q'[&&series_09.]' THEN q'[&&series_09.]'
WHEN &&cs2_group. = q'[&&series_10.]' THEN q'[&&series_10.]'
WHEN &&cs2_group. = q'[&&series_11.]' THEN q'[&&series_11.]'
WHEN &&cs2_group. = q'[&&series_12.]' THEN q'[&&series_12.]'
WHEN &&cs2_group. = q'[&&series_13.]' THEN q'[&&series_13.]'
ELSE '"all others"' END
ELSE '"all others"' END AS dimension_group
FROM dba_hist_active_sess_history h
WHERE h.sample_time <= TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.') + 1
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
),
ash_mem AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
CASE
WHEN TRIM(&&cs2_group.) IS NULL THEN '"null"'
WHEN '&&cs2_dimension.' IN ('sql_id', 'top_level_sql_id', 'pdb_name') THEN
CASE
WHEN &&cs2_group. = SUBSTR(q'[&&series_01.]', 1, INSTR(q'[&&series_01.]', ' ') - 1) THEN q'[&&series_01.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_02.]', 1, INSTR(q'[&&series_02.]', ' ') - 1) THEN q'[&&series_02.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_03.]', 1, INSTR(q'[&&series_03.]', ' ') - 1) THEN q'[&&series_03.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_04.]', 1, INSTR(q'[&&series_04.]', ' ') - 1) THEN q'[&&series_04.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_05.]', 1, INSTR(q'[&&series_05.]', ' ') - 1) THEN q'[&&series_05.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_06.]', 1, INSTR(q'[&&series_06.]', ' ') - 1) THEN q'[&&series_06.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_07.]', 1, INSTR(q'[&&series_07.]', ' ') - 1) THEN q'[&&series_07.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_08.]', 1, INSTR(q'[&&series_08.]', ' ') - 1) THEN q'[&&series_08.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_09.]', 1, INSTR(q'[&&series_09.]', ' ') - 1) THEN q'[&&series_09.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_10.]', 1, INSTR(q'[&&series_10.]', ' ') - 1) THEN q'[&&series_10.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_11.]', 1, INSTR(q'[&&series_11.]', ' ') - 1) THEN q'[&&series_11.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_12.]', 1, INSTR(q'[&&series_12.]', ' ') - 1) THEN q'[&&series_12.]'
WHEN &&cs2_group. = SUBSTR(q'[&&series_13.]', 1, INSTR(q'[&&series_13.]', ' ') - 1) THEN q'[&&series_13.]'
ELSE '"all others"' END
WHEN '&&cs2_dimension.' IN ('wait_class', 'event', 'machine', 'plan_hash_value', 'blocking_session', 'current_obj#', 'module', 'p1', 'p2', 'p3') THEN
CASE
WHEN &&cs2_group. = q'[&&series_01.]' THEN q'[&&series_01.]'
WHEN &&cs2_group. = q'[&&series_02.]' THEN q'[&&series_02.]'
WHEN &&cs2_group. = q'[&&series_03.]' THEN q'[&&series_03.]'
WHEN &&cs2_group. = q'[&&series_04.]' THEN q'[&&series_04.]'
WHEN &&cs2_group. = q'[&&series_05.]' THEN q'[&&series_05.]'
WHEN &&cs2_group. = q'[&&series_06.]' THEN q'[&&series_06.]'
WHEN &&cs2_group. = q'[&&series_07.]' THEN q'[&&series_07.]'
WHEN &&cs2_group. = q'[&&series_08.]' THEN q'[&&series_08.]'
WHEN &&cs2_group. = q'[&&series_09.]' THEN q'[&&series_09.]'
WHEN &&cs2_group. = q'[&&series_10.]' THEN q'[&&series_10.]'
WHEN &&cs2_group. = q'[&&series_11.]' THEN q'[&&series_11.]'
WHEN &&cs2_group. = q'[&&series_12.]' THEN q'[&&series_12.]'
WHEN &&cs2_group. = q'[&&series_13.]' THEN q'[&&series_13.]'
ELSE '"all others"' END
ELSE '"all others"' END AS dimension_group
FROM v$active_session_history h
WHERE h.sample_time > TO_TIMESTAMP('&&cs_ash_cut_off_date.', 'YYYY-MM-DD"T"HH24:MI')
AND h.sample_time >= TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND h.sample_time < TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND (h.session_state = 'ON CPU' OR h.wait_class = 'Scheduler')
AND ('&&cs2_machine.' IS NULL OR h.machine LIKE CHR(37)||'&&cs2_machine.'||CHR(37))
AND ('&&cs2_sql_text_piece.' IS NULL OR h.sql_id IN (SELECT t.sql_id FROM sql_txt t))
AND ('&&cs2_sql_id.' IS NULL OR h.sql_id = '&&cs2_sql_id.')
),
ash_awr_denorm AS (
SELECT /*+ MATERIALIZE NO_MERGE */
ceil_timestamp(h.sample_time) AS time,
--ROUND(24 * 3600 * (MAX(CAST(h.sample_time AS DATE)) - MIN(CAST(h.sample_time AS DATE))) + 10) AS interval_secs,
SUM(CASE WHEN h.dimension_group = q'[&&series_01.]' THEN 10 ELSE 0 END) AS db_secs_01,
SUM(CASE WHEN h.dimension_group = q'[&&series_02.]' THEN 10 ELSE 0 END) AS db_secs_02,
SUM(CASE WHEN h.dimension_group = q'[&&series_03.]' THEN 10 ELSE 0 END) AS db_secs_03,
SUM(CASE WHEN h.dimension_group = q'[&&series_04.]' THEN 10 ELSE 0 END) AS db_secs_04,
SUM(CASE WHEN h.dimension_group = q'[&&series_05.]' THEN 10 ELSE 0 END) AS db_secs_05,
SUM(CASE WHEN h.dimension_group = q'[&&series_06.]' THEN 10 ELSE 0 END) AS db_secs_06,
SUM(CASE WHEN h.dimension_group = q'[&&series_07.]' THEN 10 ELSE 0 END) AS db_secs_07,
SUM(CASE WHEN h.dimension_group = q'[&&series_08.]' THEN 10 ELSE 0 END) AS db_secs_08,
SUM(CASE WHEN h.dimension_group = q'[&&series_09.]' THEN 10 ELSE 0 END) AS db_secs_09,
SUM(CASE WHEN h.dimension_group = q'[&&series_10.]' THEN 10 ELSE 0 END) AS db_secs_10,
SUM(CASE WHEN h.dimension_group = q'[&&series_11.]' THEN 10 ELSE 0 END) AS db_secs_11,
SUM(CASE WHEN h.dimension_group = q'[&&series_12.]' THEN 10 ELSE 0 END) AS db_secs_12,
SUM(CASE WHEN h.dimension_group = q'[&&series_13.]' THEN 10 ELSE 0 END) AS db_secs_13
FROM ash_awr h
GROUP BY
ceil_timestamp(h.sample_time)
),
ash_mem_denorm AS (
SELECT /*+ MATERIALIZE NO_MERGE */
ceil_timestamp(h.sample_time) AS time,
--ROUND(24 * 3600 * (MAX(CAST(h.sample_time AS DATE)) - MIN(CAST(h.sample_time AS DATE))) + 1) AS interval_secs,
SUM(CASE WHEN h.dimension_group = q'[&&series_01.]' THEN 01 ELSE 0 END) AS db_secs_01,
SUM(CASE WHEN h.dimension_group = q'[&&series_02.]' THEN 01 ELSE 0 END) AS db_secs_02,
SUM(CASE WHEN h.dimension_group = q'[&&series_03.]' THEN 01 ELSE 0 END) AS db_secs_03,
SUM(CASE WHEN h.dimension_group = q'[&&series_04.]' THEN 01 ELSE 0 END) AS db_secs_04,
SUM(CASE WHEN h.dimension_group = q'[&&series_05.]' THEN 01 ELSE 0 END) AS db_secs_05,
SUM(CASE WHEN h.dimension_group = q'[&&series_06.]' THEN 01 ELSE 0 END) AS db_secs_06,
SUM(CASE WHEN h.dimension_group = q'[&&series_07.]' THEN 01 ELSE 0 END) AS db_secs_07,
SUM(CASE WHEN h.dimension_group = q'[&&series_08.]' THEN 01 ELSE 0 END) AS db_secs_08,
SUM(CASE WHEN h.dimension_group = q'[&&series_09.]' THEN 01 ELSE 0 END) AS db_secs_09,
SUM(CASE WHEN h.dimension_group = q'[&&series_10.]' THEN 01 ELSE 0 END) AS db_secs_10,
SUM(CASE WHEN h.dimension_group = q'[&&series_11.]' THEN 01 ELSE 0 END) AS db_secs_11,
SUM(CASE WHEN h.dimension_group = q'[&&series_12.]' THEN 01 ELSE 0 END) AS db_secs_12,
SUM(CASE WHEN h.dimension_group = q'[&&series_13.]' THEN 01 ELSE 0 END) AS db_secs_13
FROM ash_mem h
GROUP BY
ceil_timestamp(h.sample_time)
),
ash_denorm AS (
SELECT time, (time - LAG(time, 1, time) OVER (ORDER BY time)) * 24 * 3600 AS interval_secs, db_secs_01, db_secs_02, db_secs_03, db_secs_04, db_secs_05, db_secs_06, db_secs_07, db_secs_08, db_secs_09, db_secs_10, db_secs_11, db_secs_12, db_secs_13 FROM ash_awr_denorm
UNION ALL
SELECT time, (time - LAG(time, 1, time) OVER (ORDER BY time)) * 24 * 3600 AS interval_secs, db_secs_01, db_secs_02, db_secs_03, db_secs_04, db_secs_05, db_secs_06, db_secs_07, db_secs_08, db_secs_09, db_secs_10, db_secs_11, db_secs_12, db_secs_13 FROM ash_mem_denorm
),
/****************************************************************************************/
my_query AS (
SELECT s.time, a.interval_secs, a.db_secs_01, a.db_secs_02, a.db_secs_03, a.db_secs_04, a.db_secs_05, a.db_secs_06, a.db_secs_07, a.db_secs_08, a.db_secs_09, a.db_secs_10, a.db_secs_11, a.db_secs_12, a.db_secs_13,
ROW_NUMBER() OVER (ORDER BY s.time ASC NULLS LAST) AS rn_asc,
ROW_NUMBER() OVER (ORDER BY s.time DESC NULLS LAST) AS rn_desc
FROM ash_denorm a,
sample s
WHERE a.interval_secs > 0
AND a.time(+) = s.time
)
SELECT ', [new Date('||
TO_CHAR(q.time, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(q.time, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(q.time, 'DD')|| /* day */
','||TO_CHAR(q.time, 'HH24')|| /* hour */
','||TO_CHAR(q.time, 'MI')|| /* minute */
','||TO_CHAR(q.time, 'SS')|| /* second */
')'||
','||num_format(q.db_secs_01 / q.interval_secs, 3)||
','||num_format(q.db_secs_02 / q.interval_secs, 3)||
','||num_format(q.db_secs_03 / q.interval_secs, 3)||
','||num_format(q.db_secs_04 / q.interval_secs, 3)||
','||num_format(q.db_secs_05 / q.interval_secs, 3)||
','||num_format(q.db_secs_06 / q.interval_secs, 3)||
','||num_format(q.db_secs_07 / q.interval_secs, 3)||
','||num_format(q.db_secs_08 / q.interval_secs, 3)||
','||num_format(q.db_secs_09 / q.interval_secs, 3)||
','||num_format(q.db_secs_10 / q.interval_secs, 3)||
','||num_format(q.db_secs_11 / q.interval_secs, 3)||
','||num_format(q.db_secs_12 / q.interval_secs, 3)||
','||num_format(q.db_secs_13 / q.interval_secs, 3)||
']'
FROM my_query q
WHERE 1 = 1
-- AND q.rn_asc > 1 AND q.rn_desc > 1
AND q.db_secs_01 + q.db_secs_02 + q.db_secs_03 + q.db_secs_04 + q.db_secs_05 + q.db_secs_06 + q.db_secs_07 + q.db_secs_08 + q.db_secs_09 + q.db_secs_10 + q.db_secs_11 + q.db_secs_12 + q.db_secs_13 > 0
ORDER BY
q.time
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'SteppedArea';
-- disable explorer with "//" when using Pie
DEF cs_chart_option_explorer = '';
-- enable pie options with "" when using Pie
DEF cs_chart_option_pie = '//';
-- use oem colors
DEF cs_oem_colors_series = '&&use_oem_colors_series.';
DEF cs_oem_colors_slices = '//';
-- for line charts
DEF cs_curve_type = '//';
--
@@cs_internal/cs_spool_id_chart.sql
@@cs_internal/cs_spool_tail_chart.sql
PRO
PRO &&report_foot_note.
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,2 @@
-- cs_cpu_sysmetric_for_cdb_hist_chart.sql - CPU System Metrics as per DBA_HIST_SYSMETRIC_SUMMARY View for a CDB (time series chart)
@@cs_some_sysmetric_for_cdb_hist_chart.sql "" "" "CentiSeconds Per Second" "Database Time Per Sec" "Host CPU Usage Per Sec" "Background CPU Usage Per Sec" "CPU Usage Per Sec" "" "" "average" "Scatter" "none"

View File

@@ -0,0 +1,2 @@
-- cs_cpu_sysmetric_for_cdb_mem_chart.sql - CPU System Metrics as per V$SYSMETRIC_HISTORY View for a CDB (time series chart)
@@cs_some_sysmetric_for_cdb_mem_chart.sql "CentiSeconds Per Second" "Database Time Per Sec" "Host CPU Usage Per Sec" "Background CPU Usage Per Sec" "CPU Usage Per Sec" "" "" "Scatter"

View File

@@ -0,0 +1,2 @@
-- cs_cpu_sysmetric_for_pdb_hist_chart.sql - CPU System Metrics as per DBA_HIST_CON_SYSMETRIC_SUMM View for a PDB (time series chart)
@@cs_some_sysmetric_for_pdb_hist_chart.sql "" "" "CentiSeconds Per Second" "CPU Usage Per Sec" "" "" "" "" "" "average" "Scatter" "none"

View File

@@ -0,0 +1,2 @@
-- cs_cpu_sysmetric_for_pdb_mem_chart.sql - CPU System Metrics as per V$CON_SYSMETRIC_HISTORY View for a PDB (time series chart)
@@cs_some_sysmetric_for_pdb_mem_chart.sql "CentiSeconds Per Second" "CPU Usage Per Sec" "" "" "" "" "" "Scatter"

View File

@@ -0,0 +1,157 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dba_hist_parameter.sql
--
-- Purpose: System Parameters History
--
-- Author: Carlos Sierra
--
-- Version: 2021/12/06
--
-- Usage: Execute connected to CDB or PDB
--
-- Enter range of dates and filters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dba_hist_parameter.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_dba_hist_parameter';
DEF cs_hours_range_default = '1440';
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
COL parameter_name FOR A43;
COL dist_values FOR 999,990;
--
SELECT h.parameter_name, COUNT(DISTINCT h.value) AS dist_values
FROM dba_hist_parameter h
WHERE h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') - 1 AND TO_NUMBER('&&cs_snap_id_to.')
AND &&cs_con_id. IN (1, h.con_id)
GROUP BY
h.parameter_name
HAVING COUNT(DISTINCT h.value) > 1
ORDER BY
h.parameter_name
/
PRO
PRO 3. Parameter Name (opt):
DEF parameter_name = '&3.';
UNDEF 3;
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&parameter_name."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
PRO PARAMETER : "&&parameter_name."
--
PRO
PRO PARAMETERS CHANGED
PRO ~~~~~~~~~~~~~~~~~~
SELECT h.parameter_name, COUNT(DISTINCT h.value) AS dist_values
FROM dba_hist_parameter h
WHERE h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') - 1 AND TO_NUMBER('&&cs_snap_id_to.')
AND &&cs_con_id. IN (1, h.con_id)
GROUP BY
h.parameter_name
HAVING COUNT(DISTINCT h.value) > 1
ORDER BY
h.parameter_name
/
COL begin_time FOR A19;
COL end_time FOR A19;
COL parameter_name FOR A43;
COL prior_value FOR A50 HEA 'BEGIN_VALUE';
COL value FOR A50 HEA 'END_VALUE';
COL change FOR 999,999,999,999,990 HEA 'NET_CHANGE';
COL con_id FOR 999990;
COL pdb_name FOR A30 TRUNC;
--
BREAK ON begin_time SKIP PAGE ON end_time;
--
PRO
PRO PARAMETERS CHANGES
PRO ~~~~~~~~~~~~~~~~~~
WITH
parameter_hist AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.snap_id,
h.dbid,
h.instance_number,
h.parameter_name,
LAG(h.value) OVER (PARTITION BY h.dbid, h.instance_number, h.parameter_name, h.con_id ORDER BY h.snap_id) AS prior_value,
h.value,
h.con_id
FROM dba_hist_parameter h
WHERE h.dbid = TO_NUMBER('&&cs_dbid.')
AND h.instance_number = TO_NUMBER('&&cs_instance_number.')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') - 1 AND TO_NUMBER('&&cs_snap_id_to.')
AND &&cs_con_id. IN (1, h.con_id)
AND ('&&parameter_name.' IS NULL OR UPPER(parameter_name) = UPPER('&&parameter_name.'))
),
parameter_changes AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.snap_id,
h.dbid,
h.instance_number,
h.parameter_name,
h.prior_value,
h.value,
h.con_id,
s.begin_interval_time,
s.end_interval_time
FROM parameter_hist h,
dba_hist_snapshot s
WHERE NVL(h.value, '-666') <> NVL(h.prior_value, '-666')
AND h.snap_id BETWEEN TO_NUMBER('&&cs_snap_id_from.') AND TO_NUMBER('&&cs_snap_id_to.')
AND s.snap_id = h.snap_id
AND s.dbid = h.dbid
AND s.instance_number = h.instance_number
)
SELECT CAST(p.begin_interval_time AS DATE) AS begin_time,
CAST(p.end_interval_time AS DATE) AS end_time,
p.parameter_name,
p.prior_value,
p.value,
CASE WHEN REGEXP_LIKE(p.prior_value, '^[^a-zA-Z]*$') AND REGEXP_LIKE(p.value, '^[^a-zA-Z]*$') THEN TO_NUMBER(p.value) - TO_NUMBER(p.prior_value) END AS change, -- https://asktom.oracle.com/pls/apex/asktom.search?tag=determine-whether-the-given-is-numeric-alphanumeric-and-hexadecimal
p.con_id,
(SELECT c.name AS pdb_name FROM v$containers c WHERE c.con_id = p.con_id) AS pdb_name
FROM parameter_changes p
ORDER BY
p.begin_interval_time,
p.parameter_name,
p.con_id
/
--
CLEAR BREAK;
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&parameter_name."
--
@@cs_internal/cs_spool_tail.sql
--
--@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,121 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dbc_snapshot_log_v.sql
--
-- Purpose: DBC Snapshot Log Report
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to CDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dbc_snapshot_log_v.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
--
COL view_owner NEW_V view_owner NOPRI;
SELECT owner AS view_owner FROM dba_views WHERE view_name = 'DBC_SNAPSHOT_LOG_V';
--
COL table_name FOR A30;
COL region_acronym FOR A3 HEA 'RGN';
COL locale FOR A6;
COL runs FOR 999,990;
COL avg_secs FOR 999,990;
COL secs_per_day FOR 999,999,990;
COL total_rows_processed FOR 999,999,999,990;
COL errors FOR 99,990;
COL seconds FOR 999,990;
COL last_rows_processed FOR 999,999,999,990;
COL last_error_stack FOR A100;
--
BREAK ON REPORT;
COMPUTE SUM LABEL "TOTAL" OF runs secs_per_day total_rows_processed errors seconds last_rows_processed ON REPORT;
--
PRO
PRO Source (from CDB)
PRO ~~~~~~
SELECT --region_acronym,
--locale,
--db_name,
table_name,
runs,
first_time,
avg_secs,
secs_per_day,
errors,
total_rows_processed,
last_begin_time,
last_end_time,
seconds,
last_rows_processed,
last_error_stack
FROM &&view_owner..dbc_snapshot_log_v
/
--
COL min_since_last FOR 9,999,990.00 HEA 'MINUTES_AGO';
COL min_until_next FOR 9,999,990.00 HEA 'MINUTES_2GO';
COL avg_rows FOR 999,999,999,990;
COL to_key FOR A14;
COL error_message FOR A100;
--
BREAK ON REPORT;
COMPUTE SUM LABEL "TOTAL" OF runs total_rows_processed errors seconds ON REPORT;
--
PRO
PRO Target (into OMR)
PRO ~~~~~~
SELECT s.collect_name AS table_name,
s.collections AS runs,
s.first_time,
s.last_time,
s.status,
s.min_since_last,
s.min_until_next,
s.errors,
s.total_rows AS total_rows_processed,
s.avg_rows,
s.elap_sec AS seconds,
s.avg_sec AS avg_secs,
--from_key,
s.to_key,
h.error_message
FROM &&view_owner..iod_metadata_ctl_summ s, &&view_owner..iod_metadata_ctl_hist h
WHERE h.collect_name = s.collect_name
AND h.start_time = s.last_time
ORDER BY s.collect_name
/
--
CLEAR BREAK;
--
COL job_name FOR A30;
COL job_action FOR A40;
COL repeat_interval FOR A30;
COL enabled FOR A7;
COL last_start_date FOR A19;
COL last_run_secs FOR 999,990.000;
COL next_run_date FOR A19;
--
PRO
PRO DBA_SCHEDULER_JOBS
PRO ~~~~~~~~~~~~~~~~~~
SELECT job_name,
job_type,
job_action,
repeat_interval,
enabled,
state,
run_count,
EXTRACT(SECOND FROM last_run_duration) last_run_secs,
TO_CHAR(last_start_date, 'YYYY-MM-DD"T"HH24:MI:SS') last_start_date,
TO_CHAR(next_run_date, 'YYYY-MM-DD"T"HH24:MI:SS') next_run_date
FROM dba_scheduler_jobs
WHERE job_name LIKE 'IOD_META%'
ORDER BY
job_name
/

View File

@@ -0,0 +1,187 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dbms_stats_age.sql
--
-- Purpose: DBMS_STATS Age as per "auto optimizer stats collection"
--
-- Author: Carlos Sierra
--
-- Version: 2021/09/23
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dbms_stats_age.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
--@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_dbms_stats_age';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql
@@cs_internal/cs_spool_id.sql
--
PRO
PRO Latest Window Start Time (dba_autotask_job_history)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~
COL con_id FOR 999999;
COL pdb_name FOR A30 TRUNC;
COL window_name FOR A20;
COL window_start_time FOR A35;
COL window_duration FOR A30;
COL job_start_time FOR A35;
COL job_duration FOR A20;
COL job_info FOR A80;
--
WITH
hist AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
con_id, window_name, window_start_time, window_duration, job_start_time, job_duration,
EXTRACT(DAY FROM (job_start_time - window_start_time) * 24 * 60) AS delay_mins,
ROW_NUMBER() OVER (PARTITION BY con_id ORDER BY window_start_time DESC) AS rn,
job_error, job_status, job_info
FROM cdb_autotask_job_history
WHERE client_name = 'auto optimizer stats collection'
)
SELECT '|' AS "|",
h.con_id, c.name AS pdb_name,
h.window_name, h.window_start_time, h.window_duration, h.job_start_time, h.job_duration, h.delay_mins,
h.job_error, h.job_status, h.job_info
FROM hist h, v$containers c
WHERE h.rn = 1
AND c.con_id = h.con_id
ORDER BY h.con_id, h.window_start_time
/
--
COL con_id FOR 9999990;
COL pdb_name FOR A30 TRUNC;
COL last_good_date FOR A19;
COL days FOR 9,990.00;
--
PRO
PRO DBMS_STATS AGE (dba_autotask_task)
PRO ~~~~~~~~~~~~~~
WITH
last_exec AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
t.con_id,
CAST(t.last_good_date AS DATE) AS last_good_date
FROM cdb_autotask_task t
WHERE t.client_name = 'auto optimizer stats collection'
)
SELECT '|' AS "|",
e.con_id, c.name AS pdb_name,
TO_CHAR(e.last_good_date, 'YYYY-MM-DD"T"HH24:MI:SS') AS last_good_date,
ROUND(SYSDATE - e.last_good_date, 2) AS days
FROM last_exec e, v$containers c
WHERE c.con_id = e.con_id
ORDER BY
e.con_id
/
--
COL con_id FOR 999990;
COL pdb_name FOR A30 TRUNC;
COL tables FOR 99,990;
COL days1 FOR 9,990.00;
COL days2 FOR 9,990.00;
COL max_last_analyzed FOR A19;
COL p90th_percentile FOR A19;
--
PRO
PRO DBMS_STATS AGE (dba_tables)
PRO ~~~~~~~~~~~~~~
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
'|' AS "|",
t.con_id,
c.name AS pdb_name,
MAX(t.last_analyzed) AS max_last_analyzed,
ROUND(SYSDATE - MAX(t.last_analyzed), 2) AS days1,
PERCENTILE_DISC(0.9) WITHIN GROUP (ORDER BY t.last_analyzed ASC) AS p90th_percentile,
ROUND(SYSDATE - PERCENTILE_DISC(0.9) WITHIN GROUP (ORDER BY t.last_analyzed ASC), 2) AS days2,
COUNT(*) AS tables
FROM cdb_tables t, cdb_users u, v$containers c
WHERE t.con_id <> 2
AND u.con_id = t.con_id
AND u.username = t.owner
AND u.oracle_maintained = 'N'
AND u.common = 'NO'
AND c.con_id = t.con_id
GROUP BY
t.con_id, c.name
ORDER BY
t.con_id, c.name
/
--
COL con_id FOR 9999990;
COL pdb_name FOR A30 TRUNC;
COL last_good_date FOR A19;
COL days FOR 9,990.00;
COL tables FOR 99,990;
COL days1 FOR 9,990.00;
COL days2 FOR 9,990.00;
COL max_last_analyzed FOR A19;
COL p90th_percentile FOR A19;
PRO
PRO DBMS_STATS AGE (dba_autotask_task and dba_tables)
PRO ~~~~~~~~~~~~~~
WITH
autotask_task AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
t.con_id,
TO_CHAR(t.last_good_date, 'YYYY-MM-DD"T"HH24:MI:SS') AS last_good_date,
ROUND(SYSDATE - CAST(t.last_good_date AS DATE), 2) AS days
FROM cdb_autotask_task t
WHERE t.client_name = 'auto optimizer stats collection'
),
tables AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') */
t.con_id,
MAX(t.last_analyzed) AS max_last_analyzed,
ROUND(SYSDATE - MAX(t.last_analyzed), 2) AS days1,
PERCENTILE_DISC(0.9) WITHIN GROUP (ORDER BY t.last_analyzed ASC) AS p90th_percentile,
ROUND(SYSDATE - PERCENTILE_DISC(0.9) WITHIN GROUP (ORDER BY t.last_analyzed ASC), 2) AS days2,
COUNT(*) AS tables
FROM cdb_tables t, cdb_users u
WHERE t.con_id <> 2
AND u.con_id = t.con_id
AND u.username = t.owner
AND u.oracle_maintained = 'N'
AND u.common = 'NO'
GROUP BY
t.con_id
)
SELECT '|' AS "|",
a.con_id,
c.name AS pdb_name,
a.last_good_date,
a.days,
'|' AS "|",
t.max_last_analyzed,
t.days1,
t.p90th_percentile,
t.days2,
t.tables
FROM autotask_task a, tables t, v$containers c
WHERE t.con_id = a.con_id
AND c.con_id = a.con_id
ORDER BY
a.con_id
/
--
PRO
PRO SQL> @&&cs_script_name..sql
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,78 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dbms_stats_auto.sql
--
-- Purpose: Generate DBMS_STATS.report_gather_auto_stats
--
-- Author: Carlos Sierra
--
-- Version: 2021/07/30
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter optional parameters when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dbms_stats_auto.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_dbms_stats_auto';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
PRO
PRO 1. Detail Level: [{BASIC}|TYPICAL|ALL]
DEF cs2_detail_level = '&1.';
UNDEF 1;
COL cs2_detail_level NEW_V cs2_detail_level NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&cs2_detail_level.')) IN ('TYPICAL','BASIC','ALL') THEN UPPER(TRIM('&&cs2_detail_level.')) ELSE 'BASIC' END AS cs2_detail_level FROM DUAL
/
--
PRO
PRO 2. Format: [{TEXT}|HTML|XML]
DEF cs2_format = '&2.';
UNDEF 2;
COL cs2_format NEW_V cs2_format NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&cs2_format.')) IN ('TEXT','HTML','XML') THEN UPPER(TRIM('&&cs2_format.')) ELSE 'TEXT' END AS cs2_format FROM DUAL
/
COL cs2_file_suffix NEW_V cs2_file_suffix NOPRI;
SELECT CASE '&&cs2_format.' WHEN 'TEXT' THEN 'txt' WHEN 'HTML' THEN 'html' WHEN 'XML' THEN 'xml' ELSE 'txt' END AS cs2_file_suffix FROM DUAL
/
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&cs2_detail_level." "&&cs2_format."
@@cs_internal/cs_spool_id.sql
--
PRO DETAIL_LEVEL : "&&cs2_detail_level."
PRO FORMAT : "&&cs2_format."
PRO
--
-- opens new spool if html or xml, or continues with existing if txt
SET HEA OFF PAGES 0;
SPO &&cs_file_name..&&cs2_file_suffix. APP
--
SELECT DBMS_STATS.report_gather_auto_stats(detail_level => '&&cs2_detail_level.', format => '&&cs2_format.') FROM DUAL
/
--
SPO OFF;
SET HEA ON PAGES 100;
HOS chmod 644 &&cs_file_name..&&cs2_file_suffix.
-- continues with original spool
SPO &&cs_file_name..txt APP
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs2_detail_level." "&&cs2_format."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,88 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dbms_stats_gather_database_stats.sql
--
-- Purpose: Execute DBMS_STATS.GATHER_DATABASE_STATS
--
-- Author: Carlos Sierra
--
-- Version: 2021/09/27
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dbms_stats_gather_database_stats.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
-- https://docs.oracle.com/cd/B19306_01/server.102/b14211/stats.htm#i41282
-- The GATHER_STATS_JOB job gathers optimizer statistics by calling the DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC procedure.
-- The GATHER_DATABASE_STATS_JOB_PROC procedure collects statistics on database objects when the object has no previously gathered statistics or the existing statistics are stale because the underlying object has been modified significantly (more than 10% of the rows).
-- The DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC is an internal procedure, but its operates in a very similar fashion to the DBMS_STATS.GATHER_DATABASE_STATS procedure using the GATHER AUTO option.
-- The primary difference is that the DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC procedure prioritizes the database objects that require statistics, so that those objects which most need updated statistics are processed first.
-- This ensures that the most-needed statistics are gathered before the maintenance window closes.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
--@@cs_internal/cs_cdb_warn.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
DEF cs_script_name = 'cs_dbms_stats_gather_database_stats';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql
@@cs_internal/cs_spool_id.sql
--
SET HEA OFF PAGES 0;
COL lin FOR A300;
PRO
SELECT
'ALTER SESSION SET CONTAINER = '||name||';'||CHR(10)||
'SET ECHO ON TIMI ON TIM ON SERVEROUT ON;'||CHR(10)||
'BEGIN'||CHR(10)||
'FOR i IN (SELECT DBMS_STATS.GET_PREFS(''STALE_PERCENT'') AS stale_percent FROM DUAL)'||CHR(10)||
'LOOP'||CHR(10)||
'IF i.stale_percent <> ''5'' THEN'||CHR(10)||
'DBMS_OUTPUT.PUT_LINE(''STALE_PERCENT was: ''||i.stale_percent);'||CHR(10)||
'DBMS_STATS.SET_GLOBAL_PREFS(''STALE_PERCENT'', ''5'');'||CHR(10)||
'END IF;'||CHR(10)||
'END LOOP;'||CHR(10)||
'DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC;'||CHR(10)||
'END;'||CHR(10)||
'/' AS lin
FROM v$containers
WHERE con_id <> 2
AND open_mode = 'READ WRITE'
AND restricted = 'NO'
ORDER BY
DBMS_RANDOM.value
/
--
SPO &&cs_file_name._driver.sql
PRO SET ECHO ON TIMI ON TIM ON;
/
PRO SET ECHO OFF TIMI OFF TIM OFF;
SPO OFF;
--
SET HEA ON PAGES 100;
SPO &&cs_file_name..txt APP;
--
@&&cs_file_name._driver.sql
--
PRO
PRO SQL> @&&cs_script_name..sql
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

Some files were not shown because too many files have changed in this diff Show More