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”
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/
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,
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