L’erreur ORA-01555 signifie que la requête en cours d’exécution cherche à obtenir pour une donnée une image dans le temps qui n’est plus présente en base.
Il est donc très fréquent de trouver cette erreur pour des requêtes avec une durée d’exécution très longue. Cette information est remontée lorsque l’erreur survient (Query Duration = <durée> sec).
Pour une requête rapide, une autre cause possible est une forte activité transactionnelle, ayant pour conséquence une saturation du tablespace d’annulation, donc potentiellement une disparition très rapide des images dans le temps pour les transactions validées.
Mais il arrive aussi qu’aucune des deux situations ci-dessus ne se présentent, et que l’on ait tout de même à faire à une ORA-01555 pour une requête rapide. Comment analyser cette situation ?
Voici un exemple concret:
Mon Jun 15 02:58:48 2015 ORA-01555 caused by SQL statement below (SQL ID: 2ky0zqc7h049z, Query Duration=0 sec, SCN: 0x000c.54839232):
La requête en cause a bien une durée d’exécution inférieure à une seconde.
On vérifie que la partie gestion des segments d’annulation ne soit pas saturée sur cette période:
SQL>select begin_time, end_time, activeblks, unexpiredblks, expiredblks, tuned_undoretention, maxquerylen from v$undostat where '2015/05/15 02:58:48' BETWEEN BEGIN_TIME and END_TIME; BEGIN_TIME END_TIME ACTIVEBLKS UNEXPIREDBLKS EXPIREDBLKS TUNED_UNDORETENTION MAXQUERYLEN ------------------- ------------------- ---------- ------------- ----------- ------------------- ----------- 2015/06/15 02:52:42 2015/06/15 03:02:42 7696 47768 318328 1052 211
La rétention estimée à 1052 secondes, soit presque 18 minutes, et la présence d’un grand nombre de blocs expirés (c-à-d correspondant à des transactions terminées plus anciennes que la période de rétention définie par défaut à 15 minutes via le paramètre UNDO_RETENTION) nous confirment qu’il n’y a aucune saturation côté segments d’annulation.
L’erreur nous indique indirectement la date de l’image à laquelle la requête cherche à accéder, au travers du SCN (system Change Number, identifiant unique d’une entrée transactionnelle). Ici, il s’agit de ” SCN: 0x000c.54839232″
La fonction SCN_TO_TIMESTAMP permet de connaître le moment correspondant à ce SCN. Attention, la valeur indiquée dans l’erreur ORA-01555 est au format hexadécimal, et elle est parasitée par un caractère “point”, il faut donc convertir ici 000c54839232 en valeur décimale pour que SCN_TO_TIMESTAMP nous donne l’information correcte:
SQL>SELECT SCN_TO_TIMESTAMP(TO_NUMBER('000c54839232','xxxxxxxxxxxx')) FROM DUAL; SCN_TO_TIMESTAMP(TO_NUMBER('000C54839232','XXXXXXXXXXXX')) --------------------------------------------------------------------------- 15-JUN-15 02.10.16.000000000 AM
Notre requête, exécutée à 2h58:48 cherchait donc à obtenir une image de certaines données à 2h10:16 (date de l’ouverture de la transaction), soit plus de 48 minutes dans le passé. On est donc très loin des 15 minutes définies au niveau de l’instance.
Deux solutions donc pour résoudre ce problème:
- Augmenter la durée de rétention des images de données: augmenter la valeur du paramètre UNDO_RETENTION (900 secondes par défaut, modifiable par exemple à 3600 secondes, soit une heure)
- Comprendre pourquoi la transaction contenant la requête dure au moins 48 minutes, et tenter de réduire cette durée.
Continuez votre lecture sur le blog :
- Meltdown sur OLE 7 et performances (Capdata team) [Oracle]
- Retrouver la requête à l’origine d’une erreur 8623 “The query processor ran out of internal resources and could not produce a query plan” (David Baffaleuf) [SQL Server]
- Retrouver une transaction en échec (David Baffaleuf) [SQL ServerVintage]
- Query Store : bloquer les régressions de plans d’exécution et Capture Mode (Capdata team) [SQL Server]
- Suppression accidentelle de ligne : comment retrouver le coupable ? (David Baffaleuf) [SQL Server]