Chapitre 9

Chapitre 8 : La gestion des transactions


Dans les contextes multi-utilisateurs inhérents aux SGBD, développer des techniques performantes pour contrôler les accès partagés aux données de la base - en écriture comme en lecture - et pour assurer la persistance des écritures validées est indispensable.

Dans la première partie de ce chapitre, nous revenons d'abord sur la notion de transaction, nous présentons ensuite quelques exemples d'incohérences possibles en cas d'absence de contrôle de concurrence, puis nous exposons les différents mécanismes utilisés pour assurer le contrôle de concurrence dans un SGBD.

Dans la seconde nous voyons comment garantir l'intégrité physique des données validées en assurant une reprise correcte dans tous les cas de panne du système.

Enfin, nous évoquons rapidement, dans une troisième partie, les indicateurs standards utilisés pour la performance de la gestion des transactions et leur mesure sur bancs d'essai ("benchmarks").
 

VIII.1. Les propriétés transactionnelles des SGBD


Une transaction par définition est une séquence d'actions - c'est-à-dire de requêtes consultatives ou modificatives - sur les données de la BD, demandées par un même utilisateur et considérées par lui comme un tout indivisible. Cette séquence est à effectuer totalement ou pas du tout et, prenant la BD dans un état cohérent, elle doit la "rendre" dans un (nouvel) état cohérent. Ces propriétés d'atomicité et de consistance distinguent les transactions de n'importe quelle séquence d'actions - éventuellement réduite à une seule - sur la BD.

Une transaction a donc nécessairement un auteur, une marque de début "begin of transaction" (BOT) et une marque de fin "end of transaction" (EOT). Sa fin peut être négative - "annulation", "abandon", "abort" ou "rollback" - ou positive - "validation", "confirmation", "engagement" ou "commit", le choix du mot étant en général indifférent - le langage SQL n'en a retenu que deux COMMIT et ROLLBACK, mais peut laisser deviner que les points de vue de l'utilisateur et du SGBD sont différents.

Un utilisateur, au vu de considérations extérieures à la BD, décide finalement de confirmer/valider sa transaction, ce qui correspond toujours peu ou prou à un engagement signé et daté, ou au contraire de l'abandonner/annuler, ce qui correspond à son droit de regret . Le SGBD, pour sa part, peut ou non mener la séquence d'actions jusqu'au terme choisi par l'utilisateur. Il peut, soit en cours, soit au terme, être contraint de "défaire " ce qu'il a déjà fait pour le compte de cette transaction, quitte à refaire automatiquement ensuite. Une concurrence d'accès insoluble ou une panne peut en être la cause. Normalement, après une validation - COMMIT - de l'utilisateur, le SGBD doit garantir la propagation et la persistance des modifications demandées par la transaction. C'est la propriété de persistance ou durabilité des transactions.
 

VIII.2. La gestion de la concurrence


Comment le SGBD peut-il servir plusieurs utilisateurs ou, plutôt, plusieurs transactions simultanément?

Si ces transactions, a priori, ne concernent que des données logiquement différentes, le SGBD, qui dispose des ressources nécessaires et les gère correctement, peut "se couper en quatre" - ou plus! - pour les traiter. Il ordonnance de fait son travail pour donner l'apparence extérieure d'une exécution en parallèle. Par contre si les transactions sont logiquement en concurrence sur une ou plusieurs données communes (une ligne comptable, une place d'avion, etc...) le SGBD devra gérer une ou plusieurs files d'attente c'est à dire des exécutions en séries ordonnées. L'absence de contrôle de ces concurrences logiques conduirait à des interférences plus ou moins inacceptables.

VIII.2.1 Les interférences à éviter


VIII.2.1.1 entre écrivains

- "lost update" (ou perte d'opération)

Deux transactions accèdent à la même donnée D pour d'abord la lire. Puis la 1ère fait X = D + 1 et met à jour D par recopie de X. De son côté, la 2ème fait Y = D * 2, puis, après la 1ère, met à jour D par recopie de Y. La mise à jour faite par la 1ère transaction est perdue, c'est le dernier qui écrit qui a raison!
 
- "dirty write" (ou écriture inconsistante)
Une 1ère transaction modifie le crédit C d'un compte. Une 2ème lit C dans ce nouvel état, puis, constatant que la provision est suffisante, modifie le débit D du compte. Mais la 1ère fait un "rollback". La donnée D a désormais une valeur qui ne satisfait plus la contrainte d'intégrité D =< C c'est à dire que le solde est négatif!
 
VIII.2.1.2 entre lecteurs et écrivains

- "dirty read" (ou lecture inconsistante)

Une 1ère transaction, pour faire un virement entre deux comptes A et B, qui satisfait la contrainte d'intégrité "somme A+B invariante", commence par débiter A. Juste à ce moment une 2ème lit A puis B et trouve A+B diminué!
 
- "non-repeatable read" (ou lecture non reproductible)
Une 1ère transaction consulte les places libres dans un avion et laisse un temps de réflexion ("think time") à l'utilisateur. Une 2ème transaction, qui voit les mêmes places libres, valide deux réservations. La 1ère demande à nouveau les places libres: la liste est diminuée alors qu'elle n'a pas encore choisi ses réservations!
 
- "phantom read" (ou lecture fantôme)
Cas identique au précédent mais avec libération au lieu de réservation de place par la 2ème transaction. Il n'y a pas alors de conflit à proprement parler mais seulement interrogation sur la validité de ces "apparitions fantômes".
 

VIII.2.2 Les niveaux d'isolation

VIII.2.2.1 exécution sérialisable


Obliger les transactions concurrentes à s'exécuter en succession totale est assurément la plus forte isolation possible, mais aussi la plus pénalisante en temps de réponse car les temps morts et les actions sans concurrence logique, inclus dans ces transactions, sont inutilement mis en série. Il est donc intéressant de considérer la concurrence entre transactions au plus bas niveau possible, celui des actions qui les composent. Dans une même transaction certaines actions sont permutables si l'exécution des permutations donne le même résultat final. Certaines transactions sont compatibles si elles ne sont pas en concurrence logique. Une transaction T1 est dite précédente logique d'une transaction T2 si une action de T1 non permutable avec une action de T2 se présente la première . Si plusieurs transactions T1,T2, .., Tn doivent être considérées simultanément, le problème de précédence s'exprime par un graphe. Notons Ai1, Ai2,..,Aip les actions successives de la transaction Ti. Une exécution entrelacée sur le modèle:

A11,A21,A31,A12,A22,A23,A32,A13 est dite sérialisable si elle donne le même résultat qu'une exécution successive des transactions (que l'on pourrait reconstituer par permutation des actions compatibles ou permutables) respectant leur graphe de précédence. Si celui-ci est sans circuit, au moins une exécution sérialisable peut être trouvée. Elle assure, comme la succession, le meilleur niveau d'isolation possible, mais avec un temps de réponse global bien inférieur.
 
VIII.2.2.2 autres niveaux


Le standard SQL92 - alias SQL2 - prévoit une instruction SET TRANSACTION ISOLATION LEVEL <niveau> pour le niveau SERIALIZABLE défini ci-dessus, mais aussi pour trois autres niveaux d'isolation de plus en plus dégradés par rapport à celui-ci:

- REPEATABLE READ qui accepte les lectures fantômes (un nouveau venu dans une liste)
- READ COMMITTED qui accepte les lectures non reproductibles (on lit à tout moment tout ce qui est validé)

- READ UNCOMMITTED qui accepte les lectures inconsistantes (conséquences d'écritures non encore validées)
L'objectif de ces "relâchements" plus ou moins importants est évidemment d'augmenter le parallélisme apparent et le débit en transactions.

VIII.2.3 Les mécanismes utilisés

Dans le modèle physique les "tuples" sont des structures adressables d'octets. Un "gestionnaire de données" les charge dans un espace de la mémoire principale ou les en décharge, par des opérations élémentaires de lecture/écriture de "pages" - ou "blocs" - de données, pouvant contenir plusieurs "tuples", depuis ou vers des fichiers sur disque. Ainsi l'adresse physique de stockage d'un tuple est de la forme <fichier>,<page>,<offset>. Le "granule" de concurrence le plus souvent gérée par les SGBD est la page ou la page et l'offset - c'est à dire le tuple.

Le gestionnaire de transaction enchaine deux fonctions: (1) il découpe les transactions en actions élémentaires au niveau physique où est gérée la concurrence, puis (2) il ordonnance ces actions. Cet ordonnancement nécessite le calcul et le maintien d'un graphe de précédences a priori et/ou d'un graphe d'attentes a posteriori, puis le choix des séquences d'exécution selon le niveau d'isolation demandé et enfin la supervision de l'exécution. Un pré-processeur alimente l'ordonnanceur en flux parallèles d'actions. Ce dernier alimente le gestionnaire de données action par action et rend compte au pré-processeur de l'état instantané de chaque transaction: encours, suspendue, rejetée, validée.

Figure 8.1 Principe de gestion des transactions concurrentes.

VIII.2.3.1 verrouillage à deux phases ("two phases locking")

Dans un bon SGBD deux types de verrous peuvent être posés sur les granules de concurrence, pages ou tuples: le verrou exclusif - eXclusive lock - et le verrou partageable - Shared lock. Le premier autorise la transaction qui l'a posé sur un granule à continuer mais met en attente toute autre transaction qui voudrait ensuite lire ou écrire sur ce granule. Le second autorise par contre les lectures concurrentes. L'ordonnanceur a la charge de transformer les requêtes READ et WRITE qu'il reçoit du préprocesseur en requêtes SREAD ou XREAD et XWRITE, puis d'ajouter des requêtes SRELEASE ou XRELEASE selon les protocoles suivants:

Verrouillage en mode X (exclusif):

Une transaction T qui veut accéder à un granule de données D pour mise à jour doit d'abord faire un XREAD D qui a pour effet: si D est non verrouillé - ni au niveau X ni même au niveau S - alors de le verrouiller au niveau X sinon de suspendre l'exécution de T jusqu'au déverrouillage de D par la transaction concurrente qui l'avait verrouillé à ce niveau.
 
Verrouillage en mode S (partagé) : Une transaction T qui veut accéder à un granule de données D pour lecture reproductible doit d'abord faire un SREAD D qui a pour effet: si D est verrouillé au niveau X alors de suspendre l'exécution de T jusqu'au déverrouillage - XRELEASE - de D par la transaction concurrente qui l'avait verrouillé, sinon T est ajoutée à la liste des transactions qui ont verrouillé D au niveau S. T ne peut elle-même faire une mise à jour de D que par un XWRITE D qui tente de verrouiller au niveau X ce qui peut la suspendre jusqu' après le dernier SRELEASE de D des transactions concurrentes.
 
Restriction à deux phases
Le respect des deux protocoles précédents n'interdit pas des verrouillages et déverrouillages au fur et à mesure de la progression des transactions. Mais cela laisse la porte ouverte à de nombreux cas d'interblocage de toutes les transactions - appelés "verrous mortels" - ou de blocage éternel de quelques unes - appelés "famines". On démontre que si l'exécution de chaque transaction en deux phases seulement est imposée, une première pour tous les verrouillages - SREAD, XREAD ou XWRITE - une seconde pour tous les déverrouillages - SRELEASE, XRELEASE - sans qu'il soit possible de verrouiller à nouveau, il existe alors au moins une exécution globale sérialisable . De plus certains cas de verrou mortel ou de famine sont aussi implicitement résolus. Détection des verrous mortels résiduels Il n'en demeure pas moins des cas où le gestionnaire de concurrence ne peut que constater l'arrêt d'une exécution sur un verrou mortel. Il lui appartient alors de décider laquelle des transactions suspendues doit être rejetée - rollback - et, éventuellement, rejouée, si la sémantique de la transaction rejetée le permet. Ces cas sont heureusement détectables - par exemple en gérant un graphe des attentes effectives entre transactions. Ce graphe est très semblable au graphe des précédences - et la règle du choix de la victime exprime le genre de "politesse" que l'on veut pratiquer entre transactions "premières nées" et "dernières nées"...

Figure 8.2 "s'effacer devant l'ancien"

VIII.2.3.2 autre mécanisme

Le mécanisme de gestion des concurrences par verrouillage à deux phases détecte a posteriori des attentes entre transactions. Des mécanismes de prévention basés sur un ordonnancement a priori des actions composantes des transactions peuvent être aussi envisagés.

L'estampillage est un mécanisme du type prévention. Les transactions T reçoivent de l'ordonnanceur à leur début - Begin Of Transaction - une estampille qui est un numéro d'ordre de présentation en entrée de l'ordonnanceur. Chaque granule G de données note l'estampille de la dernière transaction qui y a accédé. Un granule n'accepte un nouvel accès que s'il est demandé par une transaction "plus jeune" - c'est-à-dire de numéro d'estampille plus grand.
 

PROCEDURE LIRE (T, G, X)                                 PROCEDURE ECRIRE (T, G, X)
DEBUT                                                                    DEBUT
SI Estampille(T) >= Estampille(G)                             SI Estampille(T) >= Estampille(G)
ALORS                                                                    ALORS
DEBUT                                                                    DEBUT
X <- lecture(G);                                                        écriture(G) <- X;

Estampille(G) := Estampille(T)                                    Estampille(G) := Estampille(T)

FIN                                                                           FIN
SINON rollback(T)                                                   SINON rollback(T)
FIN                                                                           FIN
 
La transaction rejetée est reprise par l'ordonnanceur après avoir reçu de lui une nouvelle estampille.

Un tel algorithme d'ordonnancement total conduit souvent à de nombreuses reprises en cascades, parfois par excès de prudence. Aussi a-t-on conçu des algorithme d'ordonnancement partiel qui distinguent pour chaque granule un compteur pour les estampilles des transactions accédant en lecture et un compteur pour les estampilles des transactions accédant en écriture, ou mieux qui distinguent des versions et les couples d'estampilles correspondantes pour chaque granule. S'ils améliorent clairement le débit transactionnel leur coût en écritures et en place mémoire n'est toutefois pas négligeable.

VIII.3. La gestion des reprises sur pannes

VIII.3.1 Les différents types de panne

Une panne est un évènement logique ou physique qui provoque une fin anormale de transaction - hors du cas normal d'abandon "conscient". On peut classer les pannes en: VIII.3.1.1 Panne de transaction du fait de la transaction elle-même (si elle demande une action illégale: une division par zéro ou une modification violant une contrainte d'intégrité) ou du fait du SGBD (si il ne peut résoudre un "dead-lock" dans la concurrence de deux transactions). Dans les deux cas, un rollback de la transaction peut être automatiquement déclenché et complètement effectué. VIII.3.1.2 Panne de système ou de mémoire principale, qui malheureusement est toujours "volatile": le système a en quelque sorte "perdu la mémoire" ou ne sait plus la relire correctement. Une des parties de la mémoire consacrée soit aux données, soit aux journaux, soit aux codes des gestionnaires eux-mêmes, est devenue illisible. Le système doit redémarrer "à chaud" à partir du dernier point de reprise ("checkpoint") qui correspond à une écriture en mémoire secondaire de toutes les pages mises à jour en mémoire principale. VIII.3.1.3 Panne de "media" ou de mémoire secondaire: un volume de disque ou un fichier ou certains blocs d'un fichier ne sont plus accessibles ou ne sont plus corrects. S'ils ne concernent que la base de données, on peut les reconstituer à partir du dernier "backup" (sauvegarde) qui correspond à une écriture sur un autre disque, ou sur une bande, de tout ou partie de la base de données physique et des journaux. C'est un redémarrage "à froid". S'ils concernent la base et tout ou partie des journaux depuis la dernière sauvegarde, la panne est dite "catastrophique" et seule une réparation manuelle par l'administrateur de la base est envisageable.
 

VIII.3.2 Les redondances nécessaires


VIII.3.2.1 Mémoires "sûres" et mémoires "fiables" (ou "à haute disponibilité")

Les mémoires sûres supposent que l'écriture physique d'une unité d'enregistrement ("page" ou "bloc") soit atomique, c'est-à-dire ou totalement et correctement exécutée ou pas exécutée du tout. Les mémoires fiables sont d'abord sûres et, de plus, se corrigent le plus souvent elles-mêmes des défaillances physiques, grâce à une redondance et des comparaisons systématiques.

Les mémoires secondaires fiables les plus répandues aujourd'hui utilisent la technologie RAID: Redundant Array of Inexpensive Disks.

VIII.3.2.2 Base de données, journaux, sauvegardes et archives Les mémoires secondaires doivent être de fiabilité croissante: si la base de données physique est non sûre, les journaux doivent être sûrs et les sauvegardes doivent être fiables . Mais, bien sûr, augmenter la fiabilité de toutes les mémoires secondaires améliore la disponibilité (une reprise à froid nécessite - sauf dans le cas de dispositifs de mémoires en miroir - un arrêt d'exploitation). Dans tous les cas on minimise les risques en utilisant au moins des disques différents pour la BD d'une part et les journaux et sauvegardes d'autre part.. Les archives sont soit des sauvegardes anciennes conservées pour usage historique, soit des déchargement partiels des parties les moins souvent accédées de la base de données, soit enfin des déchargements partiels ou des duplications partielles des journaux quand ils deviennent trop longs.

VIII.3.3 Les mécanismes utilisés

Ils sont tous basés sur le couple base de données et journaux. La base de données est toujours considérée sous son aspect physique. Parmi ses états successifs, deux sont des repères essentiels: ceux correspondant à une sauvegarde (duplication physique sur un autre volume de mémoire secondaire) et ceux correspondant à un point de reprise (recopie des pages mises à jour en mémoire principale vers la mémoire secondaire - "flush", faite si possible dans un temps mort transactionnel, c'est-à-dire sans transaction en cours). Le ou les journaux peuvent être conçus logiquement ou physiquement selon que l'on conserve la trace des transactions (pour défaire ou refaire) ou la trace des données modifiées (images avant ou après les transactions).

Figure 8.3 Principe de gestion des reprises après panne.

 


VIII.3.3.1 "do-redo-undo" (faire-refaire-defaire)

Logiquement "faire" l'exécution d'une transaction, comme d'un flux de transactions, c'est lire et écrire des données dans le cache prévu à cet effet dans la mémoire principale puis écrire sur le ou les journaux en mémoire sûre secondaire. Quelque soient les stratégies de transfert des pages de données de la mémoire principale vers la mémoire secondaire (écriture laissée à l'initiative du gestionnaire de cache, écriture forcée au commit, écriture différée jusqu'au prochain point de reprise automatique - en général déclenchée par le constat d'un journal assez long) deux règles doivent être respectées:
 

REFAIRE toujours possible: les IMAGES APRÈS mise à jour doivent être inscrites DANS LA MÉMOIRE SECONDAIRE (journal et éventuellement base de donnée) AVANT la fin de transaction EOT

DÉFAIRE toujours possible: les IMAGES AVANT mise à jour doivent être inscrites dans le journal correspondant AVANT que les IMAGES APRÈS soient transférées dans la base de données.
 

VIII.3.3.2 Stratégies

Elle sont logiquement quatre, mais les trois premières seulement sont pratiquement envisageables, selon qu'après une panne REFAIRE et DÉFAIRE sont nécessaires, REFAIRE seul ou DÉFAIRE seul est nécessaire, ni l'un ni l'autre ne sont nécessaires.

Considérons d'abord le cas où le dernier point de reprise correspond à un point mort hors transactions. Une panne non catastrophique de media est reprise à froid par rechargement de la dernière sauvegarde et déroulement du journal des IMAGES APRÈS - ou du REDO log - jusqu'au dernier point de reprise. Ensuite on est dans le même cas qu'une reprise à chaud qui correspondrait à une panne système intervenue après ce point. Il y a deux catégories de transactions à considérer alors, toutes ayant commencé après le point de reprise: celles qui avaient été validées avant, celles qui n'étaient pas encore validées. Comme en général on ne sait pas quelles pages mises à jour le gestionnaire de cache a ou n'a pas déjà transféré sur la base en mémoire secondaire, il faut d'abord DÉFAIRE les transactions non validées - en remontant le journal des IMAGES AVANT - jusqu'à leur début BOT, puis REFAIRE les transactions validées - en redescendant le journal des IMAGES APRÈS - jusqu'à leur fin EOT.

Considérons maintenant le cas où le dernier point de reprise avait eu lieu alors que des transactions étaient en cours: la méthode de reprise à chaud ne diffère que par l'étendue de la relecture des journaux car il faut remonter au début BOT de la plus ancienne transaction interrompue par la panne ou commise après le point de reprise mais avant la panne, ce qui pouvait être bien avant le point de reprise; la reprise à froid elle devra cette fois-ci nécessairement être suivie d'une reprise à chaud. Ainsi, pour garantir un redémarrage depuis une base cohérente, quelque ait pu être la cause de l'arrêt, tous les SGBD font toujours une reprise à chaud après le "startup".
 

VIII.4. Les bancs de mesure des performances ("benchmarks")


La question des performances transactionnelles a été déjà un peu évoquée ci-dessus en termes de temps de réponse et de "débit" de transactions. Définissons un peu plus précisément les grandeurs à mesurer:

- N = nombre d'utilisateurs actifs simultanément présents: dans une exploitation normale les utilisateurs ouvrent des sessions au cours desquelles ils effectuent des transactions successives. Du point de vue du SGBD, celles-ci sont seulement interrompues par les temps de lecture, de réflexion et de frappe de l'utilisateur (temps d'inactivité TI pour le système). Si les utilisateurs sont actifs, les sessions comme les transactions sont à tout instant N en parallèle.

- TR = temps de réponse moyen par transaction: supposons que la transaction est préparée par remplissage d'un écran qui est transmis en bloc au système, le cycle vécu par chaque utilisateur est un alternat: TI = utilisateur actif et système inactif, TR = utilisateur inactif et système actif. C'est ce deuxième qui constitue le temps réponse du système. La somme TI + TR représente un cycle transactionnel complet.

- TPS = débit de transaction (par unité de temps): si l'on considère le flux global de toutes les transactions, quelque soit l'utilisateur responsable, on peut en mesurer le débit à travers le système par unité de temps - généralement la seconde, d'où le nom Transaction(s)_Par_Seconde. Ce débit est d'autant plus grand que le "taux d'arrivée" est grand et le "temps de service" court.

Il est facile de vérifier que ces trois grandeurs sont liées par la formule de Little:
TPS = N / (TI + TR)
qui donne précisement la définition du débit d'un SGBD: nombre de transactions en cours divisé par temps de cycle moyen d'une transaction.

VIII.4.1 Mesures synthétiques et mesures analytiques

Le point de vue de l'utilisateur est toujours externe au système - "derrière" le terminal - et synthétique: il ne s'intéresse qu'à des performances globales - moyennes ou extrêmes (le "pire cas") - qui tiennent compte de tous les besoins: dispersion géographique des utilisateurs et des données, volume et distribution statistique des données, complexité du schéma et des requêtes, fiabilité des composants, etc... L'utilisateur doit prendre une décision d'achat et son cahier des charges spécifie en général une configuration pour une application type avec un volume minimum de données, des contraintes d'extrêmes sur les temps de réponse et la disponibilité. Il demande finalement des performances - et des rapports prix/performance - pour ce volume et pour plusieurs fois ce volume (dans le cas très probable où sa BD devra grandir avec le temps).

Le point de vue du constructeur est toujours interne au système et analytique du fonctionnement de chacun de ses composants. Pour lui, la performance globale n'est que le résultat de la performance combinée des sous-systèmes de gestion des mémoires, des reprises, d'ordonnancement des transactions, d'optimisation des plans d'exécution des requêtes et des "piles" de protocoles de communication - pour ne citer que les principaux. Pour les caractériser et pouvoir les prédire en exploitation il est amené à construire des bancs de test où, tous les autres sous-systèmes ayant des performances connues par ailleurs, un sous-système est soumis à un véritable plan expérimental. Il s'agira, pour lui, plus d'identifier les coefficients de formules de coûts que de mesurer les coûts les plus avantageux pour une charge de travail idéale.

Quelque soit le point de vue, les qualités attendues des bancs pour réaliser la mesure de ces performances - les "benchmarks" - sont les mêmes:

- pertinence: le benchmark doit bien spécifier le domaine et la signification de la performance qu'il entend mesurer; il doit être reproductible, étalonnable et le plus précis possible.

- portabilité: on doit pouvoir l'appliquer à une grande variété de configurations - pour comparer les résultats de plates-formes différentes sous un même SGBD, de SGBD différents sur une même plate-forme.

- dimensionnabilité: on doit pouvoir l'appliquer, pour une configuration donnée, à des tailles variables de BD et avec des quantités variables de ressources CPU et/ou disques, afin de tester les linéarités performance/volume BD à ressources constantes, performance/ressources à volume BD constant, volume BD/ressources à performance constante.

- simplicité: malgré les trois précédentes exigences, le benchmark doit rester simple à comprendre - au moins pour les "spectateurs" - et pas trop coûteux à implémenter pour les participants à la compétition!

VIII.4.2 Les benchmarks du Transaction Processing Council (TPC)

A fin des années 80, un "benchmark" pour les systèmes transactionnels était de plus en plus utilisé et ses résultats discutés tant par les utilisateurs et les journalistes spécialisés que par les constructeurs. Il était issu des propositions d'un article de Anon et al. de 1985 dans DATAMATION pour la mesure du "transaction processing power" des systèmes et portait le nom de "débit-crédit" ou "TP1".

Devant la bataille des chiffres sans juge ni arbitre qui fit rage alors, la plupart des grands constructeurs - une cinquantaine à ce jour - ont préféré se réunir en "concile" pour stabiliser, dans des spécifications longuement discutées et précisées dans le détail, et finalement soumises à un vote formel en 1990, les définitions de deux benchmarks inspirés du TP1: les TPC-A et B. Ces benchmarks bien que ne représentant qu'une application très simple - un guichet automatique de banque ne faisant que des retraits ou des dépôts - ont été considérés comme des références obligées par presque tous les éditeurs de SGBD et ont eu une grande influence sur leur compétition. Les tps-A ou B, débits exprimés en transactions par seconde conformément aux spécifications des benchmarks TPC-A ou B, et les rapports prix/performance exprimés en milliers de US$ par tps-A ou B, ont fourni les chiffres de palmarès largement diffusés par la presse, bien que tout le monde s'accordait déjà pour trouver l'application "débit-crédit" comme très peu représentative des applications réelles des utilisateurs professionnels: l'accès exclusivement article par article ne donne aucun avantage aux SGBD relationnels par rapport aux SGBD réseaux ni à ces derniers par rapport aux SGF séquentiels indexés traditionnels. Ainsi ces benchmarks sont vite apparus plus dépendants d' aspects système généraux - multiplexage des terminaux pour le TPC-A, rapidité et/ou parallélisation des accès disques pour le TPC-B - que d'aspects proprement SGBD - optimisation et gestion transactionnelle des données.

C'est pourquoi le TPC a mis en chantier deux autres spécifications l'une pour le "business transaction processing" avec le TPC-C (1992), l'autre pour le "decision support" avec le TPC-D (1995). Toutes deux offrent un schéma et des requêtes plus complexes et plus représentatifs des applications réelles. Leur sémantique commune est inspirée des applications de gestion de clients, commandes et stocks. Les métriques en sont respectivement des tpm-C (transactions par minute pour le TPC-C) et des qph-D (requêtes - queries - par heure pour le TPC-D). D'autres spécifications ciblant plus particulièrement les gros serveurs BD et les configurations clients-serveurs sont en cours de discussion.

VIII.4.3 Le réglage ( "tuning") des applications/SGBD réelles

Obtenir les meilleures performances d'une configuration complète - terminaux, système de communication, SGBD, OS, plate-forme mono ou multiprocesseurs, batterie de disques - est un art d'expert quand il s'agit des benchmarks de compétition, c'est un métier encore relativement complexe quand il ne s'agit "que" d'administrer des systèmes de bases de données réelles. Outre une excellente connaissance de la métabase - le "schéma des schémas" - et des outils de surveillance et contrôle en cours d'exploitation - "monitoring" - il faut à l'administrateur des règles et une stratégie pour les optimisations locales aux applications et globale au système - le fameux "débit". Ce qui nécessite un apprentissage lourd, d'autant plus qu'il n'existe pas de modèles de simulation et de prévision qui soient à la fois universels et détaillés.

Les éditeurs de SGBD eux-mêmes, ou des sociétés indépendantes d'ingénierie du logiciel, proposent des interfaces dédiées aux administrateurs de SGBD qui varient de la simple manipulation visuelle des données de la métabase à de véritables systèmes-experts dont la base de modèles et de règles peut être très riche - et chère!
 

VIII.5. Conclusions


Le concept de transaction donne aux Systèmes de Bases de Données toute leur dimension dynamique: l'exigence de cohérence à la fin de chaque transaction - et de consistance dans la suite des transactions - conduit à l'exigence de services de gestion de la concurrence et de gestion des reprises non seulement fiables mais performants.

On peut théoriquement imaginer que ces services soient assurés par des sous-systèmes différents, comme ceux de contrôles des droits sur les données, d'optimisation des requêtes et de controle d'intégrité, en amont, ainsi que celui de gestion des caches de données, en aval.

Leur implantation sur des architectures distribuées pousse dans ce sens. Mais le besoin de performance pousse au contraire à intégrer le plus possible ces services entre eux et avec le gestionnaire de cache. Enormément d'efforts de conception d'algorithmes nouveaux, de modélisation et de mesures de performances sont encore en cours, tant du côte des chercheurs que du côté des constructeurs, pour de nouvelles intégrations sur de nouvelles architectures.
 

VIII.6. Références


[Gardarin 82] G. Gardarin, Bases de Données: Les Systèmes et leurs Langages, Eyrolles, 1982

[Date 83] C.J. Date, An introduction to DataBase Systems - Volume 2 Addisson-Wesley, 1983

[Bernstein & al. 87] Ph.A. Bernstein, V. Hadzilacos and N. Goodman, Concurrency control and recovery in DataBase Systems, Addison-Wesley, 1987

[Gray 93] Jim Gray and Andreas Reuter, Transaction Processing: concepts and techniques, Morgan Kofmann, 1993

[Gray 93] Jim Gray editor, The Benchmarks HandBook for DataBases and Transaction Processing Systems - 2nd edition, Morgan Kaufmann, 1993



Chapitre 9