Pages

lundi 10 février 2014

Statspack : générer une série de rapports automatiquement

Dernièrement j'ai dû générer tous les rapports statspack d'une journée. J'ai donc cherché sur le net une méthode pour automatiser cette tâche. J'ai alors trouvé ce post sur le forum "DBA Village".
J'ai complété la requête du post pour en faire la procédure ci-dessous. Celle-ci crée un fichier sql qu'il suffit ensuite de lancer sous sqlplus pour générer tous les rapports souhaités.
La procédure a 3 paramètres :
  1. Le snap_id de début
  2. Le snap_id de fin
  3. Un directory oracle.
Il faut également copier sous $ORACLE_HOME/rdbms/admin le script spreport.sql en spreport_automatic.sql et ajouter les lignes ci-dessous :

-----
define begin_snap  = &1;
define end_snap    = &2;
define report_name = &3;

@@sprepins
-----

Exemple pour générer tous les rapports entre le snap 1 et le snap 21 :

SQL> exec gen_snap_sql(1,21,'SNAP') ;

Dans le directory "SNAP", le fichier snap.sql est créé avec les lignes suivantes :

@?/rdbms/admin/spreport_automatic  1  2  sp_1_2_2014-02-01-1023.txt
@?/rdbms/admin/spreport_automatic  2  3  sp_2_3_2014-02-01-1025.txt
@?/rdbms/admin/spreport_automatic  3  4  sp_3_4_2014-02-01-1034.txt
@?/rdbms/admin/spreport_automatic  4  11  sp_4_11_2014-02-01-1044.txt
@?/rdbms/admin/spreport_automatic  11  12  sp_11_12_2014-02-01-1049.txt
@?/rdbms/admin/spreport_automatic  12  21  sp_12_21_2014-02-01-1056.txt


Il suffit alors d’exécuter sous sqlplus le fichier snap.sql pour générer l'ensemble des rapports entre le snap 1 et 21.

La procédure :

CREATE OR REPLACE PROCEDURE gen_snap_sql(
    minSnapId IN NUMBER,
    maxSnapId IN NUMBER,
    directory IN VARCHAR2)
IS
  v_file UTL_FILE.FILE_TYPE;
  v_buffer VARCHAR2(1000) ;
  CURSOR myCur
  IS
    SELECT z.begin_snap,
      z.end_snap,
      TO_CHAR(z.begin_time,'MM')
      ||'_'
      ||TO_CHAR(z.begin_time,'YYYY') snap_month,
      'sp_'
      || TRIM(TO_CHAR(z.begin_snap)
      ||'_'
      ||TO_CHAR(z.end_snap)
      ||'_'
      ||TO_CHAR(z.begin_time,'YYYY-MM-DD-HH24MI')
      || '.txt') report_name
    FROM
      (SELECT LAG(s.snap_id,1) OVER(ORDER BY s.snap_id) begin_snap,
        s.snap_id end_snap,
        LAG(s.snap_time,1) OVER(ORDER BY s.snap_id) begin_time,
        TO_CHAR(s.snap_time,'YYYY-MM-DD-HH24MI') snap_time
      FROM stats$snapshot s
      WHERE s.snap_id BETWEEN minSnapId AND maxSnapId
      ) z
  WHERE z.begin_snap IS NOT NULL
  AND EXISTS
    (SELECT 1
    FROM stats$snapshot h1,
      stats$snapshot h2
    WHERE h1.dbid          = h2.dbid
    AND h1.instance_number = h2.instance_number
    AND h1.snap_id         = z.begin_snap
    AND h2.snap_id         = z.end_snap
    AND h1.startup_time    = h2.startup_time
    )
  ORDER BY 1,2;
BEGIN
  v_file := UTL_FILE.FOPEN (directory, 'snap.sql', 'W');
  FOR myCur_record IN myCur
  LOOP
    v_buffer := '@?/rdbms/admin/spreport_automatic'||'  '|| myCur_record.begin_snap ||'  '|| myCur_record.end_snap||'  '|| myCur_record.report_name;
    UTL_FILE.PUT_LINE (v_file,v_buffer);
  END LOOP ;
  UTL_FILE.FCLOSE (v_file);
EXCEPTION
WHEN utl_file.invalid_path THEN
  dbms_output.put_line('Directory non valide');
WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('Erreur : '||sqlerrm);
END ;
/

Aucun commentaire:

Enregistrer un commentaire