Oracle Database Tuning – Génération automatique des fichiers AWR

Tuning : Génération automatique des fichiers AWR

Pour effectuer du tuning sur une base de données, on peut être amené à générer les fichiers AWR sur une période plus ou moins longue. Manuellement, cette opération peut être fastidieuse.
On s’attachera ici à décrire la méthode de génération des AWR sur une période d’une journée.
En pré requis on s’assurera qu’une directory, au sens Oracle, a bien été définie dans la base de données a auditer.
On s’assurera que l’intervalle entre la création des snapshots est correctement positionné. Un intervalle de 10 a 15mn est un bon compromis entre la qualité des informations recueillies et l’overhead généré sur la base.
Le paramétrage de l’intervalle entre les snapshots ainsi que la durée de rétention des informations peut se faire de 2 façons différentes.

En mode ligne de commande, connectez vous a la base de données en tant que sysdba et lancez la commande suivante:


EXECUTE DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
 interval => 10,
 retention => 20160);

Pour la création d’un snapshot toutes les 10mn avec une rétention de 14 jours.
Autre possibilité, passer par la console d’administration
Une fois que vous êtes connecté à la base de données voulue:

  • Choisir l’onglet                            Server
  • Puis dans le paragraphe              Statistics Management
  • Sélectionnez le lien                     Automatic Workload Repository
  • Bouton                                       Edit
  • Saisir les valeurs voulues dans    Retention Period et Interval
  • Puis bouton                                 OK

Une fois le paramétrage en place et les snapshots générés sur la période voulue, dans notre exemple 1 journée, on peut lancer la génération des AWRs.
On va générer un fichier AWR correspondant à l’intervalle défini précédemment, au format texte ou html sur la journée de la veille.
Cela correspond à 151 fichiers pour un intervalle de 10mn.
Dans un premier temps, on va créer la directory.
Connectez vous en tant que sysdba puis lancez la commande suivante


CREATE OR REPLACE DIRECTORY AWR_DIR as '/tmp/awr/{DATABASE_NAME}';

Où {DATABASE_NAME} correspond au nom de la base de données à auditer.
On peut maintenant lancer la génération des awrs.
Toujours en tant que sysdba

-- Positionnement de la variable globale correspondant au type de rapport désiré
---------------------------------------------------------------------------------
variable gl_file_type varchar2(4);
begin
 :gl_file_type := '{AWR_TYPE}' ;
 end;
 /
-- ou {AWR_TYPE} prend la valeur txt ou html
-- procédure de génération des fichiers
-----------------------------------------
 declare
 lc_dbid NUMBER;
 lc_snap_debut NUMBER;
 lc_snap_fin NUMBER;
 awr_file_name VARCHAR2(24);
 instance_liste AWRRPT_INSTANCE_LIST_TYPE;
 lc_instance_liste VARCHAR2(1023);
 snap_init NUMBER;
 snap_suivant NUMBER;
 boucle NUMBER := 0;
-- Variables utilisées dans la création des fichiers
-----------------------------------------------------
 Num_Fichier Utl_File.File_Type;
 Repertoire VARCHAR2(200):='AWR_DIR';
-- Curseur permettant de retrouver la liste des instances RAC
--------------------------------------------------------------
 cursor curs_instance_liste is
 select to_char(inst_id,'9') inst_id
   from gv$instance
  order by inst_id;
-- curseur permettant de générer les informations correspondant au fichier txt
-- Pour l'ensemble des instances de la base de données
-------------------------------------------------------------------------------
 cursor curs_awr_text_report (c_dbid NUMBER ,
                              c_instances VARCHAR2 ,
                              c_snapdeb NUMBER ,
                              c_snapfin NUMBER ) is
 SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_GLOBAL_REPORT_TEXT (
                                                                      c_dbid ,
                                                                      c_instances ,
                                                                      c_snapdeb ,
                                                                      c_snapfin ,
                                                                      0
                                                                      )
                    )
 ;
-- curseur permettant de générer les informations correspondant au fichier html
-- Pour l'ensemble des instances de la base de données
--------------------------------------------------------------------------------
 cursor curs_awr_html_report (c_dbid NUMBER ,
                              c_instances VARCHAR2 ,
                              c_snapdeb NUMBER ,
                              c_snapfin NUMBER ) is
 SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_GLOBAL_REPORT_HTML (
                                                                      c_dbid ,
                                                                      c_instances ,
                                                                      c_snapdeb ,
                                                                      c_snapfin ,
                                                                      0
                                                                      )
                    )
 ;
begin
-- recherche des numéros de snapshoot
--------------------------------------
 select DBID,
        MIN(SNAP_ID),
        MAX(SNAP_ID)
   into lc_dbid ,
        lc_snap_debut,
        lc_snap_fin
   from dba_hist_snapshot
  where trunc(BEGIN_INTERVAL_TIME) = trunc(sysdate - 1)
  group by DBID;
-- génération des awr's
---------------------------
  for ind_boucle in lc_snap_debut .. lc_snap_fin
   loop
    snap_init := ind_boucle ;
    snap_suivant := ind_boucle + 1;
-- génération du nom de fichier
--------------------------------
    select 'awr_' ||to_char(BEGIN_INTERVAL_TIME,'YYYYMMDD_HH24MISS') || '.' || :gl_file_type
      into awr_file_name
      from dba_hist_snapshot
     where dbid = lc_dbid
       and snap_id = snap_init
       and rownum = 1;
    boucle := 0 ;
    lc_instance_liste :='';
    for liste in curs_instance_liste
     loop
      if boucle != 0
       then
        lc_instance_liste := lc_instance_liste || ',' ;
      end if;
      boucle := boucle + 1;
      lc_instance_liste := lc_instance_liste || substr(liste.inst_id,2);
    end loop;
    Num_fichier := Utl_File.Fopen( Repertoire, awr_file_name ,'W', 32000);
    if :gl_file_type = 'txt'
     then
      for ligne in curs_awr_text_report (lc_dbid,lc_instance_liste,snap_init,snap_suivant)
       loop
        Utl_File.Put_Line( Num_fichier,ligne.output);
      end loop;
     else
      for ligne in curs_awr_html_report (lc_dbid,lc_instance_liste,snap_init,snap_suivant)
       loop
        Utl_File.Put_Line( Num_fichier,ligne.output);
       end loop;
     end if;
     Utl_File.Fclose(Num_fichier);
   end loop;
 end;
 /

Voila, les fichiers sont générés, reste à passer à la phase d’analyse. Et là, c’est une autre histoire.
Une dernière remarque, les fichiers de type html sont intrinsèquement beaucoup plus volumineux et donc plus long à générer.

3 réflexions sur “Oracle Database Tuning – Génération automatique des fichiers AWR”

  1. Bonjour,
    j’ai lu attentivement votre article, et j’ai généré un ensemble de rapports en html.
    Le problème est que les rapports sont différents (notamment dans la forme) de ceux générés par : @?/rdbms/admin/awrrpt.sql
    Hafedh KADDACHI
    DBA Oracle
    http://hkaddachi.blogspot.fr/

    1. Bonjour,
      Qu’ils soient différents dans la forme, je n’en disconvient pas dans la mesure ou ces rapport prennent en compte les base de données en RAC.
      Ce qui est important, c’est de voir si le fond est identique, et donc si on retrouve bien les même infos.
      Cordialement,

      1. Merci pour votre réactivité.
        Je me demande comment changer votre script, pour qu’il donne le même résultat que awrrpt.sql ?
        voici le mien qui n’est pas une procédure stockée, mais un script qui se lance depuis sql*plus (tous les awr du 13/12/2012 entre 05h et 8h):
        set termout off
        set echo off
        set feedback off
        execute dbms_output.enable;
        set serveroutput on size 1000000;
        alter session set nls_language=american;
        spool reports_awr.sql
        declare
        varsnapid integer;
        varsnapid1 integer;
        varsnaptime char(12);
        varinstancename varchar2(30);
        varstartuptime date;
        varinstancenumber integer;
        varinstancenumber1 integer;
        cursor snap_ids is
        select snap_id, instance_number, to_char(END_INTERVAL_TIME, ‘YYYYMMDDHH24MI’), startup_time
        from dba_hist_snapshot
        where begin_interval_time between to_date (’13/12/2012 05:00:00′, ‘dd/mm/yyyy hh24:mi:ss’ ) and to_date (’13/12/2012 08:00:00′, ‘dd/mm/yyyy hh24:mi:ss’ )
        order by snap_id;
        begin
        select instance_name, instance_number
        into varinstancename, varinstancenumber
        from v$instance;
        OPEN snap_ids;
        LOOP
        FETCH snap_ids
        INTO varsnapid, varinstancenumber1, varsnaptime, varstartuptime;
        EXIT WHEN snap_ids%NOTFOUND;
        IF varinstancenumber1 = varinstancenumber
        THEN
        begin
        select snap_id
        into varsnapid1
        from
        (
        select snap_id
        from dba_hist_snapshot
        where snap_id > varsnapid
        and startup_time = varstartuptime
        and instance_number = varinstancenumber
        order by snap_id
        )
        where rownum < 2;
        EXCEPTION
        WHEN OTHERS THEN NULL;
        end;
        IF varsnapid < varsnapid1
        THEN
        dbms_output.put_line('define begin_snap='||to_char(varsnapid)) ;
        dbms_output.put_line('define end_snap='||to_char(varsnapid1)) ;
        dbms_output.put_line('define report_type=html') ;
        dbms_output.put_line('define num_days=1') ;
        dbms_output.put_line('define report_name=rep_awr_'|| varinstancename || '_' || varsnaptime||'.html') ;
        dbms_output.put_line('@?/rdbms/admin/awrrpt') ;
        END IF;
        END IF;
        end loop ;
        end;
        /
        spool off ;
        @reports_awr.sql

Les commentaires sont fermés.