Automatización de informes AWR

Hola a todos, hoy queríamos compartir con vosotros una forma sencilla que nos permite la automatización de informes AWR. Esto nos evitará tener que introducir los parámetros que nos solicita cuando ejecutamos el script awrrpt.sql.

En este caso, hemos hecho un script de PL/SQL en el que introducimos el mes en letra, el año y el mes en número. Con los valores introducidos, consulta en la vista dba_hist_snapshot y ya nos genera un fichero (en formato texto en este caso) con el informe AWR del mes indicado. Tiene también un chequeo para que en el caso de que la instancia se ha reiniciado en ese período, genere ficheros distintos poniendo un número secuencial. El script controla si nuestra base de datos está en RAC y genera un informe por cada instancia.

Automatización de informes AWR

Crear script para automatización de informes AWR

Os vamos contando las partes del script y luego lo adjuntamos completo.

Antes de la generación del script, necesitamos crear un objeto directory, en este caso lo hemos definido así:

CREATE DIRECTORY INFORMES as '/tmp/test';

Definición de variables de entrada:

var mesletra  varchar2(20);
var mesnumero  varchar2(20);
var annonumero  varchar2(20);
exec :mesletra := '&1';
exec :annonumero := '&2';
exec :mesnumero := '&3';

En esta parte se definen los parámetros de entrada, que son los que hemos indicado anteriormente.

set heading off
set pagesize 1000
set linesize 1000
set echo off
set serveroutput on
SET FEEDBACK off
declare
  firstday date;
  lastday date;
  contador integer;
  instancia_anterior integer;
  v_html_report_row varchar2(1500);
  v_awr_report CLOB:=empty_clob();
  l_file   UTL_FILE.file_type;

Hasta ahora, hemos definido la salida de los scripts y las variables que vamos a utilizar en nuestro script.

cursor report_cursor is
    select s.DBID, s.INSTANCE_NUMBER, min(s.snap_id) as min_id,max(s.snap_id) as max_id, i.INSTANCE_NAME
        from dba_hist_snapshot s, gv$instance i, v$database d
                where s.DBID = d.DBID and s.INSTANCE_NUMBER = i.INSTANCE_NUMBER and s.begin_interval_time > firstday and s.begin_interval_time < lastday+1
        group by s.DBID, s.INSTANCE_NUMBER, s.startup_time, i.INSTANCE_NAME order by 2,3;

Lo que vemos en esta parte es la definición de la consulta que va a buscar los AWR generados en el mes que buscamos dentro de un cursor y crea distintas líneas dependiendo del nombre de la instancia (por si es un RAC) y las distintas paradas de las misma.

Una vez que hemos definido nuestras variables abrimos el cursor y empezamos a generar los ficheros de nuestros informes:

firstday := to_date('01-' || :mesnumero || '-20' || :annonumero,'DD-MM-YYYY');
  lastday := LAST_DAY(firstday);
  contador :=0;
  for REC in report_cursor loop
   if REC.INSTANCE_NUMBER = instancia_anterior then
	contador := contador + 1;
	l_file := UTL_FILE.fopen ('INFORMES', 'awr_' || REC.INSTANCE_NAME || '_' || :mesletra || :annonumero || '_' || contador || '.txt', 'W');
  else
	contador:=0;
	l_file := UTL_FILE.fopen ('INFORMES', 'awr_' || REC.INSTANCE_NAME || '_' || :mesletra || :annonumero || '.txt', 'W');
  end if;

Ahora empezamos a rellenar los ficheros, lo hacemos con la función dbms_workload_repository.awr_report_text, pasando los parámetros que hemos sacado del cursor anterior:

  for cv in
	(select output from table(dbms_workload_repository.awr_report_text(REC.DBID,REC.INSTANCE_NUMBER, REC.min_id, REC.max_id)))
	loop
	v_html_report_row := cv.output;
	UTL_FILE.put_line (l_file, v_html_report_row);
	end loop;
  instancia_anterior := REC.INSTANCE_NUMBER;
  UTL_FILE.fclose (l_file);
  end loop;

Ejecución del script

Esta es la definición del script, para generar los informes, llamamos al fichero sql y lo hacemos de la siguiente forma:

SQL> @awr Febrero 23 02

En el objeto directory INFORMES nos generará automáticamente el fichero AWR de nuestra instancia:

[oracle@server1 test]$ ls –ltr /tmp/test
total 272
-rw-rw-r-- 1 oracle oinstall 276288 mar  7 13:53 awr_ORCL2_Febrero23.txt

El script se puede integrar fácilmente en un Linux o Windows, solo tenemos que generar las variables de entrada de forma automática y llamar el script. Esto permite que se puede incluso programar para que tome el mes en curso y se lance automáticamente guardando en nuestro directorio los informes de meses anteriores por si necesitamos revisarlos.

Fichero awr.sql

var mesletra  varchar2(20);
var mesnumero  varchar2(20);
var annonumero  varchar2(20);
exec :mesletra := '&1';
exec :annonumero := '&2';
exec :mesnumero := '&3';
set heading off
set pagesize 1000
set linesize 1000
set echo off
set serveroutput on
SET FEEDBACK off
declare
  firstday date;
  lastday date;
  contador integer;
  instancia_anterior integer;
  v_html_report_row varchar2(1500);
  v_awr_report CLOB:=empty_clob();
  l_file   UTL_FILE.file_type;
  cursor report_cursor is
    select s.DBID, s.INSTANCE_NUMBER, min(s.snap_id) as min_id,max(s.snap_id) as max_id, i.INSTANCE_NAME
        from dba_hist_snapshot s, gv$instance i, v$database d
                where s.DBID = d.DBID and s.INSTANCE_NUMBER = i.INSTANCE_NUMBER and s.begin_interval_time > firstday and s.begin_interval_time < lastday+1
        group by s.DBID, s.INSTANCE_NUMBER, s.startup_time, i.INSTANCE_NAME order by 2,3;
begin
  firstday := to_date('01-' || :mesnumero || '-20' || :annonumero,'DD-MM-YYYY');
  lastday := LAST_DAY(firstday);
  contador :=0;
  for REC in report_cursor loop
   if REC.INSTANCE_NUMBER = instancia_anterior then
	contador := contador + 1;
	l_file := UTL_FILE.fopen ('INFORMES', 'awr_' || REC.INSTANCE_NAME || '_' || :mesletra || :annonumero || '_' || contador || '.txt', 'W');
  else
	contador:=0;
	l_file := UTL_FILE.fopen ('INFORMES', 'awr_' || REC.INSTANCE_NAME || '_' || :mesletra || :annonumero || '.txt', 'W');
  end if;
   
  for cv in
	(select output from table(dbms_workload_repository.awr_report_text(REC.DBID,REC.INSTANCE_NUMBER, REC.min_id, REC.max_id)))
	loop
	v_html_report_row := cv.output;
	UTL_FILE.put_line (l_file, v_html_report_row);
	end loop;
  instancia_anterior := REC.INSTANCE_NUMBER;
  UTL_FILE.fclose (l_file);
  end loop;
end;
/
spool off
exit

Esperamos que la entrada os sea de utilidad y si teméis algún comentario o mejora sobre el script comentadnos. Si preferis que lo implantemos en tu entorno, no dudéis en poneros en contacto con nosotros sin compromiso. Para una entrada posterior os contaremos como se puede hacer con informes statspacks si no tenéis la opción de generar AWR.

Un saludo y muchas gracias.

¿Aún no conoces Query Performance? Descubre cómo puede ayudarte en tu entorno Oracle. Más información en su página de LinkedIn.

Sígue a GPS en LinkedIn

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *