Muitas vezes precisamos gerar relatórios AWR para compartilhar com outros times ou fornecedores, e dependendo do método de acesso ao servidor de banco de dados, o processo de copiar estes arquivos para a nossa máquina ou para um servidor intermediário pode se tornar mais trabalhoso do que gerar o relatório em si.

Após atuar muito nesse tipo de cenário, criei o script getawr.sql para simplificar esse processo, onde posso abrir uma conexão com o banco de dados remotamente via SQL*PLUS ou SQLcl e gerar o relatório localmente na máquina em que abri a conexão.

Além de não ser necessário acessar o servidor de banco de dados (ssh), o script também tem a facilidade de permitir gerar um AWR do tipo de Global (RAC), da instância local ou qualquer outra instância do cluster em um único script.

O Script

/*

 getawr.sql v1.1
 Script para gerar relatorio AWR do lado do Client (SQL*PLUS ou SQLcl)
 Pode ser usado para gerar report em HTML para a Intance Local, qualquer instance do Cluster ou Global
 
 Data       | Autor              | Modificacao
 ----------- -------------------- ------------------------------------------------------------------------
 08/04/2022 | Maicon Carneiro    | Cricao do script
 
*/

SET VERIFY OFF
SET FEEDBACK OFF

SET LINES 1000
SET PAGES 50

-- entrada do usuario para instance e qtde. dias para listar snaps
VARIABLE INSTID NUMBER;
VARIABLE QTDIAS NUMBER;

PROMPT Informe 0 para gerar um AWR Global (RAC) ou o Nº da Instance especifica (default = instance local)
ACCEPT user_INSTID   CHAR PROMPT 'Inst ID: '
ACCEPT user_QTDIAS NUMBER PROMPT 'Qtde. Dias: '

BEGIN
 IF '&user_INSTID' = '' THEN
    :INSTID := SYS_CONTEXT ('USERENV', 'INSTANCE');
   ELSE
    :INSTID := '&user_INSTID';
 END IF;
 IF &user_QTDIAS > 0 THEN
   :QTDIAS := &user_QTDIAS;
  ELSE
   :QTDIAS := 1;
 END IF;
END;
/

COL INST_ID FORMAT A10
COL SNAP_TIME FORMAT A20
-- lista os snaps
SELECT DISTINCT DECODE(:INSTID,0,'GLOBAL',INSTANCE_NUMBER) INST_ID, 
       TO_CHAR(BEGIN_INTERVAL_TIME,'DD/MM/YYYY HH24:MI')  SNAP_TIME,
 	   SNAP_ID
FROM DBA_HIST_SNAPSHOT
WHERE BEGIN_INTERVAL_TIME >= TRUNC(sysdate+1) - :QTDIAS
  AND END_INTERVAL_TIME <= sysdate
  AND (INSTANCE_NUMBER = :INSTID OR :INSTID = 0)
ORDER BY SNAP_ID;

ACCEPT SNAP_INICIAL NUMBER PROMPT 'SNAP Inicial: '
ACCEPT SNAP_FINAL   NUMBER PROMPT 'SNAP Final: '

-- variaveis que definem o tipo de relatorio e a definicao do nome do arquivo .html
column FUNCTION_NAME new_value FNAME          
column INSTANCE_NAME new_value INSTNAME FORMAT A30
column HOST_NAME     new_value HOSTNAME FORMAT A40
column INSTANCES     new_value LISTA_INSTANCES 

SET TERMOUT OFF
SELECT LISTAGG(inst_id, ',') WITHIN GROUP (ORDER BY inst_id) INSTANCES,
       DECODE(:INSTID,0,'AWR_GLOBAL_REPORT_HTML','AWR_REPORT_HTML') AS FUNCTION_NAME
FROM GV$INSTANCE;
SET TERMOUT ON

SELECT DECODE(:INSTID,0, D.NAME, I.INSTANCE_NAME) AS INSTANCE_NAME,
       DECODE(:INSTID,0,'GLOBAL',HOST_NAME) AS HOST_NAME
  FROM GV$INSTANCE I, V$DATABASE D
 WHERE (I.INST_ID = :INSTID OR :INSTID = 0)
   AND ROWNUM = 1;

-- inicio da geracao do AWR
SET TERMOUT OFF
SET HEADING OFF
SPOOL awr_&HOSTNAME-&INSTNAME-&SNAP_INICIAL-&SNAP_FINAL-.html

SELECT OUTPUT FROM TABLE(DBMS_WORKLOAD_REPOSITORY.&FNAME (
  l_dbid     => (SELECT DBID FROM V$DATABASE),
  l_inst_num => DECODE(:INSTID,0,'&LISTA_INSTANCES',:INSTID),
  l_bid      => &SNAP_INICIAL,
  l_eid      => &SNAP_FINAL
  ));

SPOOL OFF;
SET HEADING ON
SET TERMOUT ON
SET FEEDBACK ON

PROMPT Relatorio gerado: awr_&HOSTNAME-&INSTNAME-&SNAP_INICIAL-&SNAP_FINAL-.html

Exemplo de uso:

SQL> @getawr
Informe 0 para gerar um AWR Global (RAC) ou o Nº da Instance especifica (default = instance local)
Inst ID: 0
Qtde. Dias: 1

   INST_ID           SNAP_TIME    SNAP_ID
__________ ___________________ __________
GLOBAL     08/04/2022 00:00        117731
GLOBAL     08/04/2022 00:10        117732
GLOBAL     08/04/2022 00:20        117733
GLOBAL     08/04/2022 00:30        117734
GLOBAL     08/04/2022 00:40        117735
GLOBAL     08/04/2022 00:50        117736
GLOBAL     08/04/2022 01:00        117737
GLOBAL     08/04/2022 01:10        117738
GLOBAL     08/04/2022 01:20        117739
GLOBAL     08/04/2022 01:30        117740
GLOBAL     08/04/2022 01:40        117741
GLOBAL     08/04/2022 01:50        117742
GLOBAL     08/04/2022 02:00        117743
GLOBAL     08/04/2022 02:10        117744
GLOBAL     08/04/2022 02:20        117745
GLOBAL     08/04/2022 02:30        117746
GLOBAL     08/04/2022 02:40        117747
....
SNAP Inicial: 117731
SNAP Final: 117732

   INSTANCE_NAME    HOST_NAME
________________ ____________
ORCLVCP1         GLOBAL
Relatorio gerado: awr_GLOBAL-ORCLVCP1-117731-117732-.html

Exemplo gerando de uma Instance específica:

SQL> @getawr
Informe 0 para gerar um AWR Global (RAC) ou o Nº da Instance especifica (default = instance local)
Inst ID: 2
Qtde. Dias: 1

   INST_ID           SNAP_TIME    SNAP_ID
__________ ___________________ __________
2          08/04/2022 00:00        117731
2          08/04/2022 00:10        117732
2          08/04/2022 00:20        117733
2          08/04/2022 00:30        117734
2          08/04/2022 00:40        117735
2          08/04/2022 00:50        117736
2          08/04/2022 01:00        117737
2          08/04/2022 01:10        117738
2          08/04/2022 01:20        117739
2          08/04/2022 01:30        117740
2          08/04/2022 01:40        117741
2          08/04/2022 01:50        117742
2          08/04/2022 02:00        117743
2          08/04/2022 02:10        117744
2          08/04/2022 02:20        117745
2          08/04/2022 02:30        117746
2          08/04/2022 02:40        117747
..
SNAP Inicial: 117731
SNAP Final: 117732

   INSTANCE_NAME            HOST_NAME
________________ ____________________
ORCLVCP12        exa0004-exemplo2
Relatorio gerado: awr_exa0004-exemplo-ORCLVCP12-117731-117732-.html

Como Funciona

Na prática, não tem mistério na geração do AWR, apenas chamo a package DBMS_WORKLOAD_REPOSITORY, que tem um uso bem simples.

Exemplo, a query abaixo retorna um AWR global das instancias 1 e 2:

SELECT OUTPUT FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_GLOBAL_REPORT_HTML (
l_dbid => (SELECT DBID FROM V$DATABASE),
l_inst_num => '1,2',
l_bid => 117791,
l_eid => 117792
));

A ideia do script é apenas fornecer uma experiência similar ao dos scripts convencionais do AWR que ficam no servidor de banco de dados, tais como awrrpt.sql e awrgrpt.sql, além de tornar dinâmica a chamada para as procedures AWR_REPORT_HTML ou AWR_GLOBAL_REPORT_HTML, de acordo ao valor informado para INSTID.

Nomeclatura Padrão do Relatório

Diferente do default dos scripts convencionais do AWR, o script getawr.sql adiciona o nome do servidor e o nome da instância no nome do relatório. Quando usando a opção Global, o nome do banco de dados é usado no lugar do nome da instância, e o texto “GLOBAL” é usado no lugar do nome do servidor.

Essa abordagem é uma customização que deve facilitar a identificação dos arquivos quando geramos relatórios de ambientes ou banco de dados diferentes.

4 thoughts on “Script getawr.sql – Gerando AWR Remotamente do Lado do Client (SQL*PLUS & SQLcl)”
    1. Vlw Acácio !

      Isso mesmo, inclusive o que me incentivou a criar o script foi que por muitas vezes eu precisei abrir o SQL Developer na minha máquina só para atender essa necessidade 🙂

      Também não consegui usar ele para gerar relatório Global, se tiver a dica, deixa ai.

      Abs.

    1. Oi Pedro,

      Da forma como ele está hoje, não funcionaria, pois ele foi pensando no uso “Interativo”, enquanto a crontab deve esperar um uso “silencioso”.
      Mas acredito que pode ser facilmente adaptado para esse caso de uso, precisando apenas definir as regras que o script deve considerar toda vez que for executado (exemplo: Sempre gerar um referente as útltimas 2h, ou referente ao dia todo, etc).

      Qual seria sua ideia de filtros?
      Se eu puder ajudar, eu coloco aqui no comentário uma versão adaptada do script.

Leave a Reply

Discover more from Blog do Dibiei

Subscribe now to keep reading and get access to the full archive.

Continue reading