1. Générer un rapport AWR sur la période critique

L'Automatic Workload Repository (AWR) est votre meilleur allié. Il capture automatiquement des snapshots du workload toutes les 60 minutes. En production, je recommande de passer à 30 minutes pour les bases critiques.

-- Lister les snapshots disponibles
select snap_id,
       to_char(begin_interval_time, 'DD/MM HH24:MI') begin_time,
       to_char(end_interval_time,   'DD/MM HH24:MI') end_time
from   dba_hist_snapshot
order  by snap_id desc
fetch  first 20 rows only;

Repérez le snapshot qui précède le début de l'incident et celui qui couvre la période de dégradation. Générez le rapport :

@?/rdbms/admin/awrrpt

-- Choisissez le type (HTML de préférence)
-- Entrez begin_snap et end_snap
-- Validez le nom du rapport

Vous obtenez un rapport HTML complet. Dirigez-vous tout de suite vers la section Top 10 Foreground Events by Total Wait Time.

2. Lire les wait events — le vrai diagnostic

Les wait events vous disent ce que la base attend vraiment. Ne vous dispersez pas sur les autres sections avant d'avoir identifié le goulot principal.

Wait Event Cause probable
log file sync Commit trop fréquents ou I/O redo log lent
read by other session Contention sur les blocs — plusieurs sessions lisent le même bloc
buffer busy waits Contention sur un bloc chaud (hot block)
db file sequential read I/O index — généralement normal si pas en tête
db file scattered read Full table scan — requête non indexée
enq: TX - row lock contention Blocage applicatif — une transaction bloque les autres
enq: TM - contention Verrou DDL sur une table

Règle empirique : si un seul wait event représente plus de 40% du temps d'attente total, c'est lui qu'il faut attaquer en priorité.

3. Identifier le top SQL

Une fois le wait event identifié, descendez à la section SQL ordered by Elapsed Time. Les requêtes les plus consommatrices en temps sont listées avec leur SQL_ID. Prenez le premier.

Pour obtenir le plan d'exécution et les statistiques détaillées :

define begin_snap = <snap_debut>
define end_snap   = <snap_fin>
define sql_id     = '<sql_id>'
define report_name = rapport_sql_probleme

@?/rdbms/admin/awrsqrpt

Ce rapport vous montre le plan d'exécution, les statistiques par exécution, et l'évolution des performances entre les deux snapshots. Regardez en particulier le nombre d'exécutions et le temps par exécution.

4. Creuser avec Statspack (sans licence Diagnostic Pack)

Vous n'avez pas le Diagnostic Pack Oracle ? Statspack est l'outil gratuit fourni avec Oracle Database. Il fait le même travail qu'AWR sans licence supplémentaire. Je l'utilise encore régulièrement chez des clients qui n'ont pas souscrit aux options de tuning Oracle.

Planifier les snapshots Statspack

-- Exécution automatique toutes les 15 minutes
dbms_job.submit(:jobno, 'statspack.snap;',
  trunc(sysdate+15/1440,'MI'),
  'trunc(SYSDATE+15/1440,''MI'')',
  TRUE, :instno);

Référence des intervalles courants :

Intervalle Expression
Toutes les heures sysdate+1/24
Toutes les 30 min sysdate+1/48
Toutes les 15 min sysdate+15/1440
Toutes les 10 min sysdate+10/1440

Générer un rapport Statspack

-- Lister les snapshots
select snap_id, snap_time, snap_level
from stats$snapshot order by 2;

-- Générer le rapport
@?/rdbms/admin/spreport

Requêtes avancées sous Statspack

Pour aller plus loin, Statspack stocke les données dans des tables STATS$* que vous pouvez interroger directement :

-- Vérifier un paramètre qui a changé
select * from STATS$PARAMETER
where name='audit_trail'
order by SNAP_ID;

-- Suivre l'évolution d'une ressource
select * from stats$resource_limit
where resource_name='processes'
order by snap_id;

-- Récupérer le SQL complet depuis son hash value
select sql_text
from STATS$SQLTEXT
where old_hash_value=&hash_value
order by piece asc;

5. Le plan d'exécution — validation finale

Une fois le SQL identifié, validez son plan d'exécution. Un changement de plan (plan_hash_value différent) est une cause fréquente et soudaine de dégradation.

-- Voir les plans utilisés par une requête
select plan_hash_value, count(*)
from stats$sql_plan_usage
where old_hash_value = &hash_value
group by plan_hash_value;

-- Afficher le plan
select * from stats$sql_plan
where plan_hash_value = &phv;

Si le plan a changé, les causes possibles sont : statistiques obsolètes, modification du paramètre optimizer_mode, ou apparition d'un SQL profile non souhaité.

Checkbook en 10 minutes

  1. Min 0-2 — Générer le rapport AWR ou Statspack sur la période
  2. Min 2-4 — Identifier le wait event principal (>40%)
  3. Min 4-6 — Descendre dans le Top SQL, noter le SQL_ID
  4. Min 6-8 — Vérifier le plan d'exécution et son historique
  5. Min 8-10 — Rédiger le diagnostic et les recommandations

Ce workflow n'est pas théorique — c'est celui que j'applique depuis plus de 20 ans sur des bases allant de quelques Go à plusieurs To, dans des contextes exigeants (banque, santé, collectivités). Il a fait ses preuves.

À retenir : ne partez pas dans tous les sens. Lisez d'abord les wait events. Le reste découle de ce diagnostic.

Yacine Oumghar · DBA Oracle depuis 1998 Retour au blog