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

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
--

View File

@@ -0,0 +1,87 @@
REM Dummy line to avoid "usage: r_sql_exec" when executed using iodcli
----------------------------------------------------------------------------------------
--
-- File name: cs_dbms_stats_gather_database_stats_job.sql
--
-- Purpose: Execute DBMS_STATS.GATHER_DATABASE_STATS (stand-alone)
--
-- Author: Carlos Sierra
--
-- Version: 2022/04/22
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dbms_stats_gather_database_stats_job.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.
--
---------------------------------------------------------------------------------------
--
WHENEVER OSERROR CONTINUE;
WHENEVER SQLERROR EXIT FAILURE;
--
-- exit graciously if executed on standby
WHENEVER SQLERROR EXIT SUCCESS;
DECLARE
l_is_primary VARCHAR2(5);
BEGIN
SELECT CASE WHEN open_mode = 'READ WRITE' AND database_role = 'PRIMARY' THEN 'TRUE' ELSE 'FALSE' END AS is_primary INTO l_is_primary FROM v$database;
IF l_is_primary = 'FALSE' THEN raise_application_error(-20000, 'Not PRIMARY'); END IF;
END;
/
-- exit not graciously if any error
WHENEVER SQLERROR EXIT FAILURE;
--
ALTER SESSION SET container = CDB$ROOT;
--
DEF cs_file_name = '/tmp/cs_dbms_stats_gather_database_stats_job';
--
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;
SET HEA OFF PAGES 0 SERVEROUT ON;
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 /* cs_dbms_stats_gather_database_stats_job 1 job */'||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)||
'END;'||CHR(10)||
'/'||CHR(10)||
'BEGIN /* cs_dbms_stats_gather_database_stats_job 2 job */'||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 SPO &&cs_file_name..log
/
PRO SPO OFF;
PRO SET ECHO OFF TIMI OFF TIM OFF;
SPO OFF;
--
@@&&cs_file_name._driver.sql
--
ALTER SESSION SET container = CDB$ROOT;
--

View File

@@ -0,0 +1,83 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dbms_stats_operations.sql
--
-- Purpose: Generate DBMS_STATS.report_stats_operations
--
-- 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_operations.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_operations';
--
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. Detail Level: [{BASIC}|TYPICAL|ALL]
DEF cs2_detail_level = '&3.';
UNDEF 3;
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 4. Format: [{TEXT}|HTML|XML]
DEF cs2_format = '&4.';
UNDEF 4;
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 "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_detail_level." "&&cs2_format."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.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_stats_operations(detail_level => '&&cs2_detail_level.', format => '&&cs2_format.', since => TO_TIMESTAMP('&&cs_sample_time_from.', '&&cs_datetime_full_format.'), until => TO_TIMESTAMP('&&cs_sample_time_to.', '&&cs_datetime_full_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 "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_detail_level." "&&cs2_format."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

173
csierra/cs_df_u02_chart.sql Normal file
View File

@@ -0,0 +1,173 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_df_u02_chart.sql
--
-- Purpose: Disk FileSystem u02 Utilization Chart
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/25
--
-- Usage: Execute connected to CDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_df_u02_chart.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_df_u02_chart';
DEF cs_hours_range_default = '4320';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL cs_hours_range_default NEW_V cs_hours_range_default NOPRI;
SELECT TRIM(TO_CHAR(LEAST(TRUNC((SYSDATE - MIN(timestamp)) * 24), TO_NUMBER('&&cs_hours_range_default.')))) AS cs_hours_range_default FROM &&cs_tools_schema..dbc_system
/
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
PRO
PRO 3. Trendlines Type: &&cs_trendlines_types.
DEF cs_trendlines_type = '&3.';
UNDEF 3;
COL cs_trendlines_type NEW_V cs_trendlines_type NOPRI;
COL cs_trendlines NEW_V cs_trendlines NOPRI;
COL cs_hAxis_maxValue NEW_V cs_hAxis_maxValue NOPRI;
SELECT CASE WHEN LOWER(TRIM(NVL('&&cs_trendlines_type.', 'none'))) IN ('linear', 'polynomial', 'exponential', 'none') THEN LOWER(TRIM(NVL('&&cs_trendlines_type.', 'none'))) ELSE 'none' END AS cs_trendlines_type,
CASE WHEN LOWER(TRIM(NVL('&&cs_trendlines_type.', 'none'))) = 'none' THEN '//' END AS cs_trendlines,
CASE WHEN LOWER(TRIM(NVL('&&cs_trendlines_type.', 'none'))) IN ('linear', 'polynomial', 'exponential') THEN '&&cs_hAxis_maxValue.' END AS cs_hAxis_maxValue
FROM DUAL
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = "Disk FileSystem u02 and DB Utilization";
DEF chart_title = "";
DEF xaxis_title = "";
DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}, 3:{}";
DEF vaxis_title = "Terabytes (TB)";
--
-- (isStacked is true and baseline is null) or (not isStacked and baseline >= 0)
DEF is_stacked = "isStacked: true,";
DEF vaxis_baseline = "";
DEF vaxis_viewwindow = ", viewWindow: {min:0}";
DEF chart_foot_note_2 = "<br>2) ";
DEF chart_foot_note_2 = "";
DEF chart_foot_note_3 = "";
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_trendlines_type."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'FileSystem u02 TB Space', id:'1', type:'number'}
PRO ,{label:'FileSystem u02 TB Used', id:'2', type:'number'}
PRO ,{label:'Database TB Allocated', id:'3', type:'number'}
PRO ,{label:'Database TB Used', id:'4', 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;
/****************************************************************************************/
df_hh AS (
SELECT timestamp, u02_size, u02_used, u02_available, host_name,
ROW_NUMBER() OVER (PARTITION BY TRUNC(timestamp, 'HH') ORDER BY u02_size DESC NULLS LAST, u02_used DESC NULLS LAST) AS rn
FROM &&cs_tools_schema..dbc_system
WHERE timestamp >= TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND timestamp < TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
),
df_u02 AS (
SELECT ROUND(timestamp, 'HH') AS timestamp,
ROUND((u02_used + u02_available) * 1024 / POWER(10, 12), 3) AS tb_space,
ROUND(u02_used * 1024 / POWER(10, 12), 3) AS tb_used
FROM df_hh
WHERE rn = 1
),
ts_hh AS (
SELECT snap_time, SUM(allocated_bytes) AS allocated_bytes, SUM(used_bytes) AS used_bytes,
ROW_NUMBER() OVER (PARTITION BY TRUNC(snap_time, 'HH') ORDER BY SUM(allocated_bytes) DESC NULLS LAST, SUM(used_bytes) DESC NULLS LAST) AS rn
FROM &&cs_tools_schema..dbc_tablespaces
WHERE snap_time >= TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.')
AND snap_time < TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
GROUP BY
snap_time
),
ts_space AS (
SELECT ROUND(snap_time, 'HH') AS snap_time,
ROUND(allocated_bytes / POWER(10, 12), 3) AS tb_allocated,
ROUND(used_bytes / POWER(10, 12), 3) AS tb_used
FROM ts_hh
WHERE rn = 1
),
/****************************************************************************************/
my_query AS (
SELECT df.timestamp,
df.tb_space AS df_tb_space,
df.tb_used AS df_tb_used,
ts.tb_allocated AS db_tb_allocated,
ts.tb_used AS db_tb_used
FROM df_u02 df,
ts_space ts
WHERE ts.snap_time = df.timestamp
)
SELECT ', [new Date('||
TO_CHAR(q.timestamp, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(q.timestamp, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(q.timestamp, 'DD')|| /* day */
','||TO_CHAR(q.timestamp, 'HH24')|| /* hour */
','||TO_CHAR(q.timestamp, 'MI')|| /* minute */
','||TO_CHAR(q.timestamp, 'SS')|| /* second */
')'||
','||num_format(q.df_tb_space, 3)||
','||num_format(q.df_tb_used, 3)||
','||num_format(q.db_tb_allocated, 3)||
','||num_format(q.db_tb_used, 3)||
']'
FROM my_query q
ORDER BY
q.timestamp
/
/****************************************************************************************/
SET HEA ON PAGES 100;
--
-- [Line|Area|SteppedArea|Scatter]
DEF cs_chart_type = 'Line';
-- 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

25
csierra/cs_dg.sql Normal file
View File

@@ -0,0 +1,25 @@
COL role FOR A10;
COL db_unique_name FOR A15;
COL host_name FOR A64;
--
SELECT r.role, d.db_unique_name, h.host_name
FROM
(SELECT x.value db_unique_name, ROW_NUMBER() OVER (ORDER BY x.indx) AS rn FROM x$drc x WHERE x.attribute = 'DATABASE') d,
(SELECT x.value role, ROW_NUMBER() OVER (ORDER BY x.indx) AS rn FROM x$drc x WHERE x.attribute = 'role') r,
(SELECT x.value host_name, ROW_NUMBER() OVER (ORDER BY x.indx) AS rn FROM x$drc x WHERE x.attribute = 'host') h
WHERE r.rn = d.rn AND h.rn = d.rn
ORDER BY r.role DESC, d.db_unique_name
/
--
COL data_guard_configuration FOR A150;
--
SELECT LISTAGG(x.attribute||':'||x.value, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY x.indx) AS data_guard_configuration
FROM x$drc x
WHERE x.attribute IN ('DRC', 'protection_mode', 'enabled', 'fast_start_failover', 'fsfo_target', 'role_change_detected',
'DATABASE', 'enabled', 'role', 'receive_from', 'ship_to', 'FSFOTargetValidity',
'host')
GROUP BY
x.object_id
ORDER BY
x.object_id
/

View File

@@ -0,0 +1,185 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dg_protection_mode_switches.sql
--
-- Purpose: Data Guard Protection Mode Switches as per Log Archive Dest
--
-- Author: Carlos Sierra
--
-- Version: 2021/10/18
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dg_protection_mode_switches.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_dg_protection_mode_switches';
--
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_set_container_to_cdb_root.
--
COL begin_time FOR A19 HEA 'AWR SNAP|BEGIN TIME';
COL end_time FOR A19 HEA 'AWR SNAP|END TIME';
COL begin_host FOR A64 HEA 'AWR SNAP|BEGIN STANDBY HOST';
COL end_host FOR A64 HEA 'AWR SNAP|END STANDBY HOST';
COL min_date_time FOR A19 HEA 'LOGON STORM|BEGIN TIME';
COL max_date_time FOR A19 HEA 'LOGON STORM|END TIME';
COL max_aas FOR 99,999 HEA 'LOGON STORM|MAX AAS';
COL max_machines FOR 999,990 HEA 'LOGON STORM|MAX AAS';
COL seconds FOR 999,990 HEA 'LOGON STORM|SECONDS';
COL max_pdbs FOR 999,990 HEA 'LOGON STORM|MAX PDBS';
COL begin_mode FOR A15 HEA 'AWR SNAP|BEGIN MODE';
COL end_mode FOR A15 HEA 'AWR SNAP|END MODE';
COL mode_switch FOR A7 HEA 'MODE|SWITCH';
COL switch_over FOR A7 HEA 'SWITCH|OVER';
--
BREAK ON mode_switch SKIP 1 DUPL;
--
PRO
PRO DG PROTECTION MODE SWITCHES
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 parameter_name LIKE 'log_archive_dest%'
AND parameter_name NOT LIKE 'log_archive_dest_state%'
),
parameter_changes AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.snap_id,
h.dbid,
h.instance_number,
h.parameter_name,
h.prior_value,
h.value,
REPLACE(REPLACE(REGEXP_SUBSTR(h.prior_value, '\(HOST=([[:alnum:]]|\.|-)+\)'), '(HOST='), ')') AS begin_host,
REPLACE(REPLACE(REGEXP_SUBSTR(h.value, '\(HOST=([[:alnum:]]|\.|-)+\)'), '(HOST='), ')') AS end_host,
CASE
WHEN h.prior_value LIKE '% SYNC AFFIRM %' THEN 'SYNC AFFIRM'
WHEN h.prior_value LIKE '% ASYNC AFFIRM %' THEN 'ASYNC AFFIRM' -- not expected
WHEN h.prior_value LIKE '% SYNC NOAFFIRM %' THEN 'SYNC NOAFFIRM' -- not expected
WHEN h.prior_value LIKE '% ASYNC NOAFFIRM %' THEN 'ASYNC NOAFFIRM'
END AS begin_mode,
CASE
WHEN h.value LIKE '% SYNC AFFIRM %' THEN 'SYNC AFFIRM'
WHEN h.value LIKE '% ASYNC AFFIRM %' THEN 'ASYNC AFFIRM' -- not expected
WHEN h.value LIKE '% SYNC NOAFFIRM %' THEN 'SYNC NOAFFIRM' -- not expected
WHEN h.value LIKE '% ASYNC NOAFFIRM %' THEN 'ASYNC NOAFFIRM'
END AS end_mode,
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.prior_value LIKE '%(HOST=%'
AND h.value LIKE '%(HOST=%'
AND s.snap_id = h.snap_id
AND s.dbid = h.dbid
AND s.instance_number = h.instance_number
),
dg_mode_switches AS (
SELECT CAST(p.begin_interval_time AS DATE) AS begin_time,
CAST(p.end_interval_time AS DATE) AS end_time,
p.begin_mode,
p.end_mode,
p.begin_host,
p.end_host
FROM parameter_changes p
),
over_height AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS aas,
COUNT(DISTINCT machine) AS machines,
COUNT(DISTINCT con_id) AS pdbs,
(CAST(h.sample_time AS DATE) - LAG(CAST(h.sample_time AS DATE)) OVER (ORDER BY h.sample_time)) * 24 * 3600 AS secs_from_prior
FROM dba_hist_active_sess_history h
GROUP BY
h.sample_time
HAVING COUNT(*) > 1000 -- active sessions!
),
over_time AS (
SELECT CAST(h.sample_time AS DATE) AS sample_time,
h.aas,
h.machines,
h.pdbs
FROM over_height h
WHERE secs_from_prior < 20 -- contiguous
),
logon_storms AS (
SELECT TRUNC(sample_time) AS date_time,
MIN(sample_time - (20/24/3600)) AS min_date_time,
MAX(sample_time) AS max_date_time,
((MAX(sample_time) - MIN(sample_time)) * 24 * 3600) + 20 AS seconds,
MAX(aas) AS max_aas,
MAX(machines) AS max_machines,
MAX(pdbs) AS max_pdbs
FROM over_time
GROUP BY
TRUNC(sample_time)
)
SELECT dg.begin_time,
dg.end_time,
dg.begin_mode,
dg.end_mode,
CASE dg.begin_mode WHEN 'ASYNC NOAFFIRM' THEN 'HP' WHEN 'SYNC AFFIRM' THEN 'HA' END||'->'||
CASE dg.end_mode WHEN 'ASYNC NOAFFIRM' THEN 'HP' WHEN 'SYNC AFFIRM' THEN 'HA' END AS mode_switch,
ls.min_date_time,
ls.max_date_time,
ls.seconds,
ls.max_aas,
ls.max_pdbs,
dg.begin_host,
dg.end_host,
CASE WHEN dg.begin_host <> dg.end_host THEN 'YES' ELSE 'NO' END AS switch_over
FROM dg_mode_switches dg
OUTER APPLY (
SELECT s.min_date_time,
s.max_date_time,
s.seconds,
s.max_aas,
s.max_pdbs
FROM logon_storms s
WHERE (s.min_date_time BETWEEN dg.begin_time AND dg.end_time OR s.max_date_time BETWEEN dg.begin_time AND dg.end_time)
AND ROWNUM >= 1 /* MATERIALIZE NO_MERGE */
ORDER BY
s.min_date_time ASC
FETCH FIRST 1 ROW ONLY
) ls
ORDER BY
dg.begin_time
/
--
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
--

View File

@@ -0,0 +1,194 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dg_redo_dest_resp_histogram_chart.sql
--
-- Purpose: Data Guard (DG) REDO Transport Duration Chart
--
-- Author: Carlos Sierra
--
-- Version: 2021/04/27
--
-- Usage: Execute connected to CDB.
--
-- Enter Source and Destination Hosts when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dg_redo_dest_resp_histogram_chart.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_dg_redo_dest_resp_histogram_chart';
DEF cs_hours_range_default = '8760';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL cs_hours_range_default NEW_V cs_hours_range_default NOPRI;
SELECT TRIM(TO_CHAR(LEAST(TRUNC((SYSDATE - MIN(time)) * 24), TO_NUMBER('&&cs_hours_range_default.')))) AS cs_hours_range_default FROM &&cs_tools_schema..dbc_redo_dest_histogram
/
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
COL source_host_name FOR A64 TRUNC;
SELECT DISTINCT host_name AS source_host_name
FROM &&cs_tools_schema..dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
ORDER BY 1
/
PRO
PRO 3. Source Host Name: (opt)
DEF s_host_name = '&3.';
UNDEF 3;
--
COL dest_host_name FOR A64 TRUNC;
SELECT DISTINCT dest_host_name
FROM &&cs_tools_schema..dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND host_name = NVL('&&s_host_name.', host_name)
ORDER BY 1
/
PRO
PRO 3. Destination Host Name: (opt)
DEF d_host_name = '&4.';
UNDEF 4;
--
DEF source_dest_host_name = "";
COL source_dest_host_name NEW_V source_dest_host_name NOPRI;
SELECT CASE WHEN '&&s_host_name.' IS NOT NULL THEN 'SRC:&&s_host_name.' END||CASE WHEN '&&s_host_name.&&d_host_name.' IS NOT NULL THEN ' -> ' END||CASE WHEN '&&d_host_name.' IS NOT NULL THEN 'DST:&&d_host_name.' END AS source_dest_host_name FROM DUAL
/
--
COL label1 NEW_V label1 NOPRI;
COL label2 NEW_V label2 NOPRI;
COL label3 NEW_V label3 NOPRI;
COL label4 NEW_V label4 NOPRI;
COL label5 NEW_V label5 NOPRI;
COL label6 NEW_V label6 NOPRI;
WITH
scope AS (
SELECT host_name||' -> '||dest_host_name AS label, SUM(duration_seconds) AS entries, ROW_NUMBER() OVER (ORDER BY SUM(duration_seconds) DESC) AS rn
FROM &&cs_tools_schema..dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND host_name = NVL('&&s_host_name.', host_name)
AND dest_host_name = NVL('&&d_host_name.', dest_host_name)
GROUP BY host_name||' -> '||dest_host_name
ORDER BY 2 DESC NULLS LAST
FETCH FIRST 6 ROWS ONLY
)
SELECT MAX(CASE rn WHEN 1 THEN label END) AS label1,
MAX(CASE rn WHEN 2 THEN label END) AS label2,
MAX(CASE rn WHEN 3 THEN label END) AS label3,
MAX(CASE rn WHEN 4 THEN label END) AS label4,
MAX(CASE rn WHEN 5 THEN label END) AS label5,
MAX(CASE rn WHEN 6 THEN label END) AS label6
FROM scope
WHERE rn BETWEEN 1 AND 6
/
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
DEF report_title = "Data Guard (DG) REDO Transport Duration (v$redo_dest_resp_histogram)";
DEF chart_title = "Data Guard (DG) REDO Transport Duration between &&cs_sample_time_from. and &&cs_sample_time_to. UTC";
DEF xaxis_title = "&&source_dest_host_name.";
DEF vaxis_title = "Duration (Seconds)";
-- DEF hAxis_maxValue = "&&cs_hAxis_maxValue.";
-- DEF cs_trendlines_series = ", 0:{}, 1:{}, 2:{}";
--
-- (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 = "";
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." "&&s_host_name." "&&d_host_name."';
--
@@cs_internal/cs_spool_head_chart.sql
--
PRO ,{label:'&&label1.', id:'1', type:'number'}
PRO ,{label:'&&label2.', id:'2', type:'number'}
PRO ,{label:'&&label3.', id:'3', type:'number'}
PRO ,{label:'&&label4.', id:'4', type:'number'}
PRO ,{label:'&&label5.', id:'5', type:'number'}
PRO ,{label:'&&label6.', id:'6', 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;
/****************************************************************************************/
my_query AS (
SELECT time AS timestamp,
CASE host_name||' -> '||dest_host_name WHEN '&&label1.' THEN duration_seconds END AS seconds1,
CASE host_name||' -> '||dest_host_name WHEN '&&label2.' THEN duration_seconds END AS seconds2,
CASE host_name||' -> '||dest_host_name WHEN '&&label3.' THEN duration_seconds END AS seconds3,
CASE host_name||' -> '||dest_host_name WHEN '&&label4.' THEN duration_seconds END AS seconds4,
CASE host_name||' -> '||dest_host_name WHEN '&&label5.' THEN duration_seconds END AS seconds5,
CASE host_name||' -> '||dest_host_name WHEN '&&label6.' THEN duration_seconds END AS seconds6
FROM &&cs_tools_schema..dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND host_name = NVL('&&s_host_name.', host_name)
AND dest_host_name = NVL('&&d_host_name.', dest_host_name)
AND host_name||' -> '||dest_host_name IN ('&&label1.', '&&label2.', '&&label3.', '&&label4.', '&&label5.', '&&label6.')
)
SELECT ', [new Date('||
TO_CHAR(q.timestamp, 'YYYY')|| /* year */
','||(TO_NUMBER(TO_CHAR(q.timestamp, 'MM')) - 1)|| /* month - 1 */
','||TO_CHAR(q.timestamp, 'DD')|| /* day */
','||TO_CHAR(q.timestamp, 'HH24')|| /* hour */
','||TO_CHAR(q.timestamp, 'MI')|| /* minute */
','||TO_CHAR(q.timestamp, 'SS')|| /* second */
')'||
','||num_format(q.seconds1)||
','||num_format(q.seconds2)||
','||num_format(q.seconds3)||
','||num_format(q.seconds4)||
','||num_format(q.seconds5)||
','||num_format(q.seconds6)||
']'
FROM my_query q
ORDER BY
q.timestamp
/
/****************************************************************************************/
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,100 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_dg_redo_dest_resp_histogram_report.sql
--
-- Purpose: Data Guard (DG) REDO Transport Duration Report
--
-- Author: Carlos Sierra
--
-- Version: 2021/06/15
--
-- Usage: Execute connected to CDB.
--
-- Enter Source and Destination Hosts when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dg_redo_dest_resp_histogram_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_dg_redo_dest_resp_histogram_report';
DEF cs_hours_range_default = '8760';
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL cs_hours_range_default NEW_V cs_hours_range_default NOPRI;
SELECT TRIM(TO_CHAR(LEAST(TRUNC((SYSDATE - MIN(time)) * 24), TO_NUMBER('&&cs_hours_range_default.')))) AS cs_hours_range_default FROM C##IOD.dbc_redo_dest_histogram
/
--
@@cs_internal/cs_sample_time_from_and_to.sql
@@cs_internal/cs_snap_id_from_and_to.sql
--
COL source_host_name FOR A64 TRUNC;
SELECT DISTINCT host_name AS source_host_name
FROM C##IOD.dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
ORDER BY 1
/
PRO
PRO 3. Source Host Name: (opt)
DEF s_host_name = '&3.';
UNDEF 3;
--
COL dest_host_name FOR A64 TRUNC;
SELECT DISTINCT dest_host_name
FROM C##IOD.dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND host_name = NVL('&&s_host_name.', host_name)
ORDER BY 1
/
PRO
PRO 3. Destination Host Name: (opt)
DEF d_host_name = '&4.';
UNDEF 4;
--
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." "&&s_host_name." "&&d_host_name."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO SOURCE : "&&s_host_name."
PRO DESTINATION : "&&d_host_name."
--
COL seconds FOR 999,999,990;
COL frequency FOR 999,990;
BREAK ON source_host_name SKIP PAGE DUPL ON dest_host_name SKIP PAGE DUPL;
--
PRO
PRO Data Guard (DG) REDO Transport Duration (v$redo_dest_resp_histogram)
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT host_name AS source_host_name, dest_host_name, time, duration_seconds AS seconds, frequency
FROM C##IOD.dbc_redo_dest_histogram
WHERE time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.')
AND host_name = NVL('&&s_host_name.', host_name)
AND dest_host_name = NVL('&&d_host_name.', dest_host_name)
ORDER BY host_name, dest_host_name, time
/
--
CL BREAK COMPUTE;
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&s_host_name." "&&d_host_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 @@
select value from v$diag_info where name = 'Diag Trace';

View File

@@ -0,0 +1,62 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_drop_redef_table.sql
--
-- Purpose: Generate commands to drop stale objects from failed Table Redefinition(s)
--
-- Author: Carlos Sierra
--
-- Version: 2021/10/20
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_drop_redef_table.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
-- Comands listed by this script must be executed manually inside corresponding PDB(s)
--
---------------------------------------------------------------------------------------
--
SET HEA ON LIN 500 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF;
ALTER SESSION SET "_px_cdb_view_enabled" = FALSE;
--
COL drop_commands FOR A200;
--
WITH
users AS (
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') MATERIALIZE NO_MERGE */ con_id, username FROM cdb_users WHERE oracle_maintained = 'N' AND common = 'NO'
)
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') MATERIALIZE NO_MERGE */
'/* '||c.name||' #1 '||purge_start||' '||last_purge_date||' */ DROP MATERIALIZED VIEW LOG ON "'||lg.log_owner||'"."'||lg.master||'";' drop_commands
FROM cdb_mview_logs lg, v$containers c
WHERE lg.log_table LIKE 'MLOG$\_'||CHR(37) ESCAPE '\'
AND c.con_id = lg.con_id
AND c.open_mode = 'READ WRITE'
AND c.restricted = 'NO'
AND (lg.con_id, lg.log_owner) IN (SELECT u.con_id, u.username FROM users u)
UNION ALL
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') MATERIALIZE NO_MERGE */
'/* '||c.name||' #2 '||LAST_REFRESH_DATE||' '||LAST_REFRESH_END_TIME||' '||STALE_SINCE||' */ DROP MATERIALIZED VIEW "'||mv.owner||'"."'||mv.mview_name||'";' drop_commands
FROM cdb_mviews mv, v$containers c
WHERE mv.mview_name LIKE 'REDEF$\_T'||CHR(37) ESCAPE '\'
AND c.con_id = mv.con_id
AND c.open_mode = 'READ WRITE'
AND c.restricted = 'NO'
AND (mv.con_id, mv.owner) IN (SELECT u.con_id, u.username FROM users u)
UNION ALL
SELECT /*+ OPT_PARAM('_px_cdb_view_enabled' 'FALSE') MATERIALIZE NO_MERGE */
'/* '||c.name||' #3 '||last_analyzed||' */ DROP TABLE "'||tb.owner||'"."'||tb.table_name||'";' drop_commands
FROM cdb_tables tb, v$containers c
WHERE tb.table_name LIKE 'REDEF$\_T'||CHR(37) ESCAPE '\'
AND c.con_id = tb.con_id
AND c.open_mode = 'READ WRITE'
AND c.restricted = 'NO'
AND (tb.con_id, tb.owner) IN (SELECT u.con_id, u.username FROM users u)
ORDER BY
1
/
PRO
PRO Comands listed by this script must be executed manually inside corresponding PDB(s)
PRO

View File

@@ -0,0 +1,40 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_epoch_to_time.sql
--
-- Purpose: Convert Epoch to Time
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_epoch_to_time.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;
SET NUM 15;
DEF cs_datetime_full_format = 'YYYY-MM-DD"T"HH24:MI:SS';
PRO
PRO 1. Enter Epoch:
DEF cs_epoch = '&1.';
UNDEF 1;
--
-- note: on 19c consider select dbms_stats.convert_raw_to_date(hextoraw('7877031203192A0C1988C0')) from dual;
--
WITH
days AS (
SELECT TO_NUMBER('&&cs_epoch.'||CASE WHEN LENGTH('&&cs_epoch.') <= 10 THEN '000' END) / 1000 / 3600 / 24 AS cnt,
CASE WHEN LENGTH('&&cs_epoch.') > 10 THEN SUBSTR('&&cs_epoch.', 11, 3) END AS ms
FROM DUAL
)
SELECT TO_CHAR(TO_DATE('1970-01-01T00:00:00', '&&cs_datetime_full_format.') + days.cnt, '&&cs_datetime_full_format.')||
CASE WHEN days.ms IS NOT NULL THEN '.'||days.ms END
AS time
FROM days
/

View File

@@ -0,0 +1,56 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_estimate_index_size.sql
--
-- Purpose: Estimate Index Size
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_estimate_index_size.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;
PRO
PRO 1. Enter Index Name:
DEF index_name = '&1.';
UNDEF 1;
--
COL schema_name NEW_V schema_name NOPRI;
SELECT owner AS schema_name FROM dba_indexes WHERE index_name = '&&index_name.';
--
VAR v_used_bytes NUMBER;
VAR v_alloc_bytes NUMBER;
BEGIN
DBMS_SPACE.create_index_cost (
ddl => DBMS_METADATA.get_ddl('INDEX', '&&index_name.', '&&schema_name.'),
used_bytes => :v_used_bytes,
alloc_bytes => :v_alloc_bytes
);
END;
/
COL used_gb FOR 999,990.000;
COL alloc_gb FOR 999,990.000;
SELECT :v_used_bytes/1e9 AS used_gb, :v_alloc_bytes/1e9 AS alloc_gb FROM DUAL;
--
ROLLBACK;
DELETE plan_table;
BEGIN
EXECUTE IMMEDIATE('EXPLAIN PLAN FOR '||DBMS_METADATA.get_ddl('INDEX', '&&index_name.', '&&schema_name.'));
END;
/
COMMIT;
SET HEA ON PAGES 0;
PRO
SELECT plan_table_output FROM
TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', NULL, 'ADVANCED'))
/
SET HEA ON PAGES 100;
CLEAR COLUMNS;

View File

@@ -0,0 +1,72 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_estimate_table_size.sql
--
-- Purpose: Estimate Table Size
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_estimate_table_size.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;
PRO
PRO 1. Enter Table Name:
DEF table_name = '&1.';
UNDEF 1;
--
COL schema_name NEW_V schema_name NOPRI;
SELECT owner AS schema_name FROM dba_tables WHERE table_name = '&&table_name.';
--
VAR v_used_bytes NUMBER;
VAR v_alloc_bytes NUMBER;
DECLARE
l_rec dba_tables%ROWTYPE;
BEGIN
SELECT * INTO l_rec FROM dba_tables WHERE owner = '&&schema_name.' AND table_name = '&&table_name.';
--
IF l_rec.tablespace_name IS NULL THEN
SELECT MAX(tablespace_name)
INTO l_rec.tablespace_name
FROM dba_segments
WHERE owner = '&&schema_name.'
AND segment_name = '&&table_name.'
AND segment_type LIKE 'TABLE%';
END IF;
--
DBMS_SPACE.create_table_cost (
tablespace_name => l_rec.tablespace_name,
avg_row_size => l_rec.avg_row_len,
row_count => l_rec.num_rows,
pct_free => l_rec.pct_free,
used_bytes => :v_used_bytes,
alloc_bytes => :v_alloc_bytes
);
END;
/
COL used_gb FOR 999,990.000;
COL alloc_gb FOR 999,990.000;
SELECT :v_used_bytes/1e9 AS used_gb, :v_alloc_bytes/1e9 AS alloc_gb FROM DUAL;
--
ROLLBACK;
DELETE plan_table;
BEGIN
EXECUTE IMMEDIATE('EXPLAIN PLAN FOR CREATE TABLE &&schema_name..&&table_name._ AS SELECT * FROM &&schema_name..&&table_name.');
END;
/
COMMIT;
SET HEA ON PAGES 0;
PRO
SELECT plan_table_output FROM
TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', NULL, 'ADVANCED'))
/
SET HEA ON PAGES 100;
CLEAR COLUMNS;

261
csierra/cs_extents_map.sql Normal file
View File

@@ -0,0 +1,261 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_extents_map.sql
--
-- Purpose: Tablespace Block Map
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to PDB.
--
-- Parameters: 1. Tablespace Name
--
-- 2. Grouping
--
-- [{SEGMENT}|S|PARTITION|P]
--
-- 3. Coalesce (on Map) Contiguos Extents of same Grouping
--
-- [{Y}|N]
--
-- 4. Smallest BLOCK_ID on Top (of Map) or at the Bottom
--
-- [{BOTTOM}|B|TOP|T]
--
-- Example(s): $ sqlplus / as sysdba
-- SQL> @cs_extents_map.sql "KIEV" "PARTITION" "Y" "BOTTOM"
-- SQL> @cs_extents_map.sql "KIEV" "P" "Y" "B"
-- SQL> @cs_extents_map.sql KIEV S N T
--
-- Notes: Source: https://oraboard.wordpress.com/2016/04/22/tablespace-block-map/
--
-- 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_extents_map';
--
--@@cs_internal/&&cs_set_container_to_cdb_root.
--
SELECT tablespace_name
FROM dba_tablespaces
WHERE contents = 'PERMANENT'
ORDER BY 1
/
PRO
PRO 1. Tablespace Name:
DEF cs_tablespace_name = '&1.';
UNDEF 1;
PRO
PRO 2. Grouping: [{SEGMENT}|S|PARTITION|P]
DEF cs_grouping = '&2.';
UNDEF 2;
COL cs_grouping NEW_V cs_grouping NOPRI;
SELECT CASE WHEN UPPER(NVL('&&cs_grouping.', 'SEGMENT')) LIKE '%P%' THEN 'PARTITION' ELSE 'SEGMENT' END AS cs_grouping FROM DUAL
/
PRO
PRO 3. Coalesce (on Map) Contiguos Extents of same Grouping (&&cs_grouping.): [{Y}|N]
DEF cs_coalesce_contiguous_extents = '&3.';
UNDEF 3;
COL cs_coalesce_contiguous_extents NEW_V cs_coalesce_contiguous_extents NOPRI;
SELECT CASE SUBSTR(UPPER(TRIM(NVL('&&cs_coalesce_contiguous_extents.', 'Y'))), 1, 1) WHEN 'N' THEN 'N' ELSE 'Y' END AS cs_coalesce_contiguous_extents FROM DUAL
/
PRO
PRO 4. Smallest BLOCK_ID on Top (of Map) or at the Bottom: [{BOTTOM}|B|TOP|T]
DEF cs_top_or_bottom = '&4.';
UNDEF 4;
COL cs_top_or_bottom NEW_V cs_top_or_bottom NOPRI;
SELECT CASE SUBSTR(UPPER(TRIM(NVL('&&cs_top_or_bottom.', 'BOTTOM'))), 1, 1) WHEN 'T' THEN 'TOP' ELSE 'BOTTOM' END AS cs_top_or_bottom FROM DUAL
/
--
SELECT '&&cs_file_prefix._&&cs_script_name._&&cs_tablespace_name.' cs_file_name FROM DUAL;
--
DEF report_foot_note = 'SQL> @&&cs_script_name..sql "&&cs_tablespace_name." "&&cs_grouping." "&&cs_coalesce_contiguous_extents." "&&cs_top_or_bottom."';
--
SPO &&cs_file_name..html
SET HEA OFF PAGES 0 SERVEROUT ON;
DECLARE
l_rowcount NUMBER := 0;
l_group_count NUMBER := 0;
l_cellcolor VARCHAR2(10);
l_cellwidth NUMBER(3);
l_file_id NUMBER := -1;
l_datafile VARCHAR2(1024);
l_segment VARCHAR2(512);
l_prior_segment VARCHAR2(512);
l_blocks NUMBER := 0;
l_extents NUMBER := 0;
l_tot_extents NUMBER := 0;
l_block_id_from NUMBER;
l_block_id_to NUMBER;
l_group VARCHAR2(512);
l_prior_group VARCHAR2(512);
l_busy_blocks NUMBER := 0;
l_free_blocks NUMBER := 0;
l_block_size NUMBER;
l_map_row NUMBER := 0;
l_prior_file_id NUMBER;
--
PROCEDURE print_line (p_line IN VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.put_line(p_line);
END print_line;
--
PROCEDURE put_line (l_prior_file_id IN NUMBER, p_map_row IN NUMBER, p_group_count IN NUMBER, p_line IN VARCHAR2)
IS
BEGIN
INSERT INTO plan_table (statement_id, plan_id, parent_id, id, remarks) VALUES ('&&cs_file_date_time.', l_prior_file_id, p_map_row, p_group_count, p_line);
--print_line(p_line);
END put_line;
BEGIN
SELECT block_size INTO l_block_size FROM dba_tablespaces WHERE tablespace_name = '&&cs_tablespace_name.';
-- initial html
print_line('<HTML>');
print_line('<!-- $Header: &&cs_file_name..html carlos.sierra $ -->');
print_line('<style type="text/css">body {font:10pt Arial,Helvetica,Geneva,sans-serif; color:black; background:white;} pre {font:8pt monospace,Monaco,"Courier New",Courier;} font.n {font-size:8pt; font-style:italic; color:#336699;} font.f {font-size:8pt; color:#999999; border-top:1px solid #336699; margin-top:30pt;}</style>');
print_line('<style>.datafile {clear:both; font: Arial; font-size:12pt; font-weight:bold; color:#336699; margin-top:10pt; margin-bottom:10pt; padding:0px;} .blocks{ float:left; width:5px; height:5px; border:1px solid Silver; padding:5px; } </style>');
print_line('<H1 style="clear:both; font:Arial; font-size:16pt; font-weight:bold; color:#336699; border-bottom:1px solid #336699; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px; ">&&cs_tablespace_name. Tablespace Block Map </H1>');
print_line('<BODY>');
print_line('<pre>');
print_line('DATE_TIME : &&cs_date_time.Z');
print_line('REFERENCE : &&cs_reference.');
print_line('LOCALE : &&cs_realm. &&cs_region. &&cs_locale.');
print_line('DATABASE : &&cs_db_name_u. (&&cs_db_version.) STARTUP:&&cs_startup_time.');
print_line('CONTAINER : &&cs_db_name..&&cs_con_name. (&&cs_con_id.) &&cs_pdb_open_mode.');
print_line('CPU : CORES:&&cs_num_cpu_cores. THREADS:&&cs_num_cpus. COUNT:&&cs_cpu_count. ALLOTTED:&&cs_allotted_cpu. PLAN:&&cs_resource_manager_plan.');
print_line('HOST : &&cs_host_name.');
print_line('CONNECT_STRNG: &&cs_easy_connect_string.');
print_line('SCRIPT : &&cs_script_name..sql');
print_line('KIEV_VERSION : &&cs_kiev_version. (&&cs_schema_name.)');
print_line('</pre>');
print_line('<div class="datafile">');
-- open cursor
FOR l_row IN (
SELECT file_id,
block_id,
block_id + blocks - 1 AS end_block,
blocks,
owner,
segment_name,
partition_name,
segment_type
FROM dba_extents
WHERE tablespace_name = '&&cs_tablespace_name.'
UNION ALL
SELECT file_id,
block_id,
block_id + blocks - 1 AS end_block,
blocks,
'free' AS owner,
'free' AS segment_name,
NULL AS partition_name,
NULL AS segment_type
FROM dba_free_space
WHERE tablespace_name = '&&cs_tablespace_name.'
ORDER BY 1, 2
)
LOOP
l_tot_extents := l_tot_extents + 1;
IF l_row.segment_name = 'free' THEN l_free_blocks := l_free_blocks + l_row.blocks; ELSE l_busy_blocks := l_busy_blocks + l_row.blocks; END IF;
IF '&&cs_grouping.' = 'PARTITION' THEN l_segment := TRIM('.' FROM l_row.segment_name||'.'||l_row.partition_name); ELSE l_segment := l_row.segment_name; END IF;
IF '&&cs_coalesce_contiguous_extents.' = 'Y' THEN l_group := l_row.file_id||' '||l_segment; ELSE l_group := l_row.file_id||' '||l_segment||' '||l_row.block_id; END IF;
--
IF l_rowcount = 0 THEN
l_prior_segment := l_segment;
l_prior_group := l_group;
l_prior_file_id := l_row.file_id;
l_block_id_from := l_row.block_id;
END IF;
l_rowcount := l_rowcount + 1;
--
IF l_group = l_prior_group THEN
l_block_id_to := l_row.end_block;
l_blocks := l_blocks + l_row.blocks;
l_extents := l_extents + 1;
ELSE
-- max of 50 cells per row
IF mod(l_group_count,50) = 0 THEN
l_map_row := l_map_row + 1;
put_line(l_prior_file_id, l_map_row, l_group_count, '<div style="clear:both;"></div>');
l_map_row := l_map_row + 1;
END IF;
l_group_count := l_group_count + 1;
-- set cell color
IF l_prior_segment = 'free' THEN l_cellcolor := 'Azure'; ELSE l_cellcolor := 'Gray'; END IF;
-- display space cells
put_line(l_prior_file_id, l_map_row, l_group_count, '<div name="'||l_prior_segment||'" title='||'"'||l_prior_segment||','||l_blocks||'('||l_block_id_from||'-'||l_block_id_to||'),'||l_extents||'" class="blocks" style="background-color:'|| l_cellcolor||';" onClick="SetSelectionColor('''||l_prior_segment ||''')";></div>');
--
l_prior_segment := l_segment;
l_prior_group := l_group;
l_prior_file_id := l_row.file_id;
l_block_id_from := l_row.block_id;
l_block_id_to := l_row.end_block;
l_blocks := l_row.blocks;
l_extents := 1;
END IF;
END LOOP;
-- set cell color for last cell and display it
IF l_prior_segment = 'free' THEN l_cellcolor := 'Azure'; ELSE l_cellcolor := 'Gray'; END IF;
put_line(l_prior_file_id, l_map_row, l_group_count, '<div name="'||l_prior_segment||'" title='||'"'||l_prior_segment||','||l_blocks||'('||l_block_id_from||'-'||l_block_id_to||'),'||l_extents||'" class="blocks" style="background-color:'|| l_cellcolor||';" onClick="SetSelectionColor('''||l_prior_segment ||''')";></div>');
l_map_row := l_map_row + 1;
put_line(l_prior_file_id, l_map_row, l_group_count, '<div style="clear:both;"></div>');
-- process put lines
FOR i IN (SELECT plan_id AS file_id, parent_id AS map_row, id AS group_count, remarks AS line FROM plan_table WHERE statement_id = '&&cs_file_date_time.' ORDER BY plan_id, CASE '&&cs_top_or_bottom.' WHEN 'BOTTOM' THEN -1 ELSE 1 END * parent_id, id)
LOOP
-- check if a new datafile
IF i.file_id <> l_file_id THEN
l_file_id := i.file_id;
SELECT name INTO l_datafile FROM v$datafile WHERE file#=l_file_id;
print_line('<div style="clear:both; font:Arial; ">'||'File '||l_file_id||':' ||l_datafile||'</div>');
END IF;
--
print_line(i.line);
END LOOP;
-- javascript to color selected segments
print_line('<script>');
print_line('function SetSelectionColor(prm){');
print_line('var elements = document.getElementsByName(prm);');
print_line('for(var i=0; i<elements.length; i++) {');
print_line('if (elements[i].title.search(/free/i) < 0) {');
print_line('if (elements[i].style.backgroundColor == ''rgb(0, 0, 255)'') {');
print_line('elements[i].style.background=''Gray'';}');
print_line('else { ');
print_line('elements[i].style.background=''#0000FF''; }}}}');
print_line('</script>');
-- closing html tags
print_line('</div>');
print_line('<font class="n"><br>Notes:</font>');
print_line('<font class="n"><br>1. Total Extents on &&cs_tablespace_name. Tablespace:'||l_tot_extents||'. Total Blocks:'||(l_busy_blocks + l_free_blocks)||'('||ROUND((l_busy_blocks + l_free_blocks) * l_block_size / POWER(10,9), 1)||'GB). Busy Blocks:'||l_busy_blocks||'('||ROUND(l_busy_blocks * l_block_size / POWER(10,9), 1)||'GB). Free Blocks:'||l_free_blocks||'('||ROUND(l_free_blocks * l_block_size / POWER(10,9), 1)||'GB). Space utilization:'||ROUND(100 * l_busy_blocks / (l_busy_blocks + l_free_blocks), 1)||'%</font>');
print_line('<font class="n"><br>2. The Azure squares are those free, the Gray ones are those busy, and the Blue ones are those selected by you (with a click on a Grey square).</font>');
print_line('<font class="n"><br>3. If you click on a Gray square corresponding to a Group (&&cs_grouping.), it will Blue all other Extents in all datafiles belonging to that Group. Click again to reset.</font>');
print_line('<font class="n"><br>4. A tooltip appears on hover with: Group (&&cs_grouping.), number of blocks, blocks range, and number of extents. E.g.: TABLE_NAME,blocks(block_id_from-block_id_to),extents.</font>');
print_line('<font class="n"><br>5. The smallest BLOCK_ID is at the &&cs_top_or_bottom. of the Map (on the left-most square).</font>');
IF '&&cs_coalesce_contiguous_extents.' = 'Y' THEN print_line('<font class="n"><br>6. Contiguous Extents belonging to the same Grouping (&&cs_grouping.) have been Coalesced on this Map.</font>'); END IF;
print_line('<font class="f"><br><br>&&report_foot_note.</font>');
print_line('</BODY>');
print_line('</HTML>');
END;
/
SET HEA ON PAGES 100 SERVEROUT OFF;
PRO <pre>
L 59 80
PRO </pre>
--
@@cs_internal/cs_spool_tail_chart.sql
ROLLBACK;
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,81 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_foreign_key_fk_constraints_missing_indexes.sql
--
-- Purpose: Generate DDL to create missing Indexes to support FK constraints
--
-- Author: Carlos Sierra
--
-- Version: 2022/05/04
--
-- Usage: Execute connected to PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_foreign_key_fk_constraints_missing_indexes.sql
--
-- Notes: https://andrewfraserdba.com/2017/03/10/oracle-foreign-key-constraints-with-missing-indexes/
-- https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4530093713805#26568859366976
--
---------------------------------------------------------------------------------------
--
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;
SET HEA OFF PAGES 0;
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF3';
--
COL ddl_statement FOR A300;
--
WITH cons AS (
SELECT c.owner
, c.table_name
, c.constraint_name
, c.r_owner
, MAX ( CASE cc.position WHEN 1 THEN cc.column_name END ) AS cname1
, MAX ( CASE cc.position WHEN 2 THEN cc.column_name END ) AS cname2
, MAX ( CASE cc.position WHEN 3 THEN cc.column_name END ) AS cname3
, MAX ( CASE cc.position WHEN 4 THEN cc.column_name END ) AS cname4
, MAX ( CASE cc.position WHEN 5 THEN cc.column_name END ) AS cname5
, MAX ( CASE cc.position WHEN 6 THEN cc.column_name END ) AS cname6
, MAX ( CASE cc.position WHEN 7 THEN cc.column_name END ) AS cname7
, MAX ( CASE cc.position WHEN 8 THEN cc.column_name END ) AS cname8
, COUNT(*) AS col_cnt
FROM dba_constraints c
JOIN dba_cons_columns cc ON cc.constraint_name = c.constraint_name AND cc.owner = c.owner
WHERE c.constraint_type = 'R'
AND cc.owner IN (SELECT username FROM dba_users WHERE oracle_maintained = 'N' AND common = 'NO')
GROUP BY c.table_name , c.constraint_name , c.owner , c.r_owner
) , inds AS (
SELECT cons.owner
, cons.table_name
, cons.constraint_name
, cons.r_owner
, /*LOWER*/ ( cons.cname1 || NVL2 ( cons.cname2 , ',' || cons.cname2 , NULL )
|| NVL2 ( cons.cname3 , ',' || cons.cname3 , NULL ) || NVL2 ( cname4 , ',' || cname4 , NULL )
|| NVL2 ( cons.cname5 , ',' || cons.cname5 , NULL ) || NVL2 ( cname6 , ',' || cname6 , NULL )
|| NVL2 ( cons.cname7 , ',' || cons.cname7 , NULL ) || NVL2 ( cname8 , ',' || cname8 , NULL )
) AS column_list
FROM cons
WHERE cons.col_cnt > ALL (
SELECT COUNT(*)
FROM dba_ind_columns ic
WHERE ic.table_name = cons.table_name
AND ic.table_owner = cons.owner
AND ic.column_name IN ( cons.cname1 , cons.cname2 , cons.cname3 , cons.cname4 , cons.cname5 , cons.cname6 , cons.cname7 , cons.cname8 )
AND ic.column_position <= cons.col_cnt
GROUP BY ic.index_name
)
)
SELECT
-- inds.owner
-- , inds.table_name
-- , t.num_rows
-- , t.blocks * 8/1024/1024 AS gb
-- , inds.r_owner
'/* tblocks='||t.blocks||' trows='||t.num_rows||' */ CREATE INDEX ' || inds.owner || '.' || inds.constraint_name || ' ON ' || inds.owner || '.' || inds.table_name || '(' || inds.column_list ||') ONLINE;' AS ddl_statement
FROM inds
JOIN dba_tables t ON t.table_name = inds.table_name AND t.owner = inds.owner
WHERE t.blocks > 5 AND NOT t.table_name LIKE 'KIEV%'
ORDER BY t.blocks DESC, inds.owner , inds.table_name , inds.constraint_name
/
--
SET HEA ON PAGES 100;

104
csierra/cs_fs.sql Normal file
View File

@@ -0,0 +1,104 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_fs.sql
--
-- Purpose: Find SQL statements matching some string
--
-- Author: Carlos Sierra
--
-- Version: 2023/04/14
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter string to match when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_fs.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_fs';
--
PRO 1. Search String: SQL_ID or SQL_HV or PHV or SQL_TEXT piece: (e.g.: ScanQuery, getValues, TableName, IndexName, Scan%Instances)
DEF cs_search_string = '&1.';
UNDEF 1;
COL cs_search_string NEW_V cs_search_string NOPRI;
SELECT /* &&cs_script_name. */ TRIM('&&cs_search_string.') AS cs_search_string FROM DUAL
/
--
PRO
PRO 2. Days for AWR search?: [{0}|0-61] *** note: awr search is slow! ***
DEF cs_awr_search_days = '&2.';
UNDEF 2;
COL cs_awr_search_days NEW_V cs_awr_search_days NOPRI;
SELECT CASE WHEN TO_NUMBER('&&cs_awr_search_days.') BETWEEN 0 AND 61 THEN TRIM('&&cs_awr_search_days.') ELSE '0' END AS cs_awr_search_days FROM DUAL
/
COL cs_min_snap_id NEW_V cs_min_snap_id NOPRI;
SELECT TRIM(TO_CHAR(NVL(MAX(snap_id), 0))) AS cs_min_snap_id FROM dba_hist_snapshot WHERE end_interval_time < SYSDATE - TO_NUMBER('&&cs_awr_search_days.')
/
--
PRO
PRO 3. Include SYS Parsing Schema?: [{N}|N,Y]
DEF cs_include_sys = '&3.';
UNDEF 3;
COL cs_include_sys NEW_V cs_include_sys NOPRI;
SELECT CASE WHEN UPPER(TRIM('&&cs_include_sys.')) IN ('N', 'Y') THEN UPPER(TRIM('&&cs_include_sys.')) ELSE 'N' END AS cs_include_sys FROM DUAL
/
--
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_search_string." "&&cs_awr_search_days." "&&cs_include_sys."
@@cs_internal/cs_spool_id.sql
--
PRO SEARCH_STRING: "&&cs_search_string."
PRO AWR_DAYS: "&&cs_awr_search_days."
PRO INCLUDE_SYS: "&&cs_include_sys."
--
-- 1 gv$sql - sql statistics
--
DEF cs_sql_id_col = 'PRI';
DEF cs_uncommon_col = 'NOPRI';
DEF cs_delta_col = 'NOPRI';
DEF cs_execs_delta_h = '&&cs_last_snap_mins. mins';
@@cs_internal/cs_latency_internal_cols.sql
@@cs_internal/cs_fs_internal_query_1.sql
--
-- 2 v$sqlstats - sql statistics
--
@@cs_internal/cs_latency_internal_cols.sql
CLEAR BREAK;
@@cs_internal/cs_fs_internal_query_2.sql
--
-- 3 dba_hist_sqlstat - sql statistics
--
DEF cs_execs_delta_h = 'whole history';
@@cs_internal/cs_latency_internal_cols.sql
COL begin_timestamp FOR A23 HEA 'Begin Timestamp' PRI;
COL end_timestamp FOR A23 HEA 'End Timestamp' PRI;
CLEAR BREAK;
@@cs_internal/cs_fs_internal_query_3.sql
--
-- 4 v$sqlstats - sql text
--
@@cs_internal/cs_fs_internal_query_4.sql
--
-- 5 dba_hist_sqltext - sql text
--
@@cs_internal/cs_fs_internal_query_5.sql
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_search_string." "&&cs_awr_search_days." "&&cs_include_sys."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,32 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_hanganalyze.sql
--
-- Purpose: Generate Hanganalyze Trace
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_hanganalyze.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
ALTER SESSION SET tracefile_identifier = 'iod_hanganalyze';
COL trace_file NEW_V trace_file;
SELECT value trace_file FROM v$diag_info WHERE name = 'Default Trace File';
oradebug setmypid
oradebug unlimit
oradebug hanganalyze 3
oradebug hanganalyze 3
oradebug hanganalyze 3
oradebug hanganalyze 3
oradebug hanganalyze 3
oradebug hanganalyze 3
oradebug tracefile_name
HOS cp &&trace_file. /tmp

View File

@@ -0,0 +1,50 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_hexdump_to_timestamp.sql
--
-- Purpose: Convert Hexadecimal Dump to Time
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/06
--
-- Usage: Execute connected to CDB or PDB.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_hexdump_to_timestamp.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
DEF timestamp_as_hexdump = '&1.';
--
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';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF6';
--
COL time FOR A20;
COL timestamp FOR A30;
--
WITH
FUNCTION get_date (p_hexdump IN VARCHAR2)
RETURN DATE
IS
l_date DATE;
BEGIN
DBMS_STATS.convert_raw_value(rawval => HEXTORAW(p_hexdump), resval => l_date);
RETURN l_date;
END get_date;
FUNCTION get_timestamp (p_hexdump IN VARCHAR2)
RETURN TIMESTAMP
IS
BEGIN
RETURN
TO_TIMESTAMP(
TO_CHAR(get_date(p_hexdump), 'YYYY-MM-DD"T"HH24:MI:SS')||
ROUND(TO_NUMBER(SUBSTR('&&timestamp_as_hexdump.', LENGTH('&&timestamp_as_hexdump.') - 7), 'XXXXXXXX')/POWER(10,9), 6),
'YYYY-MM-DD"T"HH24:MI:SS.FF6');
END get_timestamp;
SELECT get_date('&&timestamp_as_hexdump.') AS time, get_timestamp('&&timestamp_as_hexdump.') AS timestamp FROM DUAL
/
--

View File

@@ -0,0 +1,158 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_high_execution_rate_rps.sql
--
-- Purpose: List executions by time for a given SQL_ID with high RPS
--
-- Author: Carlos Sierra
--
-- Version: 2023/04/27
--
-- Usage: Execute connected to PDB.
--
-- Enter SQL_ID when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_high_execution_rate_rps.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_high_execution_rate_rps';
--
PRO 1. SQL_ID:
DEF cs_sql_id = '&1.';
UNDEF 1;
--
PRO
PRO 2. Seconds: [{1}|1-60]
DEF cs_seconds = '&2.';
UNDEF 2;
COL cs_seconds NEW_V cs_seconds NOPRI;
SELECT CASE WHEN TO_NUMBER('&&cs_seconds.') BETWEEN 1 AND 60 THEN '&&cs_seconds.' ELSE '1' END AS cs_seconds FROM DUAL
/
--
@@cs_internal/cs_last_snap.sql
--
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_seconds."
@@cs_internal/cs_spool_id.sql
@@cs_internal/cs_spool_id_list_sql_id.sql
--
PRO SECONDS : &&cs_seconds.
--
@@cs_internal/cs_print_sql_text.sql
PRO
PRO Samples (v$sqlstats)
PRO ~~~~~~~
SET SERVEROUT ON;
DECLARE
l_begin_timestamp TIMESTAMP(6) := SYSTIMESTAMP;
l_exit_timestamp TIMESTAMP(6) := l_begin_timestamp + INTERVAL '&&cs_seconds.' SECOND;
l_timestamp TIMESTAMP(6);
l_parse_calls NUMBER;
l_executions NUMBER;
l_rows_processed NUMBER;
l_us_delta NUMBER;
l_parse_calls_total NUMBER := 0;
l_executons_total NUMBER := 0;
l_rows_processed_total NUMBER := 0;
l_us_total NUMBER := 0;
l_parse_calls_delta NUMBER;
l_executions_delta NUMBER;
l_rows_processed_delta NUMBER;
l_timestamp_prior TIMESTAMP(6) := l_begin_timestamp;
l_parse_calls_prior NUMBER;
l_executions_prior NUMBER;
l_rows_processed_prior NUMBER;
l_timestamp_zero_begin TIMESTAMP(6) := l_begin_timestamp;
l_timestamp_zero_end TIMESTAMP(6);
l_us_delta_zero NUMBER;
l_samples_zero NUMBER := 0;
l_samples_total NUMBER := 0;
BEGIN
WHILE SYSTIMESTAMP < l_exit_timestamp
LOOP
SELECT parse_calls, executions, rows_processed INTO l_parse_calls, l_executions, l_rows_processed FROM v$sqlstats WHERE sql_id = '&&cs_sql_id.';
l_timestamp := SYSTIMESTAMP;
l_us_delta := ((86400 * EXTRACT(DAY FROM (l_timestamp - l_timestamp_prior)) + (3600 * EXTRACT(HOUR FROM (l_timestamp - l_timestamp_prior))) + (60 * EXTRACT(MINUTE FROM (l_timestamp - l_timestamp_prior))) + EXTRACT(SECOND FROM (l_timestamp - l_timestamp_prior)))) * 1e6;
l_parse_calls_delta := l_parse_calls - l_parse_calls_prior;
l_executions_delta := l_executions - l_executions_prior;
l_rows_processed_delta := l_rows_processed - l_rows_processed_prior;
l_samples_total := l_samples_total + 1;
IF l_us_delta > 0 THEN
l_us_total := l_us_total + l_us_delta;
l_parse_calls_total := NVL(l_parse_calls_total, 0) + l_parse_calls_delta;
l_executons_total := NVL(l_executons_total, 0) + l_executions_delta;
l_rows_processed_total := NVL(l_rows_processed_total, 0) + l_rows_processed_delta;
END IF;
--
IF l_parse_calls_delta > 0 OR l_executions_delta > 0 OR l_rows_processed_delta > 0 THEN
IF l_timestamp_zero_begin IS NOT NULL AND l_timestamp_zero_end IS NOT NULL THEN
l_us_delta_zero := ((86400 * EXTRACT(DAY FROM (l_timestamp_zero_end - l_timestamp_zero_begin)) + (3600 * EXTRACT(HOUR FROM (l_timestamp_zero_end - l_timestamp_zero_begin))) + (60 * EXTRACT(MINUTE FROM (l_timestamp_zero_end - l_timestamp_zero_begin))) + EXTRACT(SECOND FROM (l_timestamp_zero_end - l_timestamp_zero_begin)))) * 1e6;
DBMS_OUTPUT.put_line (
RPAD(TO_CHAR(l_timestamp_zero_begin, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||' - '||
RPAD(TO_CHAR(l_timestamp_zero_end, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||
LPAD(TO_CHAR(l_us_delta_zero, '999,999,990'), 12, ' ')||' us'||
LPAD(TO_CHAR(0, '999,990'), 8, ' ')||' parses'||
LPAD(TO_CHAR(0, '999,990'), 8, ' ')||' executions'||
LPAD(TO_CHAR(0, '999,999,990'), 12, ' ')||' rows'||
LPAD(TO_CHAR(l_samples_zero, '9,999,990'), 10, ' ')||' samples'
);
END IF;
--
IF l_timestamp_prior IS NOT NULL AND l_timestamp IS NOT NULL THEN
DBMS_OUTPUT.put_line (
RPAD(TO_CHAR(l_timestamp_prior, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||' - '||
RPAD(TO_CHAR(l_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||
LPAD(TO_CHAR(l_us_delta, '999,999,990'), 12, ' ')||' us'||
LPAD(TO_CHAR(l_parse_calls_delta, '999,990'), 8, ' ')||' parses'||
LPAD(TO_CHAR(l_executions_delta, '999,990'), 8, ' ')||' executions'||
LPAD(TO_CHAR(l_rows_processed_delta, '999,999,990'), 12, ' ')||' rows'
);
END IF;
l_timestamp_zero_begin := l_timestamp;
l_timestamp_zero_end := NULL;
l_samples_zero := 0;
ELSE
l_timestamp_zero_end := l_timestamp;
l_samples_zero := NVL(l_samples_zero, 0) + 1;
END IF;
--
l_timestamp_prior := l_timestamp;
l_parse_calls_prior := l_parse_calls;
l_executions_prior := l_executions;
l_rows_processed_prior := l_rows_processed;
END LOOP;
--
DBMS_OUTPUT.put_line('---');
DBMS_OUTPUT.put_line (
RPAD(TO_CHAR(l_begin_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||' - '||
RPAD(TO_CHAR(l_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'), 26, ' ')||
LPAD(TO_CHAR(l_us_total, '999,999,990'), 12, ' ')||' us'||
LPAD(TO_CHAR(l_parse_calls_total, '999,990'), 8, ' ')||' parses'||
LPAD(TO_CHAR(l_executons_total, '999,990'), 8, ' ')||' executions'||
LPAD(TO_CHAR(l_rows_processed_total, '999,999,990'), 12, ' ')||' rows'||
LPAD(TO_CHAR(l_samples_total, '9,999,990'), 10, ' ')||' samples'
);
END;
/
SET SERVEROUT OFF;
--
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sql_id." "&&cs_seconds."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,114 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_index_part_reorg.sql
--
-- Purpose: Calculate index reorg savings
--
-- Author: Rodrigo Righetti
--
-- Version: 2019/04/16
--
-- Usage: Execute connected to PDB.
--
-- Enter Owner, Table and Index when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_index_part_reorg.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
col partition_name for a20
set pages 67
set lines 150
PRO 1. Table Owner:
DEF table_owner = '&1.';
SELECT DISTINCT UPPER(owner) table_owner
FROM dba_tables
WHERE owner = UPPER(TRIM('&&table_owner.'))
/
PRO 2. Table Name:
DEF table_name = '&2.';
SELECT DISTINCT UPPER(table_name) table_name
FROM dba_tables
WHERE table_name = UPPER(TRIM('&&table_name.'))
/
PRO 3. Index Name:
DEF index_name = '&3.';
SELECT DISTINCT UPPER(index_name) index_name
FROM dba_indexes
WHERE index_name = UPPER(TRIM('&&index_name.'))
/
WITH ca AS (
SELECT /*+ MATERIALIZE */
SUM(avg_col_len) actual_size,
SUM(avg_col_len) * 1.25 est_size
FROM
dba_tab_columns
WHERE
table_name = '&&table_name.'
and owner = '&&table_owner.'
AND column_name IN (
SELECT
column_name
FROM
dba_ind_columns
WHERE
index_name = '&&index_name.'
)
), ps AS (
SELECT /*+ MATERIALIZE */
partition_name,
round(bytes / POWER(2,20), 2) size_mb
FROM
dba_segments
WHERE
segment_name = '&&index_name.'
), pr AS (
SELECT /*+ MATERIALIZE */
partition_name,
num_rows
FROM
dba_ind_partitions
WHERE
index_name = '&&index_name.'
)
SELECT
*
FROM
(
SELECT
pr.partition_name,
pr.num_rows,
ps.size_mb,
round((ca.actual_size * pr.num_rows) / POWER(2,20), 2) est_used_size_mb,
round((ca.est_size * pr.num_rows) / POWER(2,20), 2) est_rebuild_size_mb,
round((1 -(((ca.est_size * pr.num_rows) / POWER(2,20)) / ps.size_mb)) * 100, 2) savings_pct
FROM
pr,
ps,
ca
WHERE
pr.partition_name = ps.partition_name
ORDER BY
round((1 -(((ca.est_size * pr.num_rows) / POWER(2,20)) / ps.size_mb)) * 100, 2)
)
UNION ALL
SELECT
'TOTAL',
SUM(pr.num_rows) num_rows,
SUM(ps.size_mb) size_mb,
SUM(round((ca.actual_size * pr.num_rows) / POWER(2,20), 2)) est_used_size_mb,
SUM(round((ca.est_size * pr.num_rows) / POWER(2,20), 2)) est_rebuild_size_mb,
round((1 -(SUM(round((ca.est_size * pr.num_rows) / POWER(2,20), 2)) / SUM(ps.size_mb))) * 100, 2) savings_pct
FROM
pr,
ps,
ca
WHERE
pr.partition_name = ps.partition_name;

View File

@@ -0,0 +1,142 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_index_rebuild_hist_report.sql
--
-- Purpose: Index Rebuild History (IOD_REPEATING_SPACE_MAINTENANCE log)
--
-- Author: Carlos Sierra
--
-- Version: 2020/12/25
--
-- Usage: Execute connected to CDB or PDB.
--
-- Enter range of dates, and Table when requested.
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_index_rebuild_hist_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_index_rebuild_hist_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
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL owner FOR A30 TRUNC;
SELECT DISTINCT h.owner
FROM &&cs_tools_schema..index_rebuild_hist h,
cdb_users u
WHERE '&&cs_con_name.' IN ('CDB$ROOT', h.pdb_name)
AND (h.ddl_begin_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') OR
h.ddl_end_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.'))
AND u.con_id = h.con_id
AND u.username = h.owner
AND u.oracle_maintained = 'N'
AND u.username NOT LIKE 'C##'||CHR(37)
ORDER BY 1
/
PRO
PRO 3. Index Owner (opt):
DEF cs2_index_owner = '&3.';
UNDEF 3;
COL cs2_index_owner NEW_V cs2_index_owner NOPRI;
SELECT UPPER(TRIM('&&cs2_index_owner.')) cs2_index_owner FROM DUAL
/
--
COL index_name FOR A30 TRUNC;
SELECT DISTINCT h.index_name
FROM &&cs_tools_schema..index_rebuild_hist h,
cdb_users u
WHERE '&&cs_con_name.' IN ('CDB$ROOT', h.pdb_name)
AND h.owner = COALESCE('&&cs2_index_owner.', h.owner)
AND (h.ddl_begin_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') OR
h.ddl_end_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.'))
AND u.con_id = h.con_id
AND u.username = h.owner
AND u.oracle_maintained = 'N'
AND u.username NOT LIKE 'C##'||CHR(37)
ORDER BY 1
/
PRO
PRO 4. Index Name (opt):
DEF cs2_index_name = '&4.';
UNDEF 4;
COL cs2_index_name NEW_V cs2_index_name NOPRI;
SELECT UPPER(TRIM('&&cs2_index_name.')) cs2_index_name FROM DUAL;
--
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." "&&cs2_index_owner." "&&cs2_index_name."
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/cs_spool_id_sample_time.sql
--
PRO INDEX_OWNER : "&&cs2_index_owner."
PRO INDEX_NAME : "&&cs2_index_name."
--
COL ddl_begin_time FOR A19;
COL ddl_end_time FOR A19;
COL seconds FOR 999,990 HEA 'DDL|SECONDS';
COL pdb_name FOR A30 TRUNC;
COL owner FOR A30 TRUNC;
COL index_name FOR A30 TRUNC;
COL size_mbs_before FOR 999,990.0 HEA 'SIZE_MBs|BEFORE';
COL size_mbs_after FOR 999,990.0 HEA 'SIZE_MBs|AFTER';
COL savings FOR 999,990.0 HEA 'SAVINGS|MBs';
COL perc FOR 999,990.0 HEA 'SAVINGS|PERC%';
COL ddl_statement FOR A100 TRUNC;
COL error_message FOR A100 TRUNC;
BREAK ON REPORT;
COMPUTE SUM LABEL 'TOTAL' OF seconds size_mbs_before size_mbs_after savings ON REPORT;
--
SELECT TO_CHAR(h.ddl_begin_time, '&&cs_datetime_full_format.') AS ddl_begin_time,
TO_CHAR(h.ddl_end_time, '&&cs_datetime_full_format.') AS ddl_end_time,
ROUND((h.ddl_end_time - h.ddl_begin_time) * 24 * 3600) AS seconds,
h.pdb_name,
h.owner,
h.index_name,
h.size_mbs_before,
h.size_mbs_after,
(h.size_mbs_before - h.size_mbs_after) AS savings,
ROUND(100 * (h.size_mbs_before - h.size_mbs_after) / NULLIF(h.size_mbs_before, 0), 1) AS perc,
h.ddl_statement,
h.error_message
FROM &&cs_tools_schema..index_rebuild_hist h,
cdb_users u
WHERE '&&cs_con_name.' IN ('CDB$ROOT', h.pdb_name)
AND h.owner = COALESCE('&&cs2_index_owner.', h.owner)
AND h.index_name = COALESCE('&&cs2_index_name.', h.index_name)
AND (h.ddl_begin_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.') OR
h.ddl_end_time BETWEEN TO_DATE('&&cs_sample_time_from.', '&&cs_datetime_full_format.') AND TO_DATE('&&cs_sample_time_to.', '&&cs_datetime_full_format.'))
AND u.con_id = h.con_id
AND u.username = h.owner
AND u.oracle_maintained = 'N'
AND u.username NOT LIKE 'C##'||CHR(37)
ORDER BY
h.snap_time,
h.ddl_begin_time
/
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
PRO
PRO SQL> @&&cs_script_name..sql "&&cs_sample_time_from." "&&cs_sample_time_to." "&&cs2_index_owner." "&&cs2_index_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
--

199
csierra/cs_index_usage.sql Normal file
View File

@@ -0,0 +1,199 @@
----------------------------------------------------------------------------------------
--
-- File name: cs_index_usage.sql
--
-- Purpose: Index Usage (is an index still in use?)
--
-- Author: Carlos Sierra
--
-- Version: 2023/01/09
--
-- Usage: Execute connected to PDB
--
-- Enter owner, table and index
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_index_usage.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_index_usage';
--
COL username FOR A30;
SELECT username
FROM dba_users
WHERE oracle_maintained = 'N'
AND common = 'NO'
ORDER BY
username
/
PRO
PRO 1. Table Owner:
DEF table_owner = '&1.';
UNDEF 1;
COL p_owner NEW_V p_owner FOR A30 NOPRI;
SELECT username AS p_owner
FROM dba_users
WHERE oracle_maintained = 'N'
AND common = 'NO'
AND username = UPPER(TRIM('&&table_owner.'))
AND ROWNUM = 1
/
--
COL table_name FOR A30;
SELECT table_name, blocks, num_rows
FROM dba_tables
WHERE owner = '&&p_owner.'
ORDER BY
table_name
/
PRO
PRO 2. Table Name:
DEF table_name = '&2.';
UNDEF 2;
COL p_table_name NEW_V p_table_name NOPRI;
SELECT table_name AS p_table_name
FROM dba_tables
WHERE owner = '&&p_owner.'
AND table_name = UPPER(TRIM('&&table_name.'))
AND ROWNUM = 1
/
--
COL index_name FOR A30;
SELECT index_name, leaf_blocks
FROM dba_indexes
WHERE owner = '&&p_owner.'
AND table_name = '&&p_table_name.'
ORDER BY
index_name
/
PRO
PRO 3. Index Name:
DEF index_name = '&3.'
UNDEF 3;
DEF p_index_name = '';
COL p_index_name NEW_V p_index_name NOPRI;
SELECT index_name AS p_index_name
FROM dba_indexes
WHERE owner = '&&p_owner.'
AND table_name = '&&p_table_name.'
AND index_name = UPPER(TRIM('&&index_name.'))
AND ROWNUM = 1
/
--
SELECT '&&cs_file_prefix._&&cs_script_name._&&p_owner..&&p_table_name..&&p_index_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql "&&p_owner." "&&p_table_name." "&&p_index_name."
@@cs_internal/cs_spool_id.sql
--
PRO TABLE_OWNER : "&&p_owner."
PRO TABLE_NAME : "&&p_table_name."
PRO INDEX_NAME : "&&p_index_name."
--
COL index_name FOR A30;
COL plan_hash_value FOR 999999999999999;
COL executions FOR 999,999,999,990;
COL elapsed_seconds FOR 999,999,990;
COL cpu_seconds FOR 999,999,990;
COL sql_text FOR A100 TRUNC;
BREAK ON REPORT;
COMPUTE SUM LABEL "TOTAL" OF executions elapsed_seconds cpu_seconds ON REPORT;
PRO
PRO v$object_dependency -> v$sql
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT d.to_name AS index_name, s.sql_id, s.plan_hash_value, s.sql_text,
s.executions, s.elapsed_seconds, s.cpu_seconds, s.last_active_time
FROM ( SELECT d.to_name, d.from_hash, d.from_address
FROM v$object_dependency d, v$db_object_cache c
WHERE d.to_owner = '&&p_owner.'
AND d.to_name = NVL('&&p_index_name.', d.to_name)
--AND d.to_type = 70 -- MULTI-VERSIONED OBJECT
AND d.to_name IN (SELECT index_name FROM dba_indexes WHERE owner = '&&p_owner.' AND table_name = '&&p_table_name.')
AND c.hash_value = d.to_hash
AND c.addr = d.to_address
AND c.type = 'MULTI-VERSIONED OBJECT'
GROUP BY d.to_name, d.from_hash, d.from_address
) d
CROSS APPLY (
SELECT s.sql_id, s.sql_text, s.plan_hash_value,
SUM(s.executions) AS executions,
ROUND(SUM(s.elapsed_time)/POWER(10, 6)) AS elapsed_seconds,
ROUND(SUM(s.cpu_time)/POWER(10, 6)) AS cpu_seconds,
MAX(s.last_active_time) AS last_active_time
FROM v$sql s
WHERE s.hash_value = d.from_hash
AND s.address = d.from_address
-- AND s.parsing_user_id <> 0
-- AND s.parsing_schema_id <> 0
GROUP BY
s.sql_id, s.sql_text, s.plan_hash_value
) s
ORDER BY
d.to_name, s.sql_id, s.plan_hash_value
/
PRO
PRO v$sql_plan -> v$sql
PRO ~~~~~~~~~~~~~~~~~~~
SELECT p.object_name AS index_name, p.sql_id, p.plan_hash_value, s.sql_text,
s.executions, s.elapsed_seconds, s.cpu_seconds, s.last_active_time
FROM ( SELECT p.object_name, p.sql_id, p.plan_hash_value
FROM v$sql_plan p
WHERE p.object_owner = '&&p_owner.'
AND p.object_name = NVL('&&p_index_name.', p.object_name)
AND p.object_type LIKE '%INDEX%'
AND p.object_name IN (SELECT index_name FROM dba_indexes WHERE owner = '&&p_owner.' AND table_name = '&&p_table_name.')
GROUP BY p.object_name, p.sql_id, p.plan_hash_value
) p
CROSS APPLY (
SELECT MAX(s.sql_text) AS sql_text,
SUM(s.executions) AS executions,
ROUND(SUM(s.elapsed_time)/POWER(10, 6)) AS elapsed_seconds,
ROUND(SUM(s.cpu_time)/POWER(10, 6)) AS cpu_seconds,
MAX(s.last_active_time) AS last_active_time
FROM v$sql s
WHERE s.sql_id = p.sql_id
AND s.plan_hash_value = p.plan_hash_value
-- AND s.parsing_user_id <> 0
-- AND s.parsing_schema_id <> 0
) s
ORDER BY
p.object_name, s.sql_id, s.plan_hash_value
/
PRO
PRO dba_hist_sql_plan -> dba_hist_sqltext
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT p.object_name AS index_name, p.sql_id, p.plan_hash_value, s.sql_text, p.timestamp
FROM ( SELECT p.object_name, p.sql_id, p.plan_hash_value, MAX(timestamp) AS timestamp
FROM dba_hist_sql_plan p
WHERE p.object_owner = '&&p_owner.'
AND p.object_name = NVL('&&p_index_name.', p.object_name)
AND p.object_type LIKE '%INDEX%'
AND p.dbid = TO_NUMBER('&&cs_dbid.')
AND p.object_name IN (SELECT index_name FROM dba_indexes WHERE owner = '&&p_owner.' AND table_name = '&&p_table_name.')
GROUP BY p.object_name, p.sql_id, p.plan_hash_value
) p
CROSS APPLY (
SELECT MAX(DBMS_LOB.SUBSTR(s.sql_text, 1000)) AS sql_text
FROM dba_hist_sqltext s
WHERE s.sql_id = p.sql_id
) s
ORDER BY
p.object_name, p.sql_id, p.plan_hash_value
/
--
PRO
PRO SQL> @&&cs_script_name..sql "&&p_owner." "&&p_table_name." "&&p_index_name."
--
@@cs_internal/cs_spool_tail.sql
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--

View File

@@ -0,0 +1,88 @@
COL con_id FOR 999 HEA 'Con|ID';
COL pdb_name FOR A30 HEA 'PDB Name' FOR A30 TRUNC;
COL last_active_time FOR A19 HEA 'Last Active Time';
COL child_number FOR 999999 HEA 'Child|Number';
COL plan_hash_value FOR 9999999999 HEA 'Plan|Hash Value';
COL object_status FOR A14 HEA 'Object|Status';
COL is_obsolete FOR A8 HEA 'Is|Obsolete';
COL is_shareable FOR A9 HEA 'Is|Shareable';
COL is_bind_aware FOR A9 HEA 'Is Bind|Aware';
COL is_bind_sensitive FOR A9 HEA 'Is Bind|Sensitive';
COL bucket_id FOR 999999 HEA 'Bucket|ID';
COL count FOR 999999 HEA 'Count';
COL predicate FOR A20 HEA 'Predicate';
COL range_id FOR 99999 HEA 'Range|ID';
COL low HEA 'Low';
COL high HEA 'High';
COL high_low_avg HEA 'AVG' FOR A10;
--
BREAK ON con_id DUPL ON pdb_name DUPL ON last_active_time DUPL ON child_number SKIP 1 DUPL;
PRO
PRO ACS HISTOGRAM (v$sql_cs_histogram)
PRO ~~~~~~~~~~~~~
SELECT h.con_id,
c.name AS pdb_name,
TO_CHAR(s.last_active_time, '&&cs_datetime_full_format.') last_active_time,
h.child_number,
h.bucket_id,
h.count,
s.object_status,
s.is_obsolete,
s.is_shareable,
s.is_bind_sensitive,
s.is_bind_aware,
s.plan_hash_value
FROM v$sql_cs_histogram h,
v$sql s,
v$containers c
WHERE h.sql_id = '&&cs_sql_id.'
AND s.sql_id = h.sql_id
AND s.child_number = h.child_number
AND s.con_id = h.con_id
AND c.con_id = h.con_id
ORDER BY
h.con_id,
s.last_active_time,
h.child_number,
h.bucket_id
/
--
/* v$sql_cs_statistics not populated on 12c as per bug 24441377 */
--
BREAK ON con_id DUPL ON pdb_name DUPL ON last_active_time DUPL ON child_number SKIP 1 DUPL;
PRO
PRO ACS SELECTIVITY PROFILE (v$sql_cs_selectivity)
PRO ~~~~~~~~~~~~~~~~~~~~~~~
SELECT l.con_id,
c.name AS pdb_name,
TO_CHAR(s.last_active_time, '&&cs_datetime_full_format.') last_active_time,
l.child_number,
l.range_id,
l.predicate,
l.low,
-- TRIM(TO_CHAR(ROUND((TO_NUMBER(l.high) + TO_NUMBER(l.low)) / 2, 6), '0.000000')) high_low_avg,
l.high,
s.object_status,
s.is_obsolete,
s.is_shareable,
s.is_bind_sensitive,
s.is_bind_aware,
s.plan_hash_value
FROM v$sql_cs_selectivity l,
v$sql s,
v$containers c
WHERE l.sql_id = '&&cs_sql_id.'
AND s.sql_id = l.sql_id
AND s.child_number = l.child_number
AND s.con_id = l.con_id
AND c.con_id = l.con_id
ORDER BY
l.con_id,
s.last_active_time,
l.child_number,
l.range_id,
l.predicate,
l.low,
l.high
/
--

View File

@@ -0,0 +1,59 @@
COL con_id FOR 999 HEA 'Con|ID';
COL pdb_name FOR A30 HEA 'PDB Name' FOR A30 TRUNC;
COL sid_serial# FOR A12 HEA 'Sid,Serial#';
COL child_number FOR 999999 HEA 'Child|Number';
COL sql_exec_start FOR A19 HEA 'SQL Exec Start';
COL elapsed_seconds FOR 999,990 HEA 'Elapsed|Seconds';
COL current_timed_event FOR A80 HEA 'Current Timed Event';
--
PRO
PRO ACTIVE SESSIONS (v$session)
PRO ~~~~~~~~~~~~~~~
SELECT s.con_id,
c.name AS pdb_name,
s.machine,
s.state||CASE WHEN s.state LIKE 'WAITED%' THEN ' (avg of '||ROUND(AVG(s.wait_time_micro))||'us)' END||
CASE WHEN s.wait_class IS NOT NULL THEN ' on '||s.wait_class||CASE WHEN s.event IS NOT NULL THEN ' - '||s.event END END AS current_timed_event,
COUNT(*) AS sessions
FROM v$session s,
v$containers c
WHERE s.sql_id = '&&cs_sql_id.'
AND s.status = 'ACTIVE'
AND c.con_id = s.con_id
GROUP BY
s.con_id,
c.name,
s.machine,
s.state,
s.wait_class,
s.event
ORDER BY
s.con_id,
s.machine,
s.state,
s.wait_class,
s.event
/
--
--BREAK ON con_id ON pdb_name ON machine SKIP PAGE;
SELECT s.con_id,
c.name AS pdb_name,
machine,
s.sid||','||s.serial# AS sid_serial#,
s.sql_child_number AS child_number,
TO_CHAR(s.sql_exec_start, '&&cs_datetime_full_format.') sql_exec_start,
(SYSDATE - s.sql_exec_start) * 24 * 3600 AS elapsed_seconds,
s.state||CASE WHEN s.state LIKE 'WAITED%' THEN ' ('||s.wait_time_micro||'us)' END||
CASE WHEN s.wait_class IS NOT NULL THEN ' on '||s.wait_class||CASE WHEN s.event IS NOT NULL THEN ' - '||s.event END END AS current_timed_event
FROM v$session s,
v$containers c
WHERE s.sql_id = '&&cs_sql_id.'
AND s.status = 'ACTIVE'
AND c.con_id = s.con_id
ORDER BY
s.con_id,
s.machine,
s.sql_exec_start
/
--
--CLEAR BREAK;

View File

@@ -0,0 +1,120 @@
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;
SET PAGES 300 LONGC 120;
--
COL sid_nopri NOPRI;
COL rt_lc FOR A12 HEA 'rt:RunTime|lc:LastCall';
COL sql_id_phv FOR A16 HEA 's:SQL_ID|p:Plan Hash';
COL attributes FOR A65 HEA 'c:Container, u:UserName, h:Host, m:Module, a:Action, p:Program|i:ClientInfo, s:State, w:WaitEvent, s:Sid,Session, l:LogonSecs';
COL sql_fulltext FOR A80 HEA 'SQL Text';
COL execution_plan FOR A80 HEA 'Execution Plan';
--
BREAK ON sid_nopri SKIP PAGE;
PRO
PRO Active Sessions
PRO ~~~~~~~~~~~~~~~
--
WITH
FUNCTION execution_plan (p_sql_id IN VARCHAR2, p_child_number IN NUMBER)
RETURN VARCHAR2
IS
l_execution_plan VARCHAR2(32767) := NULL;
BEGIN
FOR i IN (SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(p_sql_id, p_child_number, 'BASIC')) WHERE TRIM(plan_table_output) IS NOT NULL)
LOOP
IF i.plan_table_output LIKE 'Plan hash value: %' THEN l_execution_plan := NULL; END IF;
IF l_execution_plan IS NOT NULL THEN l_execution_plan := l_execution_plan||CHR(10); END IF;
IF LENGTH(l_execution_plan||SUBSTR(i.plan_table_output, 1, 79)) <= 4000 THEN
l_execution_plan := l_execution_plan||SUBSTR(i.plan_table_output, 1, 79);
ELSE
EXIT; -- avoid ORA-06502: PL/SQL: numeric or value error: character string buffer too small
END IF;
END LOOP;
RETURN l_execution_plan;
END execution_plan;
active_user_sessions
AS (
SELECT /*+ MATERIALIZE NO_MERGE */
e.con_id
, e.sql_exec_start
, e.last_call_et
, e.sql_id
, e.username
, e.osuser
, e.machine
, e.module
, e.action
, e.program
, e.client_info
, e.state
, e.wait_class
, e.event
, e.seconds_in_wait
, e.wait_time_micro
, e.sid
, e.serial#
, e.type
, e.logon_time
, e.sql_child_number
, e.audsid
, p.spid
, p.pname
FROM v$session e,
v$process p
WHERE e.status = 'ACTIVE'
-- AND e.type = 'USER'
AND e.sid <> SYS_CONTEXT('USERENV', 'SID') -- exclude myself
AND p.addr = e.paddr
)
SELECT e.sid AS sid_nopri
, 'rt:'||TRIM(TO_CHAR((SYSDATE - e.sql_exec_start) * 24 * 3600, '999,999,990'))||CASE WHEN e.sql_exec_start IS NOT NULL THEN 's' ELSE '<null>' END||
CHR(10)||'lc:'||TRIM(TO_CHAR(e.last_call_et, '999,999,990'))||'s' AS rt_lc
, CASE WHEN e.sql_id IS NOT NULL THEN 's:'||e.sql_id END||
CASE WHEN s.plan_hash_value IS NOT NULL THEN CHR(10)||'p:'||s.plan_hash_value END||
CASE WHEN s.sql_plan_baseline IS NOT NULL THEN CHR(10)||' spbl' END||
CASE WHEN s.sql_patch IS NOT NULL THEN CHR(10)||' spch' END||
CASE WHEN s.sql_profile IS NOT NULL THEN CHR(10)||' sprf' END
AS sql_id_phv
, 'c:'||SUBSTR(c.name, 1, 64)||
CHR(10)||'u:'||SUBSTR(NVL(e.username,'<null>'), 1, 64)||' os:'||SUBSTR(NVL(e.osuser,'<null>'), 1, 64)||
CHR(10)||'h:'||SUBSTR(NVL(e.machine,'<null>'), 1, 64)||
CASE WHEN e.module IS NOT NULL THEN CHR(10)||'m:'||SUBSTR(e.module, 1, 64) END||
CASE WHEN e.action IS NOT NULL THEN CHR(10)||'a:'||SUBSTR(e.action, 1, 64) END||
CASE WHEN e.program IS NOT NULL THEN CHR(10)||'p:'||SUBSTR(e.program, 1, 64) END||
CASE WHEN e.client_info IS NOT NULL THEN CHR(10)||'i:'||SUBSTR(e.client_info, 1, 64) END||
CHR(10)||'s:'||e.state||
CASE WHEN e.wait_time_micro > 0 THEN ' ('||TRIM(TO_CHAR(e.wait_time_micro,'999,999,999,990'))||'us)' END||
CASE WHEN e.seconds_in_wait > 0 THEN ' ('||TRIM(TO_CHAR(e.seconds_in_wait,'999,990'))||'s)' END||
CASE WHEN e.wait_class IS NOT NULL THEN CHR(10)||'w:'||e.wait_class||CASE WHEN e.event IS NOT NULL THEN ' - '||e.event END END||
CHR(10)||'os:'||e.spid||'('||NVL(e.pname,'ORA')||')'||
CHR(10)||'s:'||e.sid||','||e.serial#||'('||e.type||')'||
CHR(10)||'l:'||TRIM(TO_CHAR((SYSDATE - e.logon_time) * 24 * 3600, '999,999,990'))||'s'
AS attributes
, COALESCE(s.sql_fulltext, s2.sql_fulltext) AS sql_fulltext
, (SELECT execution_plan(e.sql_id, e.sql_child_number) FROM DUAL WHERE s.plan_hash_value > 0) AS execution_plan
FROM active_user_sessions e
OUTER APPLY (
SELECT s.plan_hash_value
, s.sql_plan_baseline
, s.sql_patch
, s.sql_profile
, s.sql_fulltext
FROM v$sql s
WHERE s.con_id = e.con_id
AND s.sql_id = e.sql_id
AND s.child_number = e.sql_child_number
AND s.object_status = 'VALID'
AND s.is_obsolete = 'N'
AND s.is_shareable = 'Y'
ORDER BY s.last_active_time DESC
FETCH FIRST ROW ONLY ) s
OUTER APPLY (
SELECT s.sql_fulltext
FROM v$sql s
WHERE s.sql_id = e.sql_id
FETCH FIRST ROW ONLY ) s2
, v$containers c
WHERE c.con_id = e.con_id
ORDER BY
e.sql_exec_start NULLS LAST,
e.last_call_et DESC
/

View File

@@ -0,0 +1,319 @@
--SET HEA OFF PAGES 0 SERVEROUT ON;
SET HEA OFF PAGES 0;
DECLARE
l_line INTEGER := 0;
l_b1 VARCHAR2(300) := '| | Active || Top #1 SQL | || Top #1 Event | || Top #1 PDB | |'; -- begin line 1
l_b2 VARCHAR2(300) := '| Sample Time | Sessions || Sessions | Top #1 SQL || Sessions | Top #1 Timed Event || Sessions | Top #1 PDB |'; -- begin line 2
l_s1 VARCHAR2(300) := '+-------------------------+----------++------------+------------------------------------------------------------------++--------------+----------------------------------------------------++------------+-------------------------------------+'; -- spacer
l_l1 VARCHAR2(300); -- line
l_begin_peak DATE;
l_seconds NUMBER;
l_sessions_peak NUMBER;
l_sql_id_peak VARCHAR2(13);
l_con_id_peak NUMBER;
l_sql_text_peak VARCHAR2(1000);
l_session_state_peak VARCHAR2(30);
l_wait_class_peak VARCHAR2(255);
l_event_peak VARCHAR2(255);
l_pdb_name_peak VARCHAR2(128);
BEGIN
DELETE plan_table;
IF &&times_cpu_cores. = 0 THEN
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
END IF;
FOR i IN (
WITH
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,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"') AS sql_id,
COUNT(*) AS active_sessions
FROM dba_hist_active_sess_history h
WHERE 1 = 1
AND '&&include_hist.' = 'Y'
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.
-- AND TO_NUMBER('&&cs_con_id.') IN (1, h.con_id)
AND (TO_NUMBER('&&cs_con_id.') IN (0, 1, h.con_id) OR h.con_id IN (0, 1)) -- now we include CDB$ROOT samples when executed from a PDB
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,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"')
UNION
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"') AS sql_id,
COUNT(*) AS active_sessions
FROM v$active_session_history h
WHERE 1 = 1
AND '&&include_mem.' = 'Y'
-- AND TO_NUMBER('&&cs_con_id.') IN (1, h.con_id)
AND (TO_NUMBER('&&cs_con_id.') IN (0, 1, h.con_id) OR h.con_id IN (0, 1)) -- now we include CDB$ROOT samples when executed from a PDB
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,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"')
),
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,
t.active_sessions,
CASE WHEN t.active_sessions < threshold.value AND t.lead_active_sessions >= threshold.value THEN 'Y' END AS b,
CASE WHEN t.active_sessions >= threshold.value THEN 'Y' END AS p,
CASE WHEN t.active_sessions < threshold.value AND t.lag_active_sessions >= threshold.value THEN 'Y' END AS e
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 */
),
con_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
con_id,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
con_id
),
c AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
con_id,
active_sessions
FROM con_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
),
eve_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
session_state,
wait_class,
event,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
session_state,
wait_class,
event
),
e AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
session_state,
wait_class,
event,
active_sessions
FROM eve_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
),
sql_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
sql_id,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
sql_id
),
s AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
sql_id,
active_sessions
FROM sql_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
)
SELECT t.sample_time,
t.active_sessions,
t.b,
t.p,
t.e,
s.active_sessions AS s_active_sessions,
s.sql_id,
(SELECT /*+ NO_MERGE */ REPLACE(v.sql_text, CHR(39)) FROM v$sql v WHERE s.sql_id <> '"null"' AND v.sql_id = s.sql_id AND ROWNUM = 1 /* MATERIALIZE */) AS sql_text,
e.active_sessions AS e_active_sessions,
e.session_state,
e.wait_class,
e.event,
c.active_sessions AS c_active_sessions,
(SELECT /*+ NO_MERGE */ v.name FROM v$containers v WHERE v.con_id = c.con_id AND ROWNUM = 1 /* MATERIALIZE */) AS pdb_name,
c.con_id
FROM t, c, e, s
WHERE c.sample_time = t.sample_time
AND e.sample_time = t.sample_time
AND s.sample_time = t.sample_time
ORDER BY
t.sample_time
)
LOOP
l_line := l_line + 1;
l_l1 :=
'| '||TO_CHAR(i.sample_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF3')||
' | '||TO_CHAR(i.active_sessions, '999,990')||
' || '||TO_CHAR(i.s_active_sessions, '999,990')||
' | '||RPAD(i.sql_id, 13)||
' '||RPAD(COALESCE(i.sql_text, ' '), 50)||
' || '||TO_CHAR(i.e_active_sessions, '999,990')||
' | '||RPAD(CASE i.session_state WHEN 'ON CPU' THEN i.session_state ELSE i.wait_class||' - '||i.event END, 50)||
' || '||TO_CHAR(i.c_active_sessions, '999,990')||
' | '||RPAD(i.pdb_name||'('||i.con_id||')', 35)||
' | ';
IF i.e = 'Y' AND i.b = 'Y' THEN -- end of peak followed by begin of peak (same row is both)
DBMS_OUTPUT.put_line(l_l1);
l_seconds := ROUND((CAST(i.sample_time AS DATE) - l_begin_peak) * 24 * 3600);
-- DBMS_OUTPUT.put_line(TO_CHAR(l_begin_peak, 'YYYY-MM-DD"T"HH24:MI:SS')||' '||l_seconds||' '||l_sessions_peak);
INSERT INTO plan_table (timestamp, cost, cardinality, statement_id, plan_id, remarks, operation, options, object_node, object_owner, object_type)
VALUES (l_begin_peak, l_seconds, l_sessions_peak, l_sql_id_peak, l_con_id_peak, l_sql_text_peak, l_session_state_peak, l_wait_class_peak, l_event_peak, l_pdb_name_peak, 'GLOBAL');
DBMS_OUTPUT.put_line(l_s1);
END IF;
IF i.b = 'Y' THEN -- begin of peak
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
l_begin_peak := NULL; l_sessions_peak := 0; l_sql_id_peak := NULL; l_con_id_peak := NULL; l_sql_text_peak := NULL; l_session_state_peak := NULL; l_wait_class_peak := NULL; l_event_peak := NULL; l_pdb_name_peak := NULL;
END IF;
DBMS_OUTPUT.put_line(l_l1); -- line
IF i.active_sessions > l_sessions_peak THEN
l_sessions_peak := i.active_sessions;
l_sql_id_peak := i.sql_id;
l_con_id_peak := i.con_id;
l_sql_text_peak := i.sql_text;
l_session_state_peak := i.session_state;
l_wait_class_peak := i.wait_class;
l_event_peak := i.event;
l_pdb_name_peak := i.pdb_name;
END IF;
IF i.e IS NULL AND i.b IS NULL AND l_begin_peak IS NULL THEN -- first line after a begin-peak
l_begin_peak := CAST(i.sample_time AS DATE);
END IF;
IF i.e = 'Y' AND i.b IS NULL THEN -- end of peak
l_seconds := ROUND((CAST(i.sample_time AS DATE) - l_begin_peak) * 24 * 3600);
-- DBMS_OUTPUT.put_line(TO_CHAR(l_begin_peak, 'YYYY-MM-DD"T"HH24:MI:SS')||' '||l_seconds||' '||l_sessions_peak);
INSERT INTO plan_table (timestamp, cost, cardinality, statement_id, plan_id, remarks, operation, options, object_node, object_owner, object_type)
VALUES (l_begin_peak, l_seconds, l_sessions_peak, l_sql_id_peak, l_con_id_peak, l_sql_text_peak, l_session_state_peak, l_wait_class_peak, l_event_peak, l_pdb_name_peak, 'GLOBAL');
DBMS_OUTPUT.put_line(l_s1);
END IF;
IF &&times_cpu_cores. = 0 AND MOD(l_line, 100) = 0 THEN -- heading every 100 rows when executed requesting all sample times and not just peaks
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
END IF;
END LOOP;
IF &&times_cpu_cores. = 0 THEN
DBMS_OUTPUT.put_line(l_s1); -- separator when executed requesting all sample times and not just peaks
END IF;
COMMIT;
END;
/
SET HEA ON PAGES 5000 SERVEROUT OFF;
PRO NOTE: Sum of Active Sessions per AWR sampled time, when greater than &&times_cpu_cores.x NUM_CPU_CORES(&&cs_num_cpu_cores.). Report includes for each sampled time Top #1: SQL, Timed Event and PDB; with corresponding Sum of Active Sessions for each of these 3 dimensions.
/*
plan_table mapping
Name Null? Type
----------------------------------------- -------- ----------------------------
STATEMENT_ID VARCHAR2(30) sql_id
PLAN_ID NUMBER con_id
TIMESTAMP DATE begin_peak
REMARKS VARCHAR2(4000) sql_text
OPERATION VARCHAR2(30) session_state
OPTIONS VARCHAR2(255) wait_class
OBJECT_NODE VARCHAR2(128) event
OBJECT_OWNER VARCHAR2(128) pdb_name
OBJECT_NAME VARCHAR2(128)
OBJECT_ALIAS VARCHAR2(261)
OBJECT_INSTANCE NUMBER(38)
OBJECT_TYPE VARCHAR2(30) global
OPTIMIZER VARCHAR2(255)
SEARCH_COLUMNS NUMBER
ID NUMBER(38)
PARENT_ID NUMBER(38)
DEPTH NUMBER(38)
POSITION NUMBER(38)
COST NUMBER(38) seconds
CARDINALITY NUMBER(38) sessions_peak
BYTES NUMBER(38)
OTHER_TAG VARCHAR2(255)
PARTITION_START VARCHAR2(255)
PARTITION_STOP VARCHAR2(255)
PARTITION_ID NUMBER(38)
OTHER LONG
OTHER_XML CLOB
DISTRIBUTION VARCHAR2(30)
CPU_COST NUMBER(38)
IO_COST NUMBER(38)
TEMP_SPACE NUMBER(38)
ACCESS_PREDICATES VARCHAR2(4000)
FILTER_PREDICATES VARCHAR2(4000)
PROJECTION VARCHAR2(4000)
TIME NUMBER(38)
QBLOCK_NAME VARCHAR2(128)
SELECT TO_CHAR(timestamp, 'YYYY-MM-DD"T"HH24:MI:SS') AS begin_peak,
TO_CHAR(timestamp + (cost/3600/24), 'YYYY-MM-DD"T"HH24:MI:SS') AS end_peak,
cost AS seconds,
cardinality AS sessions_peak,
-- statement_id AS sql_id,
-- remarks AS sql_text,
statement_id||' '||SUBSTR(remarks, 1, 50) AS sql_statement,
-- operation AS session_state,
-- options AS wait_class,
-- object_node AS event,
CASE operation WHEN 'ON CPU' THEN operation ELSE options||' - '||object_node END AS timed_event,
-- object_owner AS pdb_name,
-- plan_id AS con_id
object_owner||'('||plan_id||')' AS pdb_name
FROM plan_table
ORDER BY 1;
*/

View File

@@ -0,0 +1,293 @@
--SET HEA OFF PAGES 0 SERVEROUT ON;
SET HEA OFF PAGES 0;
DECLARE
l_line INTEGER := 0;
l_b1 VARCHAR2(300) := '| | Active || Top #1 SQL | || Top #1 Event | || Top #1 PDB | |'; -- begin line 1
l_b2 VARCHAR2(300) := '| Sample Time | Sessions || Sessions | Top #1 SQL || Sessions | Top #1 Timed Event || Sessions | Top #1 PDB |'; -- begin line 2
l_s1 VARCHAR2(300) := '+-------------------------+----------++------------+------------------------------------------------------------------++--------------+----------------------------------------------------++------------+-------------------------------------+'; -- spacer
l_l1 VARCHAR2(300); -- line
l_begin_peak DATE;
l_seconds NUMBER;
l_sessions_peak NUMBER;
l_sql_id_peak VARCHAR2(13);
l_con_id_peak NUMBER;
l_sql_text_peak VARCHAR2(1000);
l_session_state_peak VARCHAR2(30);
l_wait_class_peak VARCHAR2(255);
l_event_peak VARCHAR2(255);
l_pdb_name_peak VARCHAR2(128);
BEGIN
DELETE plan_table;
IF &&times_cpu_cores. = 0 THEN
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
END IF;
FOR i IN (
WITH
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,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"') AS sql_id,
COUNT(*) AS active_sessions
FROM &&ash_view. h
WHERE 1 = 1
-- AND TO_NUMBER('&&cs_con_id.') IN (1, h.con_id)
AND (TO_NUMBER('&&cs_con_id.') IN (0, 1, h.con_id) OR h.con_id IN (0, 1)) -- now we include CDB$ROOT samples when executed from a PDB
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,
h.con_id,
h.session_state,
h.wait_class,
h.event,
COALESCE(h.sql_id, h.top_level_sql_id, '"null"')
),
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,
t.active_sessions,
CASE WHEN t.active_sessions < threshold.value AND t.lead_active_sessions >= threshold.value THEN 'Y' END AS b,
CASE WHEN t.active_sessions >= threshold.value THEN 'Y' END AS p,
CASE WHEN t.active_sessions < threshold.value AND t.lag_active_sessions >= threshold.value THEN 'Y' END AS e
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 */
),
con_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
con_id,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
con_id
),
c AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
con_id,
active_sessions
FROM con_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
),
eve_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
session_state,
wait_class,
event,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
session_state,
wait_class,
event
),
e AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
session_state,
wait_class,
event,
active_sessions
FROM eve_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
),
sql_dim AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
sql_id,
SUM(active_sessions) AS active_sessions,
ROW_NUMBER() OVER (PARTITION BY sample_time ORDER BY SUM(active_sessions) DESC) AS rn
FROM active_sessions_time_series
WHERE ROWNUM >= 1 /* MATERIALIZE */
GROUP BY
sample_time,
sql_id
),
s AS (
SELECT /*+ MATERIALIZE NO_MERGE */
sample_time,
sql_id,
active_sessions
FROM sql_dim
WHERE rn = 1
AND ROWNUM >= 1 /* MATERIALIZE */
)
SELECT t.sample_time,
t.active_sessions,
t.b,
t.p,
t.e,
s.active_sessions AS s_active_sessions,
s.sql_id,
(SELECT /*+ NO_MERGE */ REPLACE(v.sql_text, CHR(39)) FROM v$sql v WHERE s.sql_id <> '"null"' AND v.sql_id = s.sql_id AND ROWNUM = 1 /* MATERIALIZE */) AS sql_text,
e.active_sessions AS e_active_sessions,
e.session_state,
e.wait_class,
e.event,
c.active_sessions AS c_active_sessions,
(SELECT /*+ NO_MERGE */ v.name FROM v$containers v WHERE v.con_id = c.con_id AND ROWNUM = 1 /* MATERIALIZE */) AS pdb_name,
c.con_id
FROM t, c, e, s
WHERE c.sample_time = t.sample_time
AND e.sample_time = t.sample_time
AND s.sample_time = t.sample_time
ORDER BY
t.sample_time
)
LOOP
l_line := l_line + 1;
l_l1 :=
'| '||TO_CHAR(i.sample_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF3')||
' | '||TO_CHAR(i.active_sessions, '999,990')||
' || '||TO_CHAR(i.s_active_sessions, '999,990')||
' | '||RPAD(i.sql_id, 13)||
' '||RPAD(COALESCE(i.sql_text, ' '), 50)||
' || '||TO_CHAR(i.e_active_sessions, '999,990')||
' | '||RPAD(CASE i.session_state WHEN 'ON CPU' THEN i.session_state ELSE i.wait_class||' - '||i.event END, 50)||
' || '||TO_CHAR(i.c_active_sessions, '999,990')||
' | '||RPAD(i.pdb_name||'('||i.con_id||')', 35)||
' | ';
IF i.e = 'Y' AND i.b = 'Y' THEN -- end of peak followed by begin of peak (same row is both)
DBMS_OUTPUT.put_line(l_l1);
l_seconds := ROUND((CAST(i.sample_time AS DATE) - l_begin_peak) * 24 * 3600);
-- DBMS_OUTPUT.put_line(TO_CHAR(l_begin_peak, 'YYYY-MM-DD"T"HH24:MI:SS')||' '||l_seconds||' '||l_sessions_peak);
INSERT INTO plan_table (timestamp, cost, cardinality, statement_id, plan_id, remarks, operation, options, object_node, object_owner, object_type)
VALUES (l_begin_peak, l_seconds, l_sessions_peak, l_sql_id_peak, l_con_id_peak, l_sql_text_peak, l_session_state_peak, l_wait_class_peak, l_event_peak, l_pdb_name_peak, 'GLOBAL');
DBMS_OUTPUT.put_line(l_s1);
END IF;
IF i.b = 'Y' THEN -- begin of peak
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
l_begin_peak := NULL; l_sessions_peak := 0; l_sql_id_peak := NULL; l_con_id_peak := NULL; l_sql_text_peak := NULL; l_session_state_peak := NULL; l_wait_class_peak := NULL; l_event_peak := NULL; l_pdb_name_peak := NULL;
END IF;
DBMS_OUTPUT.put_line(l_l1); -- line
IF i.active_sessions > l_sessions_peak THEN
l_sessions_peak := i.active_sessions;
l_sql_id_peak := i.sql_id;
l_con_id_peak := i.con_id;
l_sql_text_peak := i.sql_text;
l_session_state_peak := i.session_state;
l_wait_class_peak := i.wait_class;
l_event_peak := i.event;
l_pdb_name_peak := i.pdb_name;
END IF;
IF i.e IS NULL AND i.b IS NULL AND l_begin_peak IS NULL THEN -- first line after a begin-peak
l_begin_peak := CAST(i.sample_time AS DATE);
END IF;
IF i.e = 'Y' AND i.b IS NULL THEN -- end of peak
l_seconds := ROUND((CAST(i.sample_time AS DATE) - l_begin_peak) * 24 * 3600);
-- DBMS_OUTPUT.put_line(TO_CHAR(l_begin_peak, 'YYYY-MM-DD"T"HH24:MI:SS')||' '||l_seconds||' '||l_sessions_peak);
INSERT INTO plan_table (timestamp, cost, cardinality, statement_id, plan_id, remarks, operation, options, object_node, object_owner, object_type)
VALUES (l_begin_peak, l_seconds, l_sessions_peak, l_sql_id_peak, l_con_id_peak, l_sql_text_peak, l_session_state_peak, l_wait_class_peak, l_event_peak, l_pdb_name_peak, 'GLOBAL');
DBMS_OUTPUT.put_line(l_s1);
END IF;
IF &&times_cpu_cores. = 0 AND MOD(l_line, 100) = 0 THEN -- heading every 100 rows when executed requesting all sample times and not just peaks
DBMS_OUTPUT.put_line(l_s1);
DBMS_OUTPUT.put_line(l_b1);
DBMS_OUTPUT.put_line(l_b2);
DBMS_OUTPUT.put_line(l_s1);
END IF;
END LOOP;
IF &&times_cpu_cores. = 0 THEN
DBMS_OUTPUT.put_line(l_s1); -- separator when executed requesting all sample times and not just peaks
END IF;
COMMIT;
END;
/
SET HEA ON PAGES 5000 SERVEROUT OFF;
PRO NOTE: Sum of Active Sessions per AWR sampled time, when greater than &&times_cpu_cores.x NUM_CPU_CORES(&&cs_num_cpu_cores.). Report includes for each sampled time Top #1: SQL, Timed Event and PDB; with corresponding Sum of Active Sessions for each of these 3 dimensions.
/*
plan_table mapping
Name Null? Type
----------------------------------------- -------- ----------------------------
STATEMENT_ID VARCHAR2(30) sql_id
PLAN_ID NUMBER con_id
TIMESTAMP DATE begin_peak
REMARKS VARCHAR2(4000) sql_text
OPERATION VARCHAR2(30) session_state
OPTIONS VARCHAR2(255) wait_class
OBJECT_NODE VARCHAR2(128) event
OBJECT_OWNER VARCHAR2(128) pdb_name
OBJECT_NAME VARCHAR2(128)
OBJECT_ALIAS VARCHAR2(261)
OBJECT_INSTANCE NUMBER(38)
OBJECT_TYPE VARCHAR2(30) global
OPTIMIZER VARCHAR2(255)
SEARCH_COLUMNS NUMBER
ID NUMBER(38)
PARENT_ID NUMBER(38)
DEPTH NUMBER(38)
POSITION NUMBER(38)
COST NUMBER(38) seconds
CARDINALITY NUMBER(38) sessions_peak
BYTES NUMBER(38)
OTHER_TAG VARCHAR2(255)
PARTITION_START VARCHAR2(255)
PARTITION_STOP VARCHAR2(255)
PARTITION_ID NUMBER(38)
OTHER LONG
OTHER_XML CLOB
DISTRIBUTION VARCHAR2(30)
CPU_COST NUMBER(38)
IO_COST NUMBER(38)
TEMP_SPACE NUMBER(38)
ACCESS_PREDICATES VARCHAR2(4000)
FILTER_PREDICATES VARCHAR2(4000)
PROJECTION VARCHAR2(4000)
TIME NUMBER(38)
QBLOCK_NAME VARCHAR2(128)
SELECT TO_CHAR(timestamp, 'YYYY-MM-DD"T"HH24:MI:SS') AS begin_peak,
TO_CHAR(timestamp + (cost/3600/24), 'YYYY-MM-DD"T"HH24:MI:SS') AS end_peak,
cost AS seconds,
cardinality AS sessions_peak,
-- statement_id AS sql_id,
-- remarks AS sql_text,
statement_id||' '||SUBSTR(remarks, 1, 50) AS sql_statement,
-- operation AS session_state,
-- options AS wait_class,
-- object_node AS event,
CASE operation WHEN 'ON CPU' THEN operation ELSE options||' - '||object_node END AS timed_event,
-- object_owner AS pdb_name,
-- plan_id AS con_id
object_owner||'('||plan_id||')' AS pdb_name
FROM plan_table
ORDER BY 1;
*/

View File

@@ -0,0 +1,33 @@
PRO
PRO Active Sessions Peaks (when greater than &&times_cpu_cores.x NUM_CPU_CORES)
PRO ~~~~~~~~~~~~~~~~~~~~~
COL begin_peak FOR A19 HEA 'Aprox|Start Time';
COL end_peak FOR A19 HEA 'Aprox|End Time';
COL seconds FOR 999,990 HEA 'Aprox|Secs';
COL sessions_peak FOR 999,990 HEA 'Max|Sessions';
COL sql_statement FOR A64 HEA 'Top SQL Statement' TRUNC;
COL timed_event FOR A50 HEA 'Top Timed Event' TRUNC;
COL pdb_name FOR A35 HEA 'Top PDB Name(CON_ID)' TRUNC;
--
BREAK ON REPORT;
COMPUTE SUM OF seconds ON REPORT;
--
SELECT TO_CHAR(timestamp, 'YYYY-MM-DD"T"HH24:MI:SS') AS begin_peak,
TO_CHAR(timestamp + (cost/3600/24), 'YYYY-MM-DD"T"HH24:MI:SS') AS end_peak,
cost AS seconds,
cardinality AS sessions_peak,
-- statement_id AS sql_id,
-- remarks AS sql_text,
statement_id||' '||SUBSTR(remarks, 1, 50) AS sql_statement,
-- operation AS session_state,
-- options AS wait_class,
-- object_node AS event,
CASE operation WHEN 'ON CPU' THEN operation ELSE options||' - '||object_node END AS timed_event,
-- object_owner AS pdb_name,
-- plan_id AS con_id
object_owner||'('||plan_id||')' AS pdb_name
FROM plan_table
ORDER BY 1
/
--
PRO NOTE: Displayed values for 3 dimensions (SQL, Timed Event and PDB), correspond to sample time of Max Sessions

View File

@@ -0,0 +1,15 @@
PRO <pre>
PRO #01 &&aas_01. &&series_01.
PRO #02 &&aas_02. &&series_02.
PRO #03 &&aas_03. &&series_03.
PRO #04 &&aas_04. &&series_04.
PRO #05 &&aas_05. &&series_05.
PRO #06 &&aas_06. &&series_06.
PRO #07 &&aas_07. &&series_07.
PRO #08 &&aas_08. &&series_08.
PRO #09 &&aas_09. &&series_09.
PRO #10 &&aas_10. &&series_10.
PRO #11 &&aas_11. &&series_11.
PRO #12 &&aas_12. &&series_12.
PRO #13 &&aas_13. &&series_13.
PRO </pre>

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