update ( 10/10/2012 ): I have changed the script to make work better with hourly requests at it was causing issues. Thanks to Dominic Brooks for the trick
update ( 11/10/2012 ): Added ADDM and Global report generation
Since I got turbo boost (over 1000 hits a day-wooow) from Tanel Poder the Great, better I write something to deserve the fame. This one is a real quick one which made my life easier.
On my second week at current company, I had to cover Exadata for 2 weeks which were completely nightmare due to some problems. I had to work with Oracle Support too much and most of the time they ask AWR reports from 8 nodes for x hour duration. First day I was not armed with anything automatic, so tried to do it manually but it was proper nightmare for 8 nodes. Then I said this is complete rubbish way of wasting my time and I need to automate the process otherwise my life will be miserable. Finally I came up with something after couple of attempts
The script below is the result of this automation attempts.
update ( 11/10/2012 ): –not equal sign may have been corrupted during paste for (next_snap_id”0 AND previous_snap_id”0)
-- Name: gen_snap.sql
--
-- Purpose: Automating ADDM and AWR and Global RAC report generation
--Usage: copy the script your script directory. Edit the parameters section then run it ,
---it will generate gen_awr.sql script . Call that script for generating awr reports
---
--- ALWAYS CHECK gen_awr.sql script before you run !!!!!!!!!
---
-- @gen_snap.sql
-- @gen_awr
-- Versioning:
-- Version Modified by Date What Modified
-- ------- --------------- ---------- --------------
-- 1.0 Coskan Gundogar 11/10/2012 Initial
------------PARAMETERS - BEGIN -------------------------------
define _interval=2 --1 for half hour 2 for 1 hour (30 mins snapshots) / 1 for hour 2 for 2 hour (60 mins snapshots)
define _database_name='DATABASE_NAME' ---- database name
define _begin_interval_date='111012 07:00:00' ----begin date DDMMYY HH24:MI:SS
define _end_interval_date='111012 10:00:00' ----end date DDMMYY HH24:MI:SS
define _folder='C:\awr\DATABASE_NAME\111012' ---report output location
define _option=2 ---1 without ADDM 2 with ADDM
define _global=1 ---0 if you don't want Global Reports for RAC - It will not generate report for Single Instance with any setting
------------PARAMETERS - END-------------------------------
SET termout OFF
host mkdir &_folder
SET termout ON
--host dir &_folder
prompt
prompt
prompt GEN_AWR.SQL script generation started
prompt
SET termout OFF
SET heading off
SET feedback OFF
SET echo OFF
SET linesize 155
SET verify OFF
spool gen_awr.SQL
SELECT 'set veri off;'||CHR(10)||
'set feedback off;' ||CHR(10)||
'set linesize 1500;' ||CHR(10)||
'prompt '||CHR(10)||
'prompt '||CHR(10)||
'prompt REPORT GENERATION STARTED'||CHR(10)||
'prompt '||CHR(10)||
'SET TIME OFF'||CHR(10)||
'set termout off;'||CHR(10)||
'set long 1000000 pagesize 0 longchunksize 1000;'||CHR(10)||
'COLUMN get_clob format a80'||CHR(10)
FROM dual;
with driver as (
select *
from (
select rownum rn,dbid,snap_id,previous_snap_id,next_snap_id,begin_interval_time from (
SELECT * FROM (
select instance_number,dbid,snap_id,
LEAD(snap_id, &_interval, 0) OVER (PARTITION BY instance_number ORDER BY snap_id DESC NULLS LAST) previous_snap_id,
LAG(snap_id, &_interval, 0) OVER (PARTITION BY instance_number ORDER BY snap_id DESC NULLS LAST) next_snap_id,
begin_interval_time
from dba_hist_snapshot
where dbid=(select dbid from v$database where name='&_database_name')
AND instance_number= (select min(inst_id) from gV$database)
AND begin_interval_time>=TO_DATE('&_begin_interval_date','DDMMYY HH24:MI:SS')-1/24
AND begin_interval_time<TO_DATE('&_end_interval_date','DDMMYY HH24:MI:SS')+1/24
) d WHERE next_snap_id0 AND previous_snap_id0 ---not equal sign may have been corrupted during paste
ORDER BY 3
) s ) where (
CASE WHEN &_INTERVAL = 2 THEN mod(rn,2)
WHEN &_INTERVAL=1 THEN 1
END)=1
)
SELECT
CASE &_option
WHEN 1 THEN
'spool &_folder\awrrptto_&_database_name'||CHR(95)||TO_CHAR(instance_number)||'_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'.html'||CHR(10)|| CHR(10)||
'SELECT * FROM TABLE(dbms_workload_repository.awr_report_html('||TO_CHAR(dbid)||','||TO_CHAR(instance_number)||','||TO_CHAR(snap_id)||','||TO_CHAR(next_snap_id)||',8));'||CHR(10)
||CHR(10)||'spool off'
WHEN 2 THEN
'spool &_folder\awrrptto_&_database_name'||CHR(95)||TO_CHAR(instance_number)||'_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'.html'||CHR(10)|| CHR(10)||
'SELECT * FROM TABLE(dbms_workload_repository.awr_report_html('||TO_CHAR(dbid)||','||TO_CHAR(instance_number)||','||TO_CHAR(snap_id)||','||TO_CHAR(next_snap_id)||',8));'||CHR(10)
||CHR(10)||'spool off'||CHR(10)||
'BEGIN'||CHR(10)||
'DBMS_ADVISOR.create_task (advisor_name => ''ADDM'',task_name=> ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'');'||CHR(10)||
'DBMS_ADVISOR.set_task_parameter (task_name => ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'',parameter => ''START_SNAPSHOT'',value=> '||TO_CHAR(snap_id)||');'||CHR(10)||
'DBMS_ADVISOR.set_task_parameter (task_name => ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'',parameter => ''END_SNAPSHOT'', value=> '||TO_CHAR(next_snap_id)||');'||CHR(10)||
'DBMS_ADVISOR.set_task_parameter (task_name => ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'',parameter => ''INSTANCE'', value=> '||TO_CHAR(instance_number)||');'||CHR(10)||
'DBMS_ADVISOR.set_task_parameter (task_name => ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'',parameter => ''DB_ID'', value=> '||TO_CHAR(dbid)||');'||CHR(10)||
'DBMS_ADVISOR.execute_task(task_name => ''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'');'||CHR(10)||
'END;'||CHR(10)||
'/'||CHR(10)||
'spool &_folder\addm_&_database_name'||CHR(95)||TO_CHAR(instance_number)||'_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT.txt'||CHR(10)||
'SELECT DBMS_ADVISOR.get_task_report(''ADDM_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'_AWR_SNAPSHOT'') AS report'||CHR(10)||
'FROM dual;'||CHR(10)||
'spool off'||CHR(10)
END
FROM (
select ai.inst_id instance_number,d.dbid,d.snap_id,d.previous_snap_id,d.next_snap_id,d.begin_interval_time from driver d,
gv$database ai
order by 1,3);
SELECT
CASE &_global
WHEN 1 then
'set timing off space 1 flush on pause off numwidth 10;' ||CHR(10)||
'set echo off feedback off newpage 1 recsep off;' ||CHR(10)||
'set trimspool on trimout on define "&" concat "." serveroutput on;'||CHR(10)||
'set underline on;'||CHR(10)||
'set heading off;'||CHR(10)||
'set pagesize 50000;'||CHR(10)||
'set echo off;'||CHR(10)||
'set feedback off;'||CHR(10)||
'set linesize 8000;'||CHR(10)||
'set veri off;'||CHR(10)
WHEN 0 THEN ''
END
FROM dual;
with driver as (
select *
from (
select rownum rn,dbid,snap_id,previous_snap_id,next_snap_id,begin_interval_time from (
SELECT * FROM (
select instance_number,dbid,snap_id,
LEAD(snap_id, &_interval, 0) OVER (PARTITION BY instance_number ORDER BY snap_id DESC NULLS LAST) previous_snap_id,
LAG(snap_id, &_interval, 0) OVER (PARTITION BY instance_number ORDER BY snap_id DESC NULLS LAST) next_snap_id,
begin_interval_time
from dba_hist_snapshot
where dbid=(select dbid from v$database where name='&_database_name')
AND instance_number= (select min(inst_number) from gV$active_instances)
AND begin_interval_time>=TO_DATE('&_begin_interval_date','DDMMYY HH24:MI:SS')-&_interval/24
AND begin_interval_time<TO_DATE('&_end_interval_date','DDMMYY HH24:MI:SS')+&_interval/24
) d WHERE next_snap_id0 AND previous_snap_id0 --not equal sign may have been corrupted during paste
ORDER BY 3
) s ) where (
CASE WHEN &_INTERVAL = 2 THEN mod(rn,2)
WHEN &_INTERVAL=1 THEN 1
END)=1
)
SELECT
CASE &_global
WHEN 1 then
'spool &_folder\global_awrrptto_&_database_name'||CHR(95)||'_'||TO_CHAR(snap_id)||'_'||TO_CHAR(next_snap_id)||'.html'||CHR(10)|| CHR(10)||
'SELECT * FROM TABLE(dbms_workload_repository.awr_global_report_html('||TO_CHAR(dbid)||','''','||TO_CHAR(snap_id)||','||TO_CHAR(next_snap_id)||',8));'||CHR(10)
||CHR(10)||'spool off'
WHEN 0 THEN ''
END
FROM driver;
SELECT
'set termout on' ||CHR(10)||
'SET TIME ON' ||CHR(10)||
'prompt '||CHR(10)||
'prompt '||CHR(10)||
'prompt REPORT GENERATION FINISHED'||CHR(10)||
'prompt '||CHR(10)||
'SET TIME OFF'||CHR(10)
FROM dual;
SET termout ON
spool off
prompt
prompt
prompt GEN_AWR.SQL script generation finished
prompt
prompt
!!!To save it click on the view source link on the sourcode upright corner
Nothing rocket science, just using dbms_workload_repository.awr_report_html with some junior level analytic.
All you have to do is give the date, interval (only tested for half hour or one hour intervals)and folder to be saved then rest will be done by the script.
It will create a gen_awr.sql script which you will run and go have a coffee then when you come back your awr reports are ready to be sent.
so the sequence is
@gen_snap ---assume you save it with this name @gen_awr --coffee break --zip+upload
I would like to automate it further by doing the same for rac comparison or group of instance but I think I am too lazy or maybe busy with some other non-automatable rubbish
(I also had some issues with rac comparison report formatting with the DBMS_WORKLOAD_REPOSITORY package so I gave up on that one)
Hope this tiny script save your time as much as it saves mine.

Hi-
Good approach, I have also stuck in similar situation to generate awr reports for exadata (multi-nodes) and had to come with similar approach. Do you also not like of using DBMS_WORKLOAD_REPOSITORY.AWR_GLOBAL_REPORT_HTML ? personally I found myself comfortable with individual instance report but time consuming sometime.
Comment by Jagjeet Singh — November 18, 2011 @ 12:07 pm
Thanks for your comment Jagjeet. I think idea of global report is really good, but somehow formatting of DBMS_WORKLOAD_REPOSITORY.AWR_GLOBAL_REPORT_HTML never worked for me
Comment by coskan — November 18, 2011 @ 12:23 pm
Hi Coskan,
Great script !!!
There is also 2 other scripts to get the AWR Workload RAC (Global) report script to get RAC-wide differences between values recorded in 2 snapshots =>
$ORACLE_HOME/rdbms/admin/awrgrpt.sql (calls ” awrgrpti.sql “)
Thanks for the script
Regards,
Divakar
Comment by Divakar Mehta — December 15, 2011 @ 4:50 pm
Thank you very much mate I know the other two but as I said at the last paragraph I could not manage to get the right formatting for them
Comment by coskan — December 17, 2011 @ 2:20 pm
Coskan,
Have you seen mine solution.
http://damir-vadas.blogspot.com/2009/11/automated-awr-reports-in-oracle-10g11g.html
Rg,
Damir
Comment by Damir Vadas — December 17, 2011 @ 2:09 pm
Thanks for stopping by Damir, I knew your solution which is neat but my problem is being a bit more flexible about the time interval and also interval between two snapshots that why I needed to use analytic and also I can’t add anything to databases without convincing change management
Comment by coskan — December 17, 2011 @ 2:19 pm
Top Man. . my life is changed!!:)
Comment by Jaspal Chana — October 10, 2012 @ 1:20 pm