dimanche 27 janvier 2013

Où en est ma transaction?

Si après avoir exécuter ou rollbacker une grosse requête DML vous vous demandez au bout d'un certain temps "mais où en est ma transaction?" sachez qu'il existe une vue Oracle qui peut vous aider à répondre à cette question.

En effet la vue V$TRANSACTION et notamment les colonnes used_urec et used_ublk indiquent respectivement le nombre d'undo records et le nombre d'undo blocks en cours pour cette transaction. Ces informations ne concernent que les transactions en cours.

Voyons ça avec un exemple:
SQL> create table t1 as select * from dba_objects;

Table created.

SQL> insert /*+ append */ into t1 select * from t1;

79589 rows created. 

SQL> commit;

Commit complete.
 
SQL> insert /*+ append */ into t1 select * from t1;

159178 rows created.

SQL> commit;

Commit complete.

SQL> insert /*+ append */ into t1 select * from t1;

318356 rows created.
 
SQL> commit;

Commit complete.

SQL> insert /*+ append */ into t1 select * from t1;

636712 rows created.
 
SQL> commit;

Commit complete.

SQL> select count(1) from t1;

  COUNT(1)
----------
   1273424 

SQL> alter table t1 add UPDATED DATE;

 Table altered.

J'ai donc une table contenant 1 273 424 lignes.

J'ouvre maintenant une 2ème session pour interroger V$TRANSACTION:
 
-- session 2
SQL> select used_urec, used_ublk from v$transaction;

 no rows selected

Aucune ligne n'est retournée ce qui est normal vu que je n'ai aucune transaction en cours.
Je modifie maintenant la colonne UPDATED de ma table T1:
 SQL> update t1 set UPDATED=SYSDATE;
Allons voir ce que donne la vue V$TRANSACTION:
- session 2
SQL> select used_urec, used_ublk from v$transaction;

 USED_UREC  USED_UBLK
---------- ----------
    403450       3281

1 row selected.

SQL> select used_urec, used_ublk from v$transaction;

 USED_UREC  USED_UBLK
---------- ----------
    722550       5875

1 row selected.

SQL> select used_urec, used_ublk from v$transaction;

 USED_UREC  USED_UBLK
---------- ----------
   1238350      10068 

1 row selected.
 

SQL> select used_urec, used_ublk from v$transaction; 

 USED_UREC  USED_UBLK
---------- ----------
   1744083      14879

 1 row selected.

On se rend compte que les colonnes used_urec et used_ublk augementent ce qui indique que ma transaction est en cours d'exécution.
Une fois que l'update est terminé je regarde de nouveau le contenu de la vue:
SQL> select used_urec, used_ublk from v$transaction;

 USED_UREC  USED_UBLK
---------- ----------
   2546848      22598

 1 row selected.

Ma transaction a donc généré 2 546 848 undo records et 22598 undo blocks.

Maintenant si je rollback ma transaction les colonnes used_urec et used_ublk devraient avoir des valeurs qui diminuent jusqu'à atteindre 0:
-- session 1
SQL> rollback;


-- session 2
SQL> select used_urec, used_ublk from v$transaction;

 USED_UREC USED_UBLK
---------- ----------
 2375717 20953 

1 row selected.

SQL> select used_urec, used_ublk from v$transaction; 

 USED_UREC USED_UBLK
---------- ----------
 2211273 19371

 1 row selected.

Ces informations permettent d'avoir une idée sur ce qu'il reste à rollbacker.
Une fois le rollback terminé il n'y a plus de ligne correspondante dans V$TRANSACTION:
SQL> rollback; 

Rollback complete. 

-- session 2
SQL> select used_urec, used_ublk from v$transaction;

 no rows selected

Dans mon exemple je n'avais qu'une seule transaction en cours.
Dans un environnement de PROD vous aurez surement plusieurs transactions en cours dans votre base. Pour pouvoir obtenir la ligne dans V$TRANSACTION qui correspond à votre transaction vous pouvez utiliser une jointure avec V$SESSION via les colonnes ADDR et TADDR.

2 commentaires:

  1. Je cherchais une information sur v$transaction quand Google m'a envoyé ici. Cela m'a pris 2 min pour lire cet article et je dois dire que je l'ai beaucoup apprécié.

    Bien Cordialement
    Mohamed Houri

    RépondreSupprimer