Cet article est la traduction d’une réponse Tom Kyte à une question sur les vues cohérentes (L’article original en anglais se trouve ici).
Question:
J’ai lu qu’Oracle garantit une vue cohérente en lecture. Je l’ai lu, mais je n’ai pas l’impression que c’est très clair.
Pouvez-vous expliquer, avec vos mots, ce qu’est une vue cohérente ?
Réponse:
J’ai fais cela dans « Expert One on One Oracle« .
J’ai écrit beaucoup là dessus et voici un court extrait (il y a beaucoup plus dans le livre).
Extrait de ‘Expert One on One Oracle’ de Tomas Kyte – Apress
Multi-Versionnage et Concurrence
Le Multi-versionnage (multiversioning) est un sujet lié au contrôle de concurrence d’accès aux données, car qu’il est à la base de ce mécanisme: Oracle implémente la concurrence d’accès en faisant des lecture multi-versions cohérentes (multi-version read consistent concurrency model). Dans le chapitre suivant ‘Ce que vous devez savoir’, nous allons parler des aspects techniques de manière plus détaillée, mais dans l’essentiel, il s’agit du mécanisme fourni par Oracle pour:
- faire des lectures cohérentes (Read-consistent queries): les requêtes donnent un résultat cohérent à un instant donné.
- Requêtes non bloquantes (Non-blocking queries): les requêtes en lecture ne sont jamais bloquées par les écritures, contrairement à ce qui se passe avec d’autres SGBD.
Oracle utilise l’information des rollback segments (ou undo) pour fournir une vue cohérente sur les données. Les rollback segments étant l’endroit où Oracle stocke les anciennes valeurs (ou ‘image avant’) des données lors de l’exécution des transactions, il peut utiliser ces anciennes valeurs pour fournir à la requête les données telles qu’elles étaient en base au moment où la requête a été lancée. Au fur et à mesure que la requête lit les blocs de données de la table, elle voit si le bloc a été modifié depuis l’instant où la requête a commencé. Et si le bloc a été modifié, Oracle va aller lire les rollback segments pour retrouver à quoi ressemblait le bloc au moment où la requête a commencé. C’est cette version que la requête va voir.
C’est aussi de cette manière que les lectures non bloquantes (non blocking reads) sont implémentées. Oracle va seulement regarder si les données ont été modifiées, il n’a pas besoin de savoir si elles sont verrouillées (ce qui implique qu’elles ont été modifiées). Il va simplement ramener les anciennes valeurs grâce aux rollback segments et passer au bloc de données suivant.
C’est là qu’intervient le terme multi-versionnage (multiversioning): chaque information a plusieurs versions en base de données, chacune correspondant à un instant donné. Ces versions multiples sont fournies par l’undo des rollback segments. Oracle est capable d’utiliser ces ‘photos’ des données correspondant à différents instants (appelées snapshot comme dans le message d’erreur ‘ORA-15555 snapshot too old’), pour nous donner une version cohérente avec des lectures non bloquantes.
Ce sont deux concepts très importants pour le SGBD Oracle. Si vous comprenez comment le multi-versionnage fonctionne, vous comprendrez toujours les réponses que vous obtiendrez de la base de données.
Voici le moyen le plus simple que je connaisse pour démontrer le multi-versionnage sous Oracle:
tkyte@TKYTE816> create table t
2 as
3 select * from all_users;
Table created.
tkyte@TKYTE816> variable x refcursor
tkyte@TKYTE816> begin
2 open :x for select * from t;
3 end;
4 /
PL/SQL procedure successfully completed.
tkyte@TKYTE816> delete from t;
18 rows deleted.
tkyte@TKYTE816> commit;
Commit complete.
tkyte@TKYTE816> print x
USERNAME USER_ID CREATED
------------------------------ ---------- ---------
SYS 0 04-NOV-00
SYSTEM 5 04-NOV-00
DBSNMP 16 04-NOV-00
AURORA$ORB$UNAUTHENTICATED 24 04-NOV-00
ORDSYS 25 04-NOV-00
ORDPLUGINS 26 04-NOV-00
MDSYS 27 04-NOV-00
CTXSYS 30 04-NOV-00
...
DEMO 57 07-FEB-01
18 rows selected.
Dans cet exemple, nous avons créé une table de test, T
, et avons chargé quelques données à partir de la vue ALL_USERS.
Nous avons ouvert un curseur sur cette table. Nous n’avons fetché aucune donnée de ce curseur: nous l’avons seulement ouvert. Gardez en tête que Oracle ne ‘réponds’ pas à la requête, ne copie pas les données quelque part lorsque vous ouvrez le curseur. Il réponds à la requête plus tard.
Mettons que la table T
ait 1 milliard d’enregistrements, Oracle ne va pas ‘répondre’ à la requête et copier les données quelque part. Il va seulement les lire au fur et à mesure que l’on va faire les fetch.
Maintenant, dans la même session (mais cela pourrait être fait d’une autre session), nous supprimons toutes les données de cette table. Nous allons même jusqu’à commiter cette transaction.
Les enregistrement sont partis, mais est-ce vraiment le cas ?
Le fait est que le résultat retourné par la commande OPEN a été pré-établi au moment où nous avons ouvert le curseur. Nous n’avions pas encore touché à un seul bloc de données de cette table durant l’OPEN, mais le résultat de la requête était déjà déterminé. Nous n’avons aucun moyen de connaître le résultat avant de faire les FETCH, mais ce résultat est pourtant immuable du point de vue du curseur.
Oracle n’a pas fait une copie des données lorsque nous avons ouvert le curseur. Imaginez le temps que cela prendrait d’ouvrir un curseur sur un milliard d’enregistrements si c’était le cas. Au contraire, le curseur s’ouvre instantanément – il ne copie pas les données. C’est en fait le delete qui garde les données pour nous (oui, le delete préserve les données pour nous) en les mettant dans les rollback segment.
Voilà ce qu’est la lecture cohérente. Oracle permet des lectures cohérentes grâce au mécanisme de multi-versionnage. Dans le chapitre suivant ‘Ce que vous devez savoir’, nous allons parler des aspects techniques de manière plus détaillée. Il faut noter cependant que jusqu’à ce que vous ne compreniez ce que cette fonctionalité implique, vous ne serez pas capable de profiter à fond d’Oracle, ni d’écrire des applications correctes (c’est à dire qui assurent l’intégrité des données).
fin de l’extrait
La documentation Oracle Concept Guide explique aussi cela très bien.
Le livre en Anglais de Tom Kyte dont est extrait l’article original:
Expert Oracle Database Architecture: 9i and 10g Programming Techniques and Solutions
Apress (September 15, 2005)