Los reportes de Automatic Workload Repository (AWR), son sin duda una de las mayores armas de las que disponemos para realizar “troubleshooting” en un ambiente de base de datos Oracle. El análisis de AWR, es una actividad habitual en la vida cotidiana de un DBA, de hecho, nosotros mismos (sobre todo al principio de nuestra carrera) hemos pasado gran cantidad de horas investigando y tratando de entender cada uno de los datos proporcionados por estos reportes.
El generador de AWR que se presenta en este artículo, fue desarrollado a partir de la necesidad de obtener la máxima información posible contenida en los informes generados. Es común encontrarse en situaciones donde el análisis de rendimiento, diagnóstico y ajuste se realiza el día después del incidente, por lo que AWR resulta ser de gran ayuda para estos casos.
Un típico gran error que enmascara información en el reporte AWR, es generarlo con un gran volumen de datos. Por ejemplo, generar un único reporte con toda la información acumulada entre 8 de la mañana a las 6 de la tarde. Esto termina enmascarando los datos, y a menudo puede ocultar valiosa información que apunte al verdadero problema causando perder además, mucho tiempo analizando el reporte y no obteniendo ningún resultado útil. Por lo tanto, en estos casos la recomendación sería generar varios reportes para cada intervalo de “snapshots” entre las 8 a.m. y 6 p.m., es aquí donde entra en juego el script generador de AWR que a diferencia del script proporcionado por Oracle (awrrp.sql) que apenas genera un único informe entre dos puntos en el tiempo. Nuestro generador puede producir varios reportes de AWR dentro del rango de “snapshot id” proporcionado. Tomando como ejemplo el reporte citado, con datos recolectados entre las 8 de la mañana y las 6 de la tarde, el script generador "awr" producirá un informe AWR por cada hora, esto sería uno para las 8 am, otro para las 9 am, otro para las 10am y así sucesivamente... hasta el snapshot id de las 18:00.
Solo 4 parámetros son requeridos para la ejecución del script:
1er parámetro: Tipo de informe que desea generar, html o texto.
2do parámetro: Cantidad de días para los cuales serán listados los snapshot id en la pantalla. Sólo para ver los snaps disponibles.
3er parámetro: El snapshot id inicial
4to parámetro: El snapshot id final
Veamos la ejecución del script gerador_awr.sql:
SQL> @gerador_awr
====>Showingthe AWR Settings Inverval/Retention
Minute Minute Days
Snapshot Interval Snapshot Retention Snapshot Retention
----------------- ------------------ ------------------
60 11520 8
====>Enteringthetypeof AWR Report: [html/text]: text
====>Enteringthenumberofdaysof snapshots listed: 1
DBID SNAPID BEGIN_TIME END_TIME
------------ ------ ---------------- -----------------
665418562 2626 15/12/2014 00:00 15/12/2014 01:00
2627 15/12/2014 01:00 15/12/2014 02:00
2628 15/12/2014 02:00 15/12/2014 03:00
2629 15/12/2014 03:00 15/12/2014 04:00
2630 15/12/2014 04:00 15/12/2014 05:00
2631 15/12/2014 05:00 15/12/2014 06:00
2632 15/12/2014 06:00 15/12/2014 07:00
2633 15/12/2014 07:00 15/12/2014 08:00
2634 15/12/2014 08:00 15/12/2014 09:00
2635 15/12/2014 09:00 15/12/2014 10:00
2636 15/12/2014 10:00 15/12/2014 11:00
2637 15/12/2014 11:00 15/12/2014 12:00
2638 15/12/2014 12:00 15/12/2014 13:00
2639 15/12/2014 13:00 15/12/2014 14:00
2640 15/12/2014 14:00 15/12/2014 15:00
2641 15/12/2014 15:00 15/12/2014 16:00
2642 15/12/2014 16:00 15/12/2014 17:00
2643 15/12/2014 17:00 15/12/2014 18:00
2644 15/12/2014 18:00 15/12/2014 19:00
2645 15/12/2014 19:00 15/12/2014 20:00
2646 15/12/2014 20:00 15/12/2014 21:00
2647 15/12/2014 21:00 15/12/2014 22:00
2648 15/12/2014 22:00 15/12/2014 23:00
2649 15/12/2014 23:00 16/12/2014 00:00
====>Enteringthe BEGIN SNAP ID : 2630
====>Enteringthe END SNAP ID : 2640
Generation AWR SNAPID ...2630 TO 2640
WORKLOAD REPOSITORY report for
DB Name DB Id Instance Inst Num Startup Time Release RAC
---------- -------------- --------- ---------------- ----------- ----
dbtst 665418562 dbtst1 1 11-Oct-14 19:57 11.2.0.4.0 YES
Host Name Platform CPUs Cores Sockets Memory(GB)
---------------- ---------------------- --------- -------- ----------
dm01dbadm01.pass Linux x86 64-bit 48 24 2 251.99
Snap Id Snap Time SessionsCurs/SessInstances
--------- -------------- --------------------------
Begin Snap: 2630 15-Dec-14 05:00:00 2,3684.9 2
EndSnap: 2631 15-Dec-14 06:00:03 2,3684.9 2
Elapsed: 60.04 (mins)
DB Time: 0.17 (mins)
Load Profile Per Second Per Transaction Per Exec Per Call
~~~~~~~~~~~~~~~ ----------- --------------- --------- ---------
DB Time(s): 0.0 0.4 0.00 0.00
DB CPU(s): 0.0 0.4 0.00 0.00
Redosize (bytes): 634.1 95,187.8
Logicalread (blocks): 30.7 4,603.3
Blockchanges: 1.6 240.5
Physicalread (blocks): 0.0 1.3
Physicalwrite (blocks): 0.2 33.8
Read IO requests: 0.0 1.3
Write IO requests: 0.2 26.6
Read IO (MB): 0.0 0.0
Write IO (MB): 0.0 0.3
RAC GC blocksreceived: 0.2 32.7
RAC GC blocksserved: 0.1 21.8
Usercalls: 1.6 233.1
Parses (SQL): 1.0 151.2
Hard parses (SQL): 0.0 5.3
SQL WorkArea (MB): 0.1 16.5
Logons: 0.1 11.0
Executes (SQL): 1.7 249.7
Rollbacks: 0.0 0.0
Transactions: 0.0
InstanceEfficiencyPercentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Buffer Nowait %: 100.00 RedoNoWait %: 100.00
Buffer Hit %: 99.97 In-memorySort %: 100.00
output removido
output removido
...
...
output removido
output removido
.00 0 0 0 0
-----------------------------------------------------------------------
DynamicRemasteringStats DB/Inst: PREPROD/preprod1 Snaps: 2638-2639
No data exists for thissectionofthe report.
------------------------------------------------------
EndofReport
AWR beginsnap 2630 toendsnap 2631 generated, file: gen_awr_dbtst1_2630_2631_report.txt
AWR beginsnap 2631 toendsnap 2632 generated, file: gen_awr_dbtst1_2631_2632_report.txt
AWR beginsnap 2632 toendsnap 2633 generated, file: gen_awr_dbtst1_2632_2633_report.txt
AWR beginsnap 2633 toendsnap 2634 generated, file: gen_awr_dbtst1_2633_2634_report.txt
AWR beginsnap 2634 toendsnap 2635 generated, file: gen_awr_dbtst1_2634_2635_report.txt
AWR beginsnap 2635 toendsnap 2636 generated, file: gen_awr_dbtst1_2635_2636_report.txt
AWR beginsnap 2636 toendsnap 2637 generated, file: gen_awr_dbtst1_2636_2637_report.txt
AWR beginsnap 2637 toendsnap 2638 generated, file: gen_awr_dbtst1_2637_2638_report.txt
AWR beginsnap 2638 toendsnap 2639 generated, file: gen_awr_dbtst1_2638_2639_report.txt
SQL>
Al final se presentan 9 reportes de AWR entre el rango de snapshot indicado.
Y aquí podemos ver todos la reportes AWR generados localmente por la ejecución del script:
Flavios-MacBook-Pro:~ flaviosoares$ ll gen_awr_dbtst1_263*
-rw-r--r-- 113049600 Dec 16 00:10 gen_awr_dbtst1_2630_2631_report.txt
-rw-r--r-- 114753536 Dec 16 00:11 gen_awr_dbtst1_2631_2632_report.txt
-rw-r--r-- 113672192 Dec 16 00:11 gen_awr_dbtst1_2632_2633_report.txt
-rw-r--r-- 113213440 Dec 16 00:11 gen_awr_dbtst1_2633_2634_report.txt
-rw-r--r-- 114327552 Dec 16 00:11 gen_awr_dbtst1_2634_2635_report.txt
-rw-r--r-- 120291328 Dec 16 00:11 gen_awr_dbtst1_2635_2636_report.txt
-rw-r--r-- 125730816 Dec 16 00:11 gen_awr_dbtst1_2636_2637_report.txt
-rw-r--r-- 115408896 Dec 16 00:11 gen_awr_dbtst1_2637_2638_report.txt
-rw-r--r-- 113082368 Dec 16 00:11 gen_awr_dbtst1_2638_2639_report.txt
El script fue probado en:
- Es necesario permiso de lectura-escritura en el directorio actual de ejecución para el mismo.
- El mismo detecta automáticamente si hubo un reinicio de la instancia entre el rango de snapshots proporcionado y advierte sobre este hecho.
- En el caso de querer ejecutar el script en un ambiente Windows, se obtendrá un error a la hora de la eliminación de los archivos temporales RUN_gen_awr_report.sql y store_set_saved.sql.
Código gerador_awr.sql:
-----------------------------------------------------------------------------------------------------------
-- Header: gerador_awr.sql 03-dez-2014.22:15 $ FSX Scripts - Flavio Soares X Scripts
--
-- Filename: gerador_awr.sql
--
-- Version: v1
--
-- Purpose: Gera AWR dinamicos sequencialmente, no formato escolhido a partir de um range de SNAPID fornecido.
--
-- Modified:
--
-- Notes: O gerador_awr.sql foi testado no Oracle 11g/12c, Single e RAC Instance
-- !!Para a execução do script é necessário permissão de leitura/Escrita no diretório atual da execução!!
--
-- Usage: SQL> @gerador_awr
--
-- Others:
--
-- Author: Flavio Soares
-- Copyright: (c) Flavio Soares - http://flaviosoares.com - All rights reserved.
-------------------------------------------------------------------------------------------------------
SET TERMOUT OFF
STORE SET store_set_saved.sql
SET TERMOUT ON
SET FEEDBACK OFF SERVEROUTPUT ON SQLBL ON LINES 5000 VERIFY OFF PAGES 2000
PROMPT ====> Showing the AWR Settings Inverval/Retention
COLUMN awr_env_interval_minutes HEADING "Minute|Snapshot Interval"
COLUMN awr_env_retention_minutes HEADING "Minute|Snapshot Retention"
COLUMN awr_env_retention_days HEADING "Days|Snapshot Retention"
SELECT
EXTRACT( day FROM snap_interval) *24*60+
EXTRACT( hour FROM snap_interval) *60+
EXTRACT( minute FROM snap_interval ) awr_env_interval_minutes,
EXTRACT( day FROM retention) *24*60+
EXTRACT( hour FROM retention) *60+
EXTRACT( minute FROM retention ) awr_env_retention_minutes,
((
EXTRACT( day FROM retention) *24*60+
EXTRACT( hour FROM retention) *60+
EXTRACT( minute FROM retention )
)/60/24)
awr_env_retention_days
from dba_hist_wr_control;
PROMPT
PROMPT
ACCEPT _gen_wr_type PROMPT '====> Entering the type of AWR Report: [html/text]: ' DEFAULT 'html'
PROMPT
PROMPT
ACCEPT _gen_wr_days PROMPT '====> Entering the number of days of snapshots listed: ' DEFAULT 8
COLUMN gen_wr_startup_time HEADING STARTUP_TIME FORMAT a28
COLUMN gen_wr_begin_time HEADING BEGIN_TIME FORMAT a28
COLUMN gen_wr_end_time HEADING END_TIME FORMAT a28
COLUMN gen_wr_snap_id HEADING SNAP_ID FORMAT 999999
COLUMN gen_wr_dbid HEADING DBID FORMAT 99999999999 NEW_VALUE _gen_awr_dbid
COLUMN gen_wr_inst_id HEADING INST_ID FORMAT 999999 NEW_VALUE _gen_awr_inst_id
COLUMN gen_wr_inst_name HEADING INSTANCE_NAME FORMAT a15 NEW_VALUE _gen_awr_inst_name
BREAK ON gen_wr_dbid SKIP 1 ON gen_wr_inst_id SKIP 1 ON gen_wr_inst_name SKIP 1 ON gen_wr_startup_time SKIP 1
SELECT
s.dbid gen_wr_dbid,
s.instance_number gen_wr_inst_id,
i.instance_name gen_wr_inst_name,
TO_CHAR(s.startup_time, 'DD/MM/YYYY HH24:MI') gen_wr_startup_time,
s.snap_id gen_wr_snap_id,
TO_CHAR(s.begin_interval_time, 'DD/MM/YYYY HH24:MI') gen_wr_begin_time,
TO_CHAR(s.end_interval_time, 'DD/MM/YYYY HH24:MI') gen_wr_end_time,
s.error_count
FROM dba_hist_snapshot s, v$instance i
WHERE end_interval_time >= sysdate - TO_NUMBER(&_gen_wr_days)
AND i.instance_number = s.instance_number
ORDER BY gen_wr_dbid, gen_wr_inst_id, gen_wr_snap_id;
ACCEPT _gen_wr_begin PROMPT '====> Entering the BEGIN SNAP ID : '
PROMPT
ACCEPT _gen_wr_end PROMPT '====> Entering the END SNAP ID : '
SET TERMOUT OFF
COLUMN gen_awr_report_inst_restart NEW_VALUE _gen_count_inst_restart NOPRINT
SELECT
CASE WHEN COUNT(DISTINCT TO_CHAR(s.startup_time, 'DD/MM/YYYY HH24:MI')) > 1
THEN 6 ELSE 0 END gen_awr_report_inst_restart
FROM dba_hist_snapshot s, v$instance i
WHERE i.instance_number = s.instance_number
AND snap_id BETWEEN TO_NUMBER(&_gen_wr_begin) AND TO_NUMBER(&_gen_wr_end);
HEADING OFF TERMOUT OFF
SELECT
CASE WHEN &_gen_count_inst_restart > 1 THEN '
====== PAY ATENTION: There are restart instance between the snapshot id that you choose ======
' || chr(10) || chr(10) END
FROM DUAL;
EXEC DBMS_LOCK.SLEEP(&_gen_count_inst_restart);
SET TERMOUT OFF
SPOOL RUN_gen_awr_report.sql
DECLARE
l_snap_id NUMBER := 0;
l_report_type VARCHAR2(20) := 'AWR_REPORT_TEXT';
l_gen_awr_name VARCHAR2(50) := '';
l_files_generate_awr VARCHAR2(10000) := '';
PROCEDURE out(p_name in VARCHAR2) is
BEGIN
DBMS_OUTPUT.PUT_LINE(p_name);
END;
BEGIN
out('PROMPT Generation AWR SNAPID ...' || &_gen_wr_begin || ' TO ' || &_gen_wr_end);
out('SET FEEDBACK OFF HEADING OFF');
out('exec DBMS_LOCK.SLEEP(0.5);');
l_snap_id := &_gen_wr_begin;
IF ('&_gen_wr_type' = 'html') THEN
l_report_type := 'AWR_REPORT_HTML' ;
END IF;
WHILE (l_snap_id + 1) <> &_gen_wr_end
LOOP
out('SET PAGES 0 LINES 32767 FEEDBACK OFF HEADING OFF');
l_gen_awr_name :=
'gen_awr_' || '&_gen_awr_inst_name' || '_' || l_snap_id || '_' || (l_snap_id + 1) || '_report.' ||
CASE WHEN '&_gen_wr_type' = 'text' THEN 'txt' ELSE 'html' END;
out('SPOOL ' || l_gen_awr_name );
out('SELECT * FROM TABLE
(DBMS_WORKLOAD_REPOSITORY.' || l_report_type || '(' || &_gen_awr_dbid || ',' ||
&_gen_awr_inst_id || ',' || l_snap_id || ',' || (l_snap_id + 1) || '));');
out('SPOOL off');
l_files_generate_awr := l_files_generate_awr || chr(10) || 'PROMPT AWR begin snap ' || l_snap_id ||
' to end snap ' ||
(l_snap_id + 1) || ' generated, file: ' || l_gen_awr_name;
l_snap_id := l_snap_id + 1;
END LOOP;
out('exec DBMS_LOCK.SLEEP(2);');
out('PROMPT');
out('PROMPT');
out(l_files_generate_awr);
END;
/
SET TERMOUT ON
SPOOL OFF
PROMPT
PROMPT
@@RUN_gen_awr_report.sql
PROMPT
UNDEFINE _gen_wr_days _gen_wr_begin _gen_wr_begin _gen_wr_end _gen_count_inst_restart _gen_wr_type _gen_awr_dbid
@@store_set_saved.sql
host rm -f RUN_gen_awr_report.sql
host rm -f store_set_saved.sql
De esta manera concluimos este artículo. Esperando haya sido de interés y utilidad nos despedimos hasta la próxima.
Joel Pérez es un experto DBA (Oracle ACE Director, OCM Cloud Admin. & OCM11g) con más de 14 años de experiencia real en el mundo de tecnología Oracle, especializado en diseño e implementación de soluciones de: Alta disponibilidad, Recuperación contra desastres, Upgrades, Replicación y toda área relacionada con bases de datos Oracle. Consultor Internacional con trabajos, conferencias y actividades relacionadas en más de 50 países alrededor del mundo. Habitual Orador en eventos Oracle alrededor del mundo tales como: OTN LAD, OTN MENA, OTN APAC y más. Joel se ha caracterizado siempre por ser un pionero en materia de tecnología Oracle desde los inicios de su carrera siendo el primer latinoamericano publicado como experto en Oracle.com como "OTN Expert" en el año 2003, uno de los primeros Oracle ACE del respectivo programa en el año 2004, unos de los primeros OCP Cloud en el mercado global en el año 2013 y como uno de los mayores logros de su carrera, recientemente en el 2014 fue honorificado como uno de los primeros "OCM Database Cloud Administrator" del mundo. En la actualidad Joel Pérez esta radicado en el continente de Asia con base en Beijing, China llevando a cabo operaciones profesionales en alianza con una de las mayores compañías de consultoría Oracle en China "Enmotech".
Flavio Soares es un senior DBA Oracle, solucionador de problemas y Consultor Oracle Certificado como OCP/OCE RAC. Especialista en Exadata, alta disponibilidad y replicación de datos con diversas soluciones Oracle. Flavio ofrece información frecuente para la comunidad de Oracle a través de sus artículos a través de OTN Portugués.
Sebastián D. es un Senior DBA con más de 12 años de experiencia en tecnología Oracle, focalizado principalmente en seguridad de base de datos, soluciones de alta disponibilidad, disaster recovery y virtualización. Actualmente desarrolla su actividad como consultor e instructor de manera independiente
Este artículo ha sido revisado por el equipo de productos Oracle y se encuentra en cumplimiento de las normas y prácticas para el uso de los productos Oracle.