• Aucun résultat trouvé

MySQL - Administration et Transactions - Cours et TP

N/A
N/A
Protected

Academic year: 2022

Partager "MySQL - Administration et Transactions - Cours et TP"

Copied!
15
0
0

Texte intégral

(1)

BASES DE DONNÉES - Transactions - page 1/15 - Bertrand LIAUDET

Bases de données Transactions - ACID

Bertrand LIAUDET

LES TRANSACTIONS 2

Présentation des transactions 2

Présentation 2

Etat cohérent de la BD 2

Gestion des transactions par les SGBD 2

Propriétés ACID 3

Exemple 4

Atomicité : le problème des pannes 5

Principe : Start Transaction - Commit - Rollback 5

COMMIT implicite 5

Remarque : suspendre l’intégrité référentielle : attention : toujours dans une

transaction 5

Mode AUTOCOMMIT 6

Mode sans AUTOCOMMIT 6

Gestion de l’AUTOCOMMIT 6

Exemple - TP 7

Isolation : le problème de la concurrence 8

Présentation 8

Le problème 8

Exemple sans transaction : risque de double réservation 9 Exemple avec une transaction sans isolation (niveau 1 : read uncommited ) : risque

d’annulation complète 10

Les 4 niveaux d’isolation MySQL 11

Notion de verrou 12

Notion de deadlock 12

Conclusion 12

Consulter et modifier la valeur du niveau d’isolation : variable tx_isolation 13

Exemple – TP 14

Bibliographie 15

Edition : février 2020

(2)

BASES DE DONNÉES - Transactions - page 2/15 - Bertrand LIAUDET

LES TRANSACTIONS

Présentation des transactions Présentation

Une transaction est un ensemble de requêtes élémentaires du DML (insert, update, delete) qui doivent être exécutées ensemble pour maintenir la cohérence de la base.

L’objectif principal de la gestion des transactions est de maintenir la cohérence de la BD et de son usage.

Etat cohérent de la BD

Une BD est dans un état cohérent si les valeurs contenues dans la base vérifient toutes les contraintes d’intégrité définies sur la base.

Gestion des transactions par les SGBD

La gestion des transactions est un mécanisme standard SQL.

Attention, le moteur MyISAM ne gère pas les transactions.

Les moteurs InnoDB, Berkeley DB, NDB Cluster gèrent les transactions.

(3)

BASES DE DONNÉES - Transactions - page 3/15 - Bertrand LIAUDET

Propriétés ACID

Une transaction doit être ACID :

Atomique : tout ou rien.

Cohérente : maintenir la cohérence de la BD.

Isolée : être indépendantes des autres transactions.

Durable : ses effets doivent être persistants.

La durabilité est un principe de base des SGBD.

La cohérence est une conséquence des contraintes d’intégrité, de l’atomicité et de l’isolation.

On va donc surtout s’intéresser aux problèmes de l’atomicité et de l’isolation.

(4)

BASES DE DONNÉES - Transactions - page 4/15 - Bertrand LIAUDET

Exemple

Une transaction qui transfère 1000 Euros du compte A vers le compte B Cette transaction se déroule en deux étapes :

• Mettre à jour le compte A : ajouter une opération (date, montant, compte)

• Mettre à jour le compte B : ajouter une opération (date, montant, compte) La transaction

Mettre à jour le compte A 1. UPDATE comptes

SET balance = balance - 10000 WHERE no_compte = compteA;

// Mettre à jour le compte B 2. UPDATE comptes

SET balance = balance + 10000 WHERE no_compte = compteB;

Le problème

La base est cohérente si les deux instructions sont exécutées.

Il faut que les 2 instructions s’exécutent, ou rien.

Si la transaction "échoue" avant l’étape 2, alors la BD sera incohérente.

Echouer

Une transaction échoue si elle ne va pas jusqu’au bout de sa réalisation. Dans ce cas, on revient à l’état initial.

(5)

BASES DE DONNÉES - Transactions - page 5/15 - Bertrand LIAUDET

Atomicité : le problème des pannes

Principe : Start Transaction - Commit - Rollback

Pour être atomique, une transaction doit valider toutes ses requêtes élémentaires ou aucunes.

START TRANSACTION : permet de marquer le début de la transaction.

COMMIT : permet de valider la transaction : toutes les requêtes élémentaires sont désormais validées durablement.

ROLLBACK : tant que le COMMIT n’est pas exécuté, un ROLLBACK permet de revenir en arrière. C’est ce que fera automatiquement le système en cas de panne au milieu de la transaction. Le programmeur peut aussi le faire s’il le souhaite en fonction de la situation dans le programme.

COMMIT implicite

De nombreuses commandes implique un COMMIT implicite :

• START TRANSACTION

• Le passage en mode AUTOCOMMIT

• Le DDL : CREATE, ALTER, DROP, RENAME, pour tout objet.

• TRUNCATE TABLE (DROP + CREATE) : pour vider une table complètement.

• LOCK et UNLOCK TABLE : pour vérouiller une table.

Remarque : suspendre l’intégrité référentielle : attention : toujours dans une transaction Set @@foreign_key_cheks = 0 ; // suspend l’intégrité référentielle.

En suspendant l’intégrité référentielle, on peut saisir les données dans n’importe quel ordre. C’est à manier avec prudence et toujours au sein d’une transaction pour éviter que l’effet soit visibles par les autres clients.

(6)

BASES DE DONNÉES - Transactions - page 6/15 - Bertrand LIAUDET

Mode AUTOCOMMIT

• En mode AUTOCOMMIT, chaque requête est validée individuellement implicitement (un COMMIT a lieu après chaque requête automatiquement).

• C’est le fonctionnement par défaut de MySQL.

START TRANSACTION stoppe l’AUTOCOMMIT jusqu’au prochain COMMIT permettant ainsi la gestion d’une transaction.

Mode sans AUTOCOMMIT

• En sans mode AUTOCOMMIT, chaque requête de DML ouvre implicitement une transaction qui s’achèvera au prochain COMMIT.

• La requête suivante s’ouvrira alors de nouveau implicitement une transaction.

• En sans mode AUTOCOMMIT, un START TRANSACTION effectue un COMMIT de requêtes DML précédentes et commence une transaction.

ATTENTION : en sans mode AUTOCOMMIT, les modifications effectuées sur la BD par un autre client ne sont pas visibles tant qu’on n’a pas fait un COMMIT ou l’équivalent !

• CONCLUSION : mieux vaut rester en mode AUTOCOMMIT !!!

Gestion de l’AUTOCOMMIT

Afficher la valeur de l’AUTOCOMMIT

C’est une variable de niveau Serveur : on y accède par @@

Select @@autocommit; // 1 par défaut

Ou

Show variables like ‘%autocommit%’; // ON par défaut

Modifier la valeur de l’AUTOCOMMIT

La modification ne vaut que pour le client qui l’effectue.

Set @@autocommit=0 ; // mode sans autocommit

(7)

BASES DE DONNÉES - Transactions - page 7/15 - Bertrand LIAUDET

Exemple - TP

1. Ouvrez 3 clients.

2. Affichez l’autocommit dans chaque client.

3. Mettez l’autocommit du client 3 à 0. Affichez l’autocommit dans chaque client.

On va maintenant regarder l’effet du sans autocommit dans le client 3.

4. Créez la BD commit dans le client 1. Créez la table test(i int) dans la BD commit. Ajoutez 1 tuple de valeur 1 dans la BD test.

5. Affichez les tuples de la BD dans les 3 clients. Que constatez-vous ?

Réponse : Vous devez voir le tuple créé dans les 3 clients. En effet, le use database à l’effet d’un Commit.

6. Ajoutez un tuple 2 dans le client 1. Affichez les tuples de la BD dans les 3 clients. Que constatez-vous ?

Réponse : On ne voit pas le tuple dans le client 3.

7. Faites un commit dans le client 3. Affichez les tuples de la BD dans le client 3. Que constatez- vous ?

Réponse : On voit les tuples qui on été créés. Le commit à permit l’accès aux modifications de la BD pour le client sans autocommit.

On va maintenant gérer une transaction à partir du client 1.

8. Dans le client 1, démarrez une transaction et ajoutez un tuple 10 dans la BD test sans faire de commit.

9. Affichez les tuples de la BD test dans les 3 clients. Que constatez-vous ?

Réponse : Vous devez voir le tuple créé dans le client 1 mais pas dans les autres. En effet, la transaction n’a pas été commité : la modification n’est visible que pour le client 1.

10. Faites un comit dans le client 1 et affichez les tuples de la BD test dans les 3 clients. Que constatez-vous ?

Réponse : Vous devez voir le tuple créé dans le client 1 et 2mais pas dans le 3. En effet, la transaction a été validée : les résultats sont visibles à condition de ne pas être sans autocommit.

11. Faites un commit dans le client 3. Affichez les tuples de la BD dans le client 3. Que constatez- vous ?

Réponse : On voit les tuples qui on été créés. Le commit à permit l’accès aux modifications de la BD pour le client sans autocommit.

(8)

BASES DE DONNÉES - Transactions - page 8/15 - Bertrand LIAUDET

Isolation : le problème de la concurrence Présentation

Pour éviter que deux utilisateurs ne modifient en même temps une donnée, les instructions du DML, insert, update et delete, verrouillent les lignes sur lesquelles elles travaillent.

En contexte transactionnelle, cette gestion se complique du fait que la transaction traite plusieurs requêtes élémentaires.

Le « niveau d’isolation » qui va définir la visibilité des modifications en cours dans une transaction.

Le problème

• Si une transaction n’est pas isolée, un autre utilisateur voit les états intermédiaires avant le commit.

• Si une transaction est isolée, un autre utilisateur ne voit pas les états intermédiaires mais ne voit que l’état qui précède la transaction et le résultat du commit de la transaction.

(9)

BASES DE DONNÉES - Transactions - page 9/15 - Bertrand LIAUDET

Exemple sans transaction : risque de double réservation On va poser le problème à partir d’un exemple.

Soit un processus de réservation : on vérifie si c’est disponible (select), puis on réserve (update ou insert).

Pas de transaction

SESSION 1 SESSION 2

Vérification : Select : ok

Vérification : Select : ok Réservation : Update ou insert : ok

Réservation : Update ou insert : ok => bug ! La vérification 2 est faite avant l’update 1. Du coup, l’update 2 passe. A la fin on a une double réservation ou une réservation (la 1) qui est écrasée par la 2.

(10)

BASES DE DONNÉES - Transactions - page 10/15 - Bertrand LIAUDET

Exemple avec une transaction sans isolation (niveau 1 : read uncommited ) : risque d’annulation complète

La transaction sans isolation est dite « read uncommited » : une modification non « commitée » est visible par tous les clients (par toutes les sessions). On peut lire les « uncommités ». Par contre on ne peut pas les modifier.

Cas où ça fonctionne :

Avec une transaction, sans isolation, on commence par réserver. Chacun peut faire sa réservation : ca génère une double réservation.

Ensuite on vérifie. Si la vérification échoue, il y a un ROLLBACK et une annulation de la première réservation : c’est bon.

Read Uncommitted : cas où ca passe

SESSION 1 SESSION 2

Réservation : Update ou insert : ok

Réservation : Update ou insert : ok Verification : Select : pas ok car on voit la

résa de droite ROLLBACK

Verification : Select : ok car il n’y a plus de résa à gauche.

COMMIT

Cas où ça ne fonctionne pas :

Si la SESSION 2 vérifie avant le ROLLBACK de la SESSION 1 : la vérification ne sera pas OK aussi dans la SESSION 2 et on aura 2 ROLLBACK et aucune réservation !

La lecture (vérification) dans la SESSION 2 est dite « lecture sale » (dirty read) : c’est une lecture sale car elle lit ce qui va être rollbacké.

Read Uncommitted : cas ou ça ne passe pas

SESSION 1 SESSION 2

Réservation : Update ou insert : ok

Réservation : Update ou insert : ok Vérification : Select : pas ok car on voit la

résa de droite

Vérification : Select : pas ok car on voit la résa de gauche

ROLLBACK

ROLLBACK

(11)

BASES DE DONNÉES - Transactions - page 11/15 - Bertrand LIAUDET

Les 4 niveaux d’isolation MySQL

N° Nom Description Erreur évitée + risque

1 Read Uncommited Lecture de données non validées

Pas d’isolation. Une modif non commitée est visible par tous les clients (par toutes les sessions). On peut lire les « uncommités ». Par contre on ne peut pas les modifier.

Risque : lecture sale

2 Read Committed Lecture de données validées

Une modif n’est visible que par le client qui l’a faite (que par sa session). On ne peut lire que les « commités ».

Lecture sale

Risque : lecture non répétable

3 Repeatable-Read Lecture répétée

Niveau par défaut: idem précédent mais avec une lecture cohérente : on ne lit pas les commités par d’autres au cours de la transaction.

C’est le niveau par défaut d’INNODB. Il utilise des « snapshot » qui sont des copies de données pour garder l’état initial.

Lecture non répétable Risque : lecture fantôme

4 Serializable Comme le précédent, avec émulation de

transactions les unes après les autres. Lecture fantôme Lecture sale : on lit quelque chose qui n’est pas encore validée et qui ne le sera pas.

Lecture non répétable : on lit quelque chose qui change en cours de transaction.

Lecture fantôme : on a lu quelque chose qui va changer ou disparaître en cours de transactions sans qu’on soit au courant.

https://docs.postgresql.fr/9.4/transaction-iso.html

(12)

BASES DE DONNÉES - Transactions - page 12/15 - Bertrand LIAUDET

Notion de verrou

Un verrou bloque l’accès en lecture ou en écriture à une ligne ou à une table.

Les verrous de table peuvent être gérés manuellement par les commandes LOCK TABLES et UNLOCK TABLES pour optimiser certains traitements.

Les verrous de ligne sont gérés automatiquement par les transactions : les transactions posent des verrous sur les lignes qu’elles utilisent.

Notion de deadlock

Les verrouillages peuvent conduire à un « dead lock » : un verrou mortel qui fait que le système est bloqué.

Un verrou mortel (impasse) est une situation dans laquelle différentes transactions ne peuvent pas être exécutées car chacune détient un verrou dont l'autre a besoin. Étant donné que deux transactions attendent qu'une ressource devienne disponible, on ne peut plus libérer les verrous qu'elles détiennent.

Toutefois, un blocage, même sans dead lock, est limité dans le temps : la variable

@@innodb_lock_wait_timeout fixe la limite (50 secondes par défaut).

Conclusion

Avec les verrous et les snapshot, l’isolation MySQL est correctement gérée. Dans le pire des cas, les deadlock sont arrêtés automatiquement.

(13)

BASES DE DONNÉES - Transactions - page 13/15 - Bertrand LIAUDET

Consulter et modifier la valeur du niveau d’isolation : variable tx_isolation

Consulter la variable niveau GLOBAL et celle niveau SESSION

SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

Rappel : une variable GLOBALE vaut pour tous les clients. Une variable LOCALE ne vaut que pour le client concerné.

Ou

Show variables like ‘%isolation%’; // REPEATABLE-READ par défaut Show global variables like ‘%isol%’; // REPEATABLE-READ par défaut

Modifier la variable niveau GLOBAL et celle niveau SESSION

SET GLOBAL tx_isolation='REPEATABLE-READ';

SET SESSION tx_isolation='SERIALIZABLE';

Ici, le serveur reste dans la configuration par défaut (REPEATABLE-READ). Par contre, au niveau client on passe en SERIALIZABLE. Ce qui veut dire qu’on interdit tout parallélisme et qu’on fait les transactions l’une après l’autre. Ca peut être mieux si il y a un risque que des lectures s’avèrent fausses et génèrent un échec de transaction. En forçant la transaction l’une après l’autre, on évite ça.

Ou encore :

SET LOCAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;

Ici, le serveur et le client passe au plus bas niveau d’isolation.

A noter qu’un SET GLOBAL a un effet sur le serveur. Les futurs clients prendront en compte la nouvelle valeur du paramètre. Le SET LOCAL a un effet uniquement sur le client qui passe la commande.

(14)

BASES DE DONNÉES - Transactions - page 14/15 - Bertrand LIAUDET

Exemple – TP

1. Ouvrez 2 clients.

2. Affichez le niveau d’isolation local et global de chaque client.

3. Créez la BD isolation dans le client 1. Créez la table test(i int) dans la BD isolation. Démarrez une transaction. Créez 1 tuple de valeur 1 dans la BD test.

4. Affichez les tuples de la BD dans les 2 clients. Que constatez-vous ?

Réponse : Vous devez voir le tuple créé dans le client 1 et pas dans le client 2.

5. Commitez la transaction du client 1. Affichez les tuples de la BD dans les 2 clients. Que constatez-vous ?

Réponse : Vous devez voir le tuple créé dans les 2 clients.

6. Démarrez une transaction dans le client 1. Créez 1 tuple de valeur 2 dans la BD test. Updatez le tuple de valeur 1 de la table test dans le client 2. Que constatez-vous ? Attendez une minute.

Que constatez-vous ?

Réponse : L’update est bloqué dans le client 2. Au bout d’une minute, le blocage s’arrête sans fait l’update.

7. Affichez la valeur de la durée pour débloquer un verrou

Réponse : affichez @@innodb_lock_wait_timeout

8. Ajoutez un tuple de valeur 3 de la table test dans le client 2. Que constatez-vous ? Affichez les tuples de la table test dans le client 2.

Réponse : l’insert fonctionne. On peut afficher les résultats. On ne voit toujours pas le tuple 2.

9. Refaites un update des tuples en les passant tous à 1 dans le client 2. Tout de suite après, commitez le client 1. Affichez les tuples dans les 2 clients. Que constatez-vous ?

Réponse : l’update est bloqué dans le client 2. Quand on commite le client 1, ça débloque le client 2 : tous les tuples sont passés à 1.

(15)

BASES DE DONNÉES - Transactions - page 15/15 - Bertrand LIAUDET

Bibliographie MySQL :

http://bliaudet.free.fr/IMG/pdf/MySQL-refman-5.0-fr.pdf https://dev.mysql.com/doc/refman/5.5/en/

https://dev.mysql.com/doc/refman/5.6/en/

https://dev.mysql.com/doc/refman/5.7/en/

https://dev.mysql.com/doc/refman/8.0/en/

PostgreSQL

https://docs.postgresql.fr/9.4/tutorial-transactions.html https://docs.postgresql.fr/9.4/transaction-iso.html https://docs.postgresql.fr/9.4/mvcc.html

Autre cours :

https://makina-corpus.com/blog/metier/2015/bien-debuter-avec-les-transactions-sql

Références

Documents relatifs

(A-J) 1-isopropyl 2-méthylcyclohexane 1,1-dibromo 2-isopropylcyclopentane. 3-chloro 3-méthylcyclohexène

CREATE Serveur 2 : BD, Table Création (toutes les créations possible) DROP Serveur 2 : BD, Table Destruction de bases ou de tables ALTER Serveur 3 : Table

Lorsque vous faites une insertion, les données vont dans la première ou la dernière table (suivant la méthode d'insertion INSERT_METHOD=xxx) et cette table

On veut savoir si Mr.Lafleur a produit des AC anti-tétanos et savoir s'il est suffisamment protégé, c'est-à-dire si son sérum contient suffisamment d'AC.. Lafleur a produit des

▪ Une instance MongoDB peut avoir zéro ou plusieurs « bases de données ». ▪ Une base de données peut contenir zéro

On précise le format des entrées et des sorties dans un fichier de paramétrage, appelé fichier de contrôle, créé avec un éditeur de texte.. Un fichier log donnant les résultats

Create Table Nom_Table (Définition des attributs, Partition by Range (Attribut) (v. Partition Nom_P1 Values Less Than Int1, Partition Nom_P2 Values Less

Base de données Ensemble d'informations necessaire à la gestion d'un sujet Collecte d'information+Etude de l'existant Les Entités (objets) , liaison entre les entités Association