Académique Documents
Professionnel Documents
Culture Documents
MySQL Cluster est un SGBD open source adaptable, conçu pour fournir des performances
et une disponibilité élevée à de nombreux types d’applications métier. Par exemple, MySQL Cluster
pilote les bases d’abonnés des principaux fournisseurs de services de télécommunication et est
utilisé au niveau mondial pour la détection des fraudes dans les transactions financières.
InnoDB, qui assure la sécurité des transactions et est conforme au concept ACID, est le
moteur de stockage par défaut de MySQL depuis la version 5.6. Les autres moteurs sont MyISAM
(pour le Web et les entrepôts de données), Memory (pour les traitements In-Memory), CSV (pour le
texte) et Archive.
2. Installation de MySQL
➢ Après avoir téléchargé vous cliquez sur Custom pour personnaliser l’installation,
ensuite on choisit le type de version (8.0.31). Choisir une configuration de
développement cad la base de données ne sera pas accessible à distance et par
défaut il faut laisser les informations de base concernant les ports(3306 et 33060).
➢ Pour éviter les problèmes de compatibilité il faut choisir les authentifications
classiques (use legacy authentification method).
Ensuite choisir le nom et le mot de passe (root est préférable et plus facile)
➢ Pour que la commande MySQL fonctionne en invite de commande ou sur power
Shell, nous devons modifier les variables d’environnement dans les paramètres de
votre ordinateur, plus précisément le PATH et y ajouter le chemin vers la commande
mysql.exe qui se trouve dans le dossier bin dans le dossier d’installation MySQL.
(Même chose pour maria DB)
II. Les outils d’administration MySQL
Les bases de données agissent comme un référentiel d’informations central auquel les
programmes ou services Web autorisés peuvent accéder, compléter ou modifier. Des
professionnels appelés administrateurs de bases de données sont en charge de la mise en
place et de la maintenance de ces serveurs logiciels spécialisés.
Les outils d’administration de base de données sont des programmes spécialisés qui leur
permettent d’accéder, de modifier et de mettre à jour le logiciel et les configurations de
base de données.
Dans le monde de la programmation informatique, un serveur est un programme dont le
but est de fournir des informations à d’autres logiciels appelés clients. Un serveur peut
fonctionner sur sa propre machine, à laquelle les clients accèdent via Internet ou un réseau
local. Un serveur peut également s’exécuter en tant que programme d’arrière-plan sur la
même machine que ses programmes clients. Le logiciel de base de données fonctionne
comme un serveur qui écoute sur un port spécifique les connexions entrantes des
programmes clients qui souhaitent accéder aux informations qu’il détient.
❖ Les outils d’administration de base de données que les professionnels utilisent pour
maintenir les bases de données en cours d’exécution sont des programmes distincts
et ne font pas partie du logiciel de base de données lui-même. Les administrateurs
de base de données utilisent ces outils pour émettre des commandes auxquelles un
logiciel de base de données particulier est programmé, pour reconnaître et
répondre par une action correspondante. Bien que la syntaxe exacte de ces
commandes varie d’un logiciel de base de données à l’autre, les actions qui
peuvent être effectuées à l’aide de celles-ci incluent :
Les administrateurs système les plus efficaces utilisent les bons outils de gestion de
base de données.
Nous vivons à l'ère des données et chaque entreprise a besoin d'une équipe
d'administrateurs système capables de gérer et d'organiser des bases de données très
complexes.
Il existe des tonnes d'outils obsolètes qui sont encore utilisés dans l'industrie. Donc,
pour aider les débutants et les experts, les outils suivants vous aideront à faire un travail
remarquable dans la gestion des bases de données.
c) DBDesigner
DBDesigner est un système de conception de base de données visuel qui intègre la
conception de base de données, la modélisation, la création et la maintenance dans un
environnement unique, homogène. Il combine des fonctionnalités professionnelles et une
interface utilisateur simple et claire et permet d'offrir le moyen le plus efficace pour gérer
vos bases de données.
DBDesigner est développé et optimisé pour la base de données open source MySQL
pour aider les utilisateurs de MySQL avec un outil de conception disponible puissant et
gratuit.
d) MySQL Workbench
MySQL Workbench est un outil visuel unifié pour architectes, développeurs et
administrateurs de base de données. MySQL Workbench permet la modélisation des
données, le développement SQL et des outils d'administration complets pour la configuration
des serveurs, l'administration des utilisateurs et davantage. MySQL Workbench est disponible
sous Windows, Linux et Mac OS. MySQL Workbench remplace MySQL Query Browser et MySQL
Administrator.
f) MySQL Front
MySQL-Front est un logiciel graphique de gestion de bases MySQL. On peut
directement manipuler les bases, tables, champs et données par le biais de l'interface
graphique mais également transmettre des scripts SQL au SGBD MySQL. MySQL Front
n'est toutefois disponible que sous Windows et il n'y a qu'une version de démonstration
de 30 jours disponible en téléchargement.
g) Spotlight on MySQL
Spotlight on MySQL est un outil de monitoring et de diagnistic en temps réel pour
les serveurs MySQL sur plateforme Windows. Il n'est valable qu'à partir de la version 5.0
de MySQL, et uniquement sur le moteur InnoDB. Néantmoins, il fournit d'importantes
sources d'informations sur les flux de données d'une base, et de puissants outils visuels
de diagnostic.
h) dbForge Studio
dbForge Studio est un outil d'administration et un environnement de
développement pour MySQL. Ses fonctionnalités permettent une exploration rapide
des bases de données, la gestion des objets dans les bases, la gestion des comptes
et privilèges, le développement de routines et la synchronisation entre bases.
Disponible uniquement sous Windows, il nécessite l'installation préalable du .NET
Framework 2.0, 3.0 ou 3.5.
i) HeidiSQL
HeidiSQL est le successeur libre de MySQL-Front. Son interface graphique permet
de gérer des serveurs MySQL : manipulation des variables serveurs, des bases, tables,
vues, champs et données, import et export de données par le biais de l'interface
graphique, ainsi que la création, l'édition et l'exécution de scripts SQL. HeidiSQL est
disponible sous Windows ainsi que sous Linux (par l'intermédiaire de Wine).
a) Quest
Quest Software, fondée en 1987, reste l'un des fournisseurs de solutions informatiques les
plus fiables à l'ère actuelle du développement logiciel.
Leurs principaux produits sont outils de gestion de base de données. La meilleure chose à
propos de Quest est le ciblage de chacun de leurs produits. Cela signifie que chaque
plate-forme ou base de données mérite son propre ensemble de boîtes à outils spécifiques.
Par exemple, si votre entreprise est fortement basée sur la base de données Cassandra,
vous pouvez opter pour le produit spécialisé Projecteur antibrouillard pour Cassandra.
Fonctionnalités
Vous pouvez voir une grande liste de solutions de gestion de base de données sur le Page
des produits Quest.
b) ManageEngine
ManageEngine offre des outils de surveillance de base de données solides orientés pour
optimiser les performances des bases de données. Ces outils de surveillance vous
informent non seulement en cas de problème, mais vous aident à résoudre rapidement
les problèmes.
Ils offrent une solution spécifique pour chaque type de base de données. Alors, si vous
recherchez un outil de surveillance optimisé pour votre base de données, n'hésitez pas à
passer en revue les solutions ManageEngine.
Fonctionnalités
c) Sequel Pro
Si tel est bien le cas, Sequel Pro est le bon système de gestion de base de données pour
vous. C'est un projet open source qui vous donne un accès direct aux bases de données
MySQL locales et distantes.
La meilleure partie de cet outil est sa simplicité et le fait qu'il est vraiment léger. En
conséquence, vous pouvez rapidement configurer cet outil sur n'importe quelle machine
Mac.
d) PHPMyAdmin
PhpMyAdmin est un outil d'administration gratuit construit avec PHP, · Il peut effectuer un
grand nombre d'opérations avec MySQL et Bases de données MariaDB.
Vous pouvez utiliser l'interface graphique ou utiliser des séquences SQL pour effectuer la
bonne gestion de la base de données.
Cet outil a gagné plusieurs prix de 2002 à aujourd'hui. En outre, il a une documentation
approfondie et un livre traduit en anglais et en espagnol.
Fonctionnalités
• Gratuit et open-source
• Prise en charge des bases de données MySQL et MariaDB
• Interface Web intuitive
• Importer des données et exporter des données (CSV et SQL)
• Traduit dans les langues 72
• Effectuer des tâches administratives
• Administration de plusieurs serveurs.
La gestion de bases de données est devenue l'une des compétences les plus exigeantes
de la dernière décennie. Ceci, en raison de la quantité croissante de données, chaque
entreprise doit se développer et réussir.
Lors de la recherche des meilleurs outils pour gérer efficacement bases de données, nous
proposons des plates-formes gratuites et payantes. Vous pouvez choisir celle qui vous
convient le mieux en fonction de vos besoins en tant qu'administrateur système ou des
besoins de l'entreprise pour laquelle vous travaillez.
1. Architecture de MySQL
MySQL est un système de gestion de base de données relationnelle qui est un logiciel
libre Open Source sous licence GNU. Il est également pris en charge par Oracle
Company. Il est rapide, évolutif, facile à utiliser système de gestion de base de données.
MYSQL prend en charge de nombreux systèmes d’exploitation comme Windows, Linux,
MacOS, etc. MySQL est un langage de requête structuré qui est utilisé pour manipuler,
gérer et récupérer des données à l’aide de diverses requêtes. MySQL est développé et
supporté par MySQL AB qui est une société suédoise et écrit en C et C ++. Il a été
développé par Michael Widenius et David Hughes. Il est souvent utilisé pour dire que
MYSQL est nommé d’après le nom de la fille du co-fondateur MIchael Widenius dont le
nom est ‘My’.
L’architecture de MYSQL décrit la relation entre les différents composants du système
MYSQL. MYSQL suit l’architecture client-serveur. Il est conçu de manière à ce que
l’utilisateur final qui est Clients puisse accéder aux ressources de l’ordinateur qui est
serveur à l’aide de divers services de mise en réseau. L’architecture de MYSQL contient
les couches principales suivantes. :
•Client
•Serveur
• Couche de stockage
Couche client :
Cette couche est la couche supérieure du diagramme ci-dessus. Le client donne des
instructions de demande au service à l’aide de la couche client. Le client effectue une
demande via l’invite de commandes ou via l’écran GUI en utilisant des commandes et
des expressions MYSQL valides. Si les expressions et les commandes sont valides, la sortie
est obtenue à l’écran. Certains services importants de la couche client sont :
• Gestion de connexion (Lorsqu’un client envoie une demande au serveur et que le
serveur accepte la demande et que le client est connecté. Lorsque le client est
connecté au serveur à ce moment-là, un client obtient son propre thread pour sa
connexion. Avec l’aide de ce thread, toutes les requêtes côté client sont
exécutées)
• Authentification (L’authentification est effectuée côté serveur lorsque le client est
connecté au serveur MYSQL. L’authentification se fait à l’aide du nom d’utilisateur
et du mot de passe.)
• Sécurité (Après l’authentification, lorsque le client se connecte avec succès au
serveur MySQL, le serveur vérifie qu’un client particulier dispose des privilèges
nécessaires pour émettre certaines requêtes sur le serveur MySQL.)
Couche serveur :
La deuxième couche de l’architecture MYSQL est responsable de toutes les
fonctionnalités logiques du système de gestion de base de données relationnelle de
MYSQL. Cette couche du système MYSQL est également connue sous le nom de
« Cerveau de l’architecture MYSQL ». Lorsque le client donne des instructions de
demande au serveur et que le serveur donne la sortie dès que l’instruction est mise en
correspondance. Les différents sous-composants du serveur MYSQL sont:
- Gestion des threads : Lorsqu’un client envoie une requête au serveur et que le serveur
accepte la demande et que le client est connecté. Lorsque le client est connecté au
serveur à ce moment-là, un client obtient son propre thread pour sa connexion. Ce
thread est fourni par la gestion des threads de la couche serveur. De plus, les requêtes
côté client qui sont exécutées par le thread sont également gérées par le module
Thread Handling.
-Parser : Un Parser est un type de composant logiciel qui construit une structure de
données (arbre d’analyse) d’entrée donnée. Avant d’analyser l’analyse lexicale, c’est-
à-dire que l’entrée est divisée en nombre de jetons. Une fois que les données sont
disponibles dans les éléments plus petits, analyseur effectuer l’analyse syntaxique,
l’analyse sémantique après que l’arbre d’analyse est généré en sortie
- Optimiseur:
Dès que l’analyse est terminée, différents types de techniques d’optimisation sont
appliqués au bloc d’optimiseur. Ces techniques peuvent inclure la réécriture de la
requête, l’ordre de balayage des tables et le choix des bons index à utiliser, etc.
-Buffer et Cache :
Cache et stockage tampon de la requête précédente ou du problème demandé par
l’utilisateur. Lorsque l’utilisateur écrit une requête, elle va d’abord dans le cache de
requêtes, puis le cache de requête vérifiera que la même requête ou le même
problème est disponible dans le cache. Si la même requête est disponible, elle fournira
une sortie sans interférer avec l’analyseur, l’optimiseur.
-Table Metadata Cache
Le cache de métadonnées est une zone de mémoire réservée utilisée pour le suivi des
informations sur les bases de données, les index ou les objets. Plus le nombre de bases
de données, d’index ou d’objets ouverts est élevé, plus la taille du cache de
métadonnées n’est importante.
- Cache de clés : Un cache de clé est une entrée d’index qui identifie de manière
unique un objet dans un cache. Par défaut, les serveurs Edge mettent en cache le
contenu en fonction du chemin d’accès complet des ressources et d’une chaîne de
requête
Couche de stockage :
Cette couche de moteur de stockage de l’architecture MYSQL la rend unique et
préférable pour les développeurs. En raison de cette couche, MYSQL est compté
comme le SGBDR le plus utilisé. Dans le serveur MYSQL, pour différentes situations et
exigences, différents types de moteurs de stockage sont utilisés, à savoir InnoDB,
MYiSAM, NDB, mémoire, etc. Ces moteurs de stockage sont utilisés comme ingénierie de
stockage où les tables créées par l’utilisateur sont connectées entre elles.
4. Caractéristiques de MYSQL
Il n’est jamais bon d’avoir des logiciels obsolètes sur votre serveur. Même la plus
petite faille dans votre sécurité pourrait être un vecteur permettant aux attaquants de se
faufiler et de prendre le contrôle.
L’assistant de migration MySQL Workbench est conçu pour faire gagner du temps aux
administrateurs de bases de données et aux développeurs en offrant une facilité
d’utilisation visuelle et par pointer-cliquer à toutes les phases de configuration et de
gestion d’un processus de migration complexe :
• Migrations de bases de données : permet les migrations à partir de Microsoft SQL Server,
Microsoft Access, PostgreSQL, Sybase ASE, Sybase SQL Anywhere, SQLite, etc.
• Gérer les projets de migration - permet de configurer, copier, éditer, exécuter et
planifier les migrations.
• Sélection de la source et de la cible - permet aux utilisateurs de définir des sources de
données spécifiques et d’analyser les données sources avant la migration.
• Migration d’objets - permet aux utilisateurs de sélectionner les objets à migrer,
d’affecter la source aux mappages cibles si nécessaire, de modifier les scripts de
migration et de créer le schéma cible.
• Mises à niveau de version - à l’aide de la migration, les utilisateurs peuvent facilement
déplacer les bases de données des anciennes versions de MySQL vers la dernière.
Avec l’assistant de migration MySQL Workbench, les utilisateurs peuvent convertir une
base de données existante en MySQL en quelques minutes plutôt qu’en quelques heures
ou jours que la même migration nécessiterait à l’aide de méthodes manuelles
traditionnelles.
La migration de données est une opération de chargement en bloc qui déplace
des lignes de données de tables MySQL dans SQL Server ou SQL Azure tables dans les
transactions. Le nombre de lignes chargées dans SQL Server dans chaque transaction est
configuré dans les paramètres du projet. Concernant les migrations nous allons les faires
en interface graphique Utilisant MySQL WORKBENCH qui est un outil graphique intégré
dans MySQL dédié aux développeurs et aux administrateurs installés avec le package
MySQL.
Aller dans le homepage et cliquer sur l’onglet DATABASE --- assistant de migration. Ensuite
on commence la migration.
Très souvent les migrations de base de données se font d’un SGBD à un autre.
• Les tables
• Les verrous
• Les index
• Les vues
• les triggers
•
Dans plusieurs débats il a été reproché à MySql, de ne pas être un véritable serveur de
base de données. Par défaut MySql, il est vrai ne supporte ni les transactions ni les
contraintes sur les clés étrangères. Tout ce qui fait qu'un serveur puisse éviter la corruption
des données lors de sessions multiples simultanées.
C'est le format de table, Myisam, utilisé par défaut dans MySQL, qui est en cause. Ce type
de table, même s'il permet de très bonnes performances, ne supporte ni les transactions ni
les contraintes sur les clés étrangères ni les verrous au niveau utilisateur…
Cette limitation peut être facilement contournée dans certains cas. Mais des
environnements plus critiques demandent une exigence accrue de sécurité pour les
données.
Introduit avec la version 3.23.5 de MySQL, InnoDB répond à cette exigence en offrant le
support des transactions, des clés étrangères et les verrous dans les enregistrements. Les
versions futures annoncent le support des requêtes imbriquées et des procédures stockées.
MySQL enregistre par défaut les informations avec le moteur de stockage MyISAM, mais il
en existe d’autres incluant InnoDB (le plus connu), ISAM, Heap, NBD, Berkeley DB ou
encore Merge. Le choix d’un moteur de stockage est important et les différents parfois
méconnue. Les principales différences entre MyISAM et InnoDB pour comprendre
comment faire ce choix sont :
➢ MyISAM
Avan tages
Voici une liste non-exhaustive d’arguments en faveurs de MyISAM:
▪ Système de stockage par défaut de MySQL. Ce type de stockage est le plus ancien
disponible avec MySQL
▪ Très rapide pour effectuer des requêtes SELECT ou INSERT
▪ Supporte l’indexation plein texte (cf. index full text). Offre de bien meilleure
performance lors d’une recherche sur des champs de textes
▪ Administration plus simple
▪ Possibilité de verrouiller au niveau d’une table (cf. table lock)
▪ Plus souple au niveau de l’intégrité des données (mais ça peut avoir son revers de la
médaille …)
I nc onvénien ts
La souplesse de MyISAM entraîne quelques points négatifs lorsqu’il s’agit de garder une
bonne intégrité des données, comme le montre les points ci-dessous:
▪ Pas de transactions
▪ Pas de clés étrangères
▪ Plus difficile de récupérer après un crash. L’intégrité des données peut facilement
être compromise
Pas s er à M yI S A M
Si vous souhaitez passer une table à MyISAM il suffit simplement d’exécuter cette requête
SQL:
➢ InnoDB
Avan tages
Les principaux avantages d’utiliser InnoDB concernent la possibilité de bien gérer
l’intégrité des données, même lors d’un crash du serveur.
▪ Gère les transactions (ensemble de requêtes regroupées) tel que BEGIN ou START
TRANSACTION, COMMIT, ROLLBACK …
▪ Gère les clés étrangères et les contraintes d’intégrité
▪ Support d’ACID pour s’assurer que tous les enregistrements sont réussis ou échoué,
Risque d’erreur impossible, même lors d’une panne
▪ Système de récupération lors d’un crash grâce à un système de relecture des logs
I nc onvénien ts
Toutefois, l’intégrité des données complique l’administration d’une base de données.
▪ Plus strict concernant l’intégrité des données
▪ Ne supporte pas l’indexation plein texte (cf. index full text)
▪ Administration un peu plus complexe
▪ Moteur de stockage plus imposant. Il demande plus de ressources et est plus lent
▪ Possibilité de verrouiller au niveau d’une ligne (cf. row lock) pour insérer ou mettre à
jour un enregistrement
▪ Intéressant de noter que c’est plus récent, même si ce n’est pas forcément un
inconvénient
Pas s er à I nnoDB
Pour passer une table à InnoDB il suffit de lancer la requête suivante:
Il est important de savoir qu’il est possible dans une même base de données d’avoir des
tables en MyISAM et d’autres en InnoDB. Cela permet même d’améliorer les
performances dans certains cas.
Pour résumer sur le choix entre InnoDB et MyISAM :
▪ MyISAM : à privilégier lorsqu’il est surtout nécessaire d’effectuer des requêtes pour
lire ou insérer des données. Pour des sites web, c’est souvent la solution
recommandée.
▪ InnoDB : à privilégier pour les systèmes qui ne doivent pas comporter d’erreurs et qui
nécessite des clés étrangères. Pour une application gérant des données
importantes, tel une application bancaire, cela peut se révéler le moteur de
stockage recommandé.
9. Paramétrage d’Innodb
Les paramètres évoqués dans cette section ne sont pas nécessairement à modifier par
rapport à la configuration par défaut, mais il est important que vous ayez réfléchi à leur
bonne valeur pour votre application.
• Taille du cache mémoire (innodb_buffer_pool_size) : il s’agit du cache principal
d’InnoDB (buffer pool), où données et index fréquemment accédés sont stockés.
Pour un serveur dédié à MySQL, il est courant de lui allouer la majeure partie de la
mémoire du serveur (par exemple, environ 25 Go pour un serveur ayant 32 Go de
mémoire physique). L’idée principale est que ce cache permet d’éviter les accès
au disque : la taille du cache est d’autant plus importante que le disque est lent.
Si votre base de données est petite (quelques dizaines de Go, par exemple), il est
assez simple d’utiliser un serveur ayant suffisamment de mémoire pour que
l’ensemble des données et index InnoDB tiennent dans le cache. Sinon, il faut
essayer de faire tenir en cache la partie utile des données et index, c’est-à-dire la
partie des données et index qui est fréquemment utilisée par l’application. Il est
assez fréquent en effet d’avoir par exemple une base de 500 Go contenant
l’historique...
a. Réplication
En informatique, la réplication est un processus de partage d'informations pour assurer la
cohérence de données entre plusieurs sources de données redondantes, pour améliorer
la fiabilité, la tolérance aux pannes, ou la disponibilité. On parle de réplication de
données si les mêmes données sont dupliquées sur plusieurs périphériques.
La réplication n'est pas à confondre avec une sauvegarde : les données sauvegardées
ne changent pas dans le temps, reflétant un état fixe des données, tandis que les
données répliquées évoluent sans cesse à mesure que les données sources changent.
Dans une base de données, la réplication est fréquemment utilisée pour des systèmes qui
ont à soutenir une forte charge : le serveur maître journalise les opérations effectuées, et
les esclaves, à partir de ce journal, dupliquent les opérations effectuées. Ainsi, moyennant
un petit temps de retard (replication lag), les mêmes données sont disponibles sur
plusieurs serveurs en même temps, ce qui permet un processus de répartition de charge.
La plupart des systèmes de gestion de base de données modernes permettent un
schéma multi-maître : cependant, celui-ci introduit de nombreux coûts supplémentaires.
La résolution, ou la prévention de conflits entre plusieurs transactions simultanées est par
exemple très complexe.
Le terme de réplication SQL décrit un groupe de technologies permettant la distribution et
la mise en miroir d’informations entre différentes bases de données. La réplication SQL
permet non seulement de copier des données entre des bases de données, mais
également de copier des objets de base de données. Essentiellement, la réplication
effectue la synchronisation entre les bases de données.
La création d'un serveur de réplication s'effectue par la copie des tablespaces, des fichiers
de logs sur le serveur esclave, des fichiers.frm et l'édition de son fichier de configuration.
La réplication avec les tables InnoDB inclut la lecture des logs. Si une transaction a échoué,
celle-ci ne sera pas répliquée.
La gestion des tables n'est pas la même qu'avec MyIsam. Il n'est pas possible d'utiliser
« optmize table » pour vérifier et gérer les tables InnoDB. Il est préférable d'effectuer alors
un dump de la table et de supprimer celle-ci avant de la recréer et de réimporter les
données.
b. L'utilisation
L'utilisation d'InnoDB diffère aussi de l'utilisation classique de MySQL. Les tables et les index
de type InnoDB utilisent des méthodes différentes d'accès. Chaque table possède un
« clustered index ». Les données sont sur la même page que cet index.
Avec InnoDB, toute l'activité se produit dans un contexte transactionnel. À savoir que
même si par défaut MySQL valide automatiquement les transactions, celles-ci restent des
transactions et MySQL effectue en réalité un commit à chaque fin de requête.
Pour éviter que MySQL utilise ce comportement, on peut commencer le script par BEGIN(sur
sql server) ou START TRANSACTION(en invite de commande ou dans Workbench) et le finir
par COMMIT ou ROLLBACK. Une autre méthode consiste à fixer la variable autocommit à
0 à chaque début de session. Il est possible de fixer cette valeur dans le fichier de config
du client MySQL.
SET AUTOCOMMIT = 0;
Il est aussi possible de modifier une table existante d'un autre type vers InnoDB :
Si une erreur survient lors de la modification d'une table, vérifiez si celle-ci ne contient pas
d'index full text. Il convient aussi non pas d'utiliser ALTER TABLE, mais de supprimer la table
en prenant soin d'avoir effectué un DUMP de la table, puis d'importer les données dans la
table en utilisant set autocommit = 0 avant l'insertion et un commit à la fin.
Il est à noter que la compression de tables MYISAM n'est pas supportée sous InnoDB.
Le support InnoDB permet l'utilisation des transactions, des contraintes sur les clés
étrangères et de gérer des verrous au niveau des enregistrements et des tables.
Pour illustrer notre propos, nous allons créer deux tables que nous utiliserons en exemple.
Cet exemple est une gestion, simplifiée à l'extrême, de salles de classe. Les instituteurs
(table users) sont liés à une et une seule salle.
1.set auto_commit = 1;
2.Create database innodbtest;
3.CREATE TABLE users (
4. id int(11) NOT NULL auto_increment,
5. nom varchar(25) default NULL,
6. prenom varchar(25) default NULL,
7. age int(11) default NULL,
8. PRIMARY KEY (id)
9.) Engine=InnoDB;
10.
11.CREATE TABLE salles (
12.idsalle int(11) NOT NULL auto_increment,
13.num char(3) default NULL,
14.refuser int(11) default NULL,
15.PRIMARY KEY (idsalle),
16.index user_ref (refuser),
17.foreign key theuser (refuser) references users(id) on delete set null 18.)
Engine=InnoDB;
19.
20.grant select, insert, update, delete on innodbtest.* touser1@localhost;
21.grant select, insert, update, delete on innodbtest.* to user2@localhost;
22.flush privileges;
23.flush tables;
c. Les transactions
Ici, nous allons parler du langage de transaction de données. Ce sont des commandes
SQL utilisées pour gérer les modifications qui affectent les données de la base de données.
Fondamentalement, nous utilisons ces commandes dans la transaction ou pour créer un
point stable lors des changements de base de données auquel nous pouvons annuler l’état
de la base de données si nécessaire.
Commandes TCL :
START TRANSACTION – Pour commencer la transaction
COMMIT – Rend les changements de la base de donnée permanents
ROLLBACK – annule une transaction en cas d’erreur et repars au statut précédent de la
base de données. (Si vous avez déjà Commit vous ne pouvez plus Rollback)
SAVEPOINT – définit un point de sauvegarde dans une transaction.
SET TRANSACTION – spécifiez les caractéristiques de la transaction.
Une chose à savoir est que MySQL est auto-commit donc toutes les transactions ou
changements sont enregistrés de manière automatique.
Pour annuler le auto-commit on doit Utiliser la commande START TRANSACTION
Si on sort de MySQL, on se rend compte que les changements sur la table n’ont pas été
effectués ou enregistrés. Il faudra donc utiliser la commande commit pour sauvegarder
les changements. Tant que ce n’est pas fait, les changements dans le serveur sont
temporaires.
Il faut utiliser à nouveau la commande START TRANSACTION pour désactiver l’auto-
commit car les commandes rollback et commit sont à usage unique.
On peut aussi faire des sauvegardes à plusieurs niveaux avec savepoint et revenir à
chaque changement de la modification de la base de données.
L'un des buts d'InnoDB est de pouvoir, à tout moment, revenir à l'état antérieur d'une table
après une transaction. En d'autres termes, seules les transactions validées sont considérées
comme durables et leurs données enregistrées dans les tables.
Par défaut et jusqu'à la version 4.0.4 le niveau d'isolation des transactions et REPEATABLE
READ. Les versions supérieures permettent de changer ce niveau d'isolation vers READ
UNCOMMITED, READ COMMITED, SERIALISABLE.
d. Niveau d'isolation
REPEATABLE READ lit et bloque les index en laissant la possibilité d'effectuer des inserts.
READ UNCOMMITED lit les enregistrements sans possibilité de regarder à la dernière version.
READ COMMITED : une instruction peut seulement voir les lignes validées avant qu'elle ne
débute.
SERIALISABLE : la transaction en cours peut seulement voir les lignes validées avant qu'une
première requête ou une instruction de modification de données soit exécutée dans la
transaction.
• Un index ordonné contient une liste de valeurs extraites d'une table et triés.
• Dans un index haché les valeurs sont transformées par une fonction de hachage.
• Dans un index dense, la totalité des enregistrements d'une table est référencée.
• Dans un index épars seule une partie des enregistrements est référencée.
L'index primaire d'une table est le premier qui est utilisé pour localiser les enregistrements.
Une table peut également contenir des index secondaires en complément de l'index
primaire2. Chaque table peut comporter un ou plusieurs index. Un index peut être issu
d'un seul champ ou peut combiner plusieurs champs
Les index sont utilisés par les SGBD pour de nombreuses opérations. Les index facilitent les
opérations de tri, de recherche, de regroupement et de jointure1. La structure la plus
courante des index est l'arbre B3. D'autres structures existent mais sont rarement utilisées
- ISAM, les tables de hachage ou les bitmaps.
• structure en arbre: un tronc auquel sont attachées des branches avec des
ramifications et des feuilles au bout. Toutes les recherches sont effectuées en partant
du tronc. En recherchant parmi les branches celle qui contient la valeur à trouver,
jusqu'à avoir atteint une feuille.
Pour accélérer les opérations, les arbres d'index sont enregistrés en un bloc comportant
un très grand nombre de ramifications: Les disques durs, sur lesquels sont enregistrés les
index, lisent les données par bloc de plusieurs kilooctets et le temps nécessaire pour lire un
bloc est généralement très inférieur au temps nécessaire pour le localiser. Avec cette
construction, la recherche d'un enregistrement dans un lot de plusieurs millions nécessite
alors seulement 2 ou 3 opérations.
Les index peuvent être ajoutés par une commande SQL. L'existence d'index est cruciale
pour accélérer les opérations de manipulation de données. L'utilisation inadéquate des
index est la principale cause de déception. Le système de gestion de base de données
(abr. SGBD) ne trouvera pas les index qui sont nécessaires pour effectuer efficacement les
opérations qui lui sont demandées. Les raisons de l'utilisation inadéquate sont que la
documentation des SGBD concernant l'utilisation des index est souvent vague et
succincte, et met en avant leurs inconvénients plus que leurs avantages.
Les index sont en particulier exploités par l´optimiseur de requêtes:
• L'optimiseur est le composant des SGBD qui recherche la manière la plus économique
d'exécuter une requête. L'optimiseur examine les différents scénarios possibles et
estime le nombre d'opérations nécessaires pour chaque scénario, puis opte pour le
scénario qui en demande le moins. Le nombre d'opérations nécessaires dépend de la
présence d'index, ainsi que du nombre de lignes de la table et de la répartition des
valeurs5.
Types d'index
• La structure la plus courante pour les index est l'arbre B (B-tree). En stockant les
différentes valeurs du champ dans un arbre équilibré, le SGBD pourra hiérarchiser les
enregistrements d'après un champ dont la plage de valeurs est infinie (ou presque).
• Un autre type d'index est l'index bitmap. Il consiste en une simple table indiquant, pour
chaque valeur possible du champ, la liste des enregistrements ayant cette valeur pour
ce champ.
Cependant, pour être efficace, il nécessite que le SGBD puisse accéder
directement à une valeur donnée. Il n'est donc applicable que sur les colonnes
pour lesquelles le nombre de valeurs est limité et ordonné.
• On trouve également des index par table de hachage. L'inconvénient majeur d'un
tel index est de ne permettre que les sélections par égalité, puisqu'il ne conserve
pas la notion d'ordre. Si n est le nombre d'enregistrements d'une table, l'utilisation
d'une table de hachage équilibrée peut permettre de réduire le nombre
d'enregistrements à parcourir à la racine carrée de n (la table étant alors
composée de valeurs de hachage accédant chacune à N enregistrements). La
même remarque sur l'efficacité existe pour l'index bitmap : le SGBD doit pouvoir
accéder directement à une valeur de hachage donnée, sans avoir à parcourir la
liste des valeurs de hachage possibles.
Les vues sont des tables virtuelles issues de l'assemblage d'autres tables en fonction de
critères. Techniquement les vues sont créées à l'aide d'une requête SELECT. Elles ne
stockent pas les données qu'elles contiennent mais conservent juste la requête
permettant de les créer.
La requête SELECT qui génère la vue référence une ou plusieurs tables. La vue peut donc
être, par exemple, une jointure entre différentes tables, l'aggrégation ou l'extraction de
certaines colonnes d'une table. Elle peut également être créée à partir d'une autre vue.
Les vues sont souvent en lecture seule et ne permettent donc que de lire des données.
Cependant MySQL permet la création de vues modifiables sous certaines conditions :
• La requête qui génère la vue doit permettre à MySQL de retrouver la trace de
l'enregistrement à modifier dans la ou les tables sous-jacentes ainsi que celle de
toutes les valeurs de chaque colonne. La requête SELECT créant la vue ne doit
donc pas contenir de clause DISTINCT, GROUP BY, HAVING... et autres fonctions
d'aggrégation. La liste complète est disponible dans la documentation de MySQL.
Les vues peuvent être utilisées pour différentes raisons. Elles permettent de :
• Contrôler l'intégrité en restreignant l'accès aux données pour améliorer la
confidentialité.
o Partitionnement vertical et/ou horizontal pour cacher des champs aux
utilisateurs, ce qui permet de personnaliser l'affichage des informations suivant
le type d'utilisateur.
• Masquer la complexité du schéma.
o Indépendance logique des données, utile pour donner aux utilisateurs l’accès
à un ensemble de relations représentées sous la forme d'une table. Les
données de la vue sont alors des champs de différentes tables regroupées, ou
des résultats d’opérations sur ces champs.
• Modifier automatiquement des données sélectionnées (sum(), avg(), max(),...).
o Manipuler des valeurs calculées à partir d'autres valeurs du schéma.
• Conserver la structure d'une table si elle doit être modifiée.
o Le schéma peut ainsi être modifié sans qu'il ne soit nécessaire de changer les
requêtes du côté applicatif.
Pour créer une vue l'utilisateur doit avoir le droit CREATE VIEW. Il faut également avoir la
permission de sélectionner toutes les colonnes qui apparaissent dans la commande
SELECT spécifiant ce qu'est la vue.
De plus si la clause REPLACE est utilisée, le droit DROP est également nécessaire.
Le droit SHOW VIEW donne la possibilité d'exécuter la commande SHOW CREATE VIEW.
Cette commande permet d'obtenir les informations de création d'une vue. Une autre
façon d'obtenir ces informations est d'interroger la table view du
schéma information_schema. Cette information sera exhaustive seulement pour les vues
que vous avez créé.
CREATE VIEW
La commande MySQL pour créer une vue est assez proche de la syntaxe du standard
SQL.
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW nom_de_la_vue [(colonne(s))]
AS requête_select
[WITH [CASCADED | LOCAL] CHECK OPTION]
Voici dans le détail les différentes clauses.
OR REPLACE : si une vue du même nom existe, elle est alors supprimée et remplacée par
la nouvelle.
ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE} : clause non standard, qui prend les
valeurs suivantes :
• UNDEFINED : C'est la valeur par défaut. MySQL décide lui-même quel algorithme
choisir entre MERGE et TEMPTABLE.
• MERGE utilise la requête SQL ayant servi à la création de la vue comme base
d'opération. En d'autres termes, faire une requête sur la vue revient à faire la même
requête sur la ou les tables sous-jacentes.
• TEMPTABLE utilise une table temporaire créée pour stocker (temporairement) les
résultats. Un intérêt de cet algorithme est de libérer plus rapidement les verrous sur
les tables sous-jacentes. Les autres requêtes sont alors moins pénalisées.
Il faut noter également qu'une vue avec pour valeur MERGE sera modifiable alors
qu'avec la valeur TEMPTABLE elle ne le sera pas.
DEFINER = { user | CURRENT_USER } : clause non standard qui permet d'assigner un
créateur à la vue. Par défaut, le créateur de la vue est DEFINER = current_user, c'est-à-
dire, l'utilisateur qui exécute la commande CREATE VIEW. Il est cependant possible
d'assigner la vue à un autre compte utilisateur, à condition d'avoir le droit SUPER.
SQL SECURITY { DEFINER | INVOKER } : clause non standard encore qui permet de définir
quels seront les droits de l'utilisateur lors de l'exécution de la vue. Deux valeurs sont
possibles :
• DEFINER qui permet d'exécuter la vue avec les droits du créateur. C'est la valeur par
défaut.
• INVOKER qui permet d'exécuter la vue avec ses propres droits.
WITH [CASCADED | LOCAL] CHECK OPTION : permet de vérifier les contraintes spécifiées
dans la clause WHERE d'une vue modifiable lorsque l'on y modifie ses données. Deux
valeurs sont possibles :
• CASCADED, la valeur par défaut. Elle permet de vérifier la contrainte pour la vue
ainsi que pour les vues sous-jacentes dont elle dérive.
• LOCAL qui permet de vérifier seulement la contrainte de la vue.
ALTER VIEW
Une fois la vue créée, il est bien évidement possible de la modifier avec la
commande ALTER VIEW.
ALTER definer='secretaire'@'localhost'
VIEW v_etudiant_liste AS SELECT nom, prenom, cursus FROM etudiant;
Cette commande modifie la clause DEFINER en lui assignant le
compte secretaire@localhost et modifie la définition de la vue en rajoutant le champ
cursus.
DROP VIEW
Lors de la création d'une vue, certaines contraintes doivent être prises en compte :
• Il n'est pas possible de créer un index sur une vue.
• La vue ne peut pas contenir de sous-requêtes dans la clause FROM du SELECT.
• Il n'est pas possible d'utiliser de variables dans une vue.
• Les objets (tables et vues) nécessaires à la création de la vue doivent exister avant
de la créer.
• Si un objet référencé par la vue est effacé, la vue n'est alors plus accessible.
• Une vue ne peut référencer une table temporaire (TEMPORARY TABLE).
• Il n'est pas possible de créer des vues temporaires.
• Il n'est pas possible d'associer un trigger à une vue.
• La définition d'une vue est "gelée" dans une requête préparée.
Par exemple :
Voici quelques exemples pratiques très simples pour illustrer les différents besoins que
peuvent combler les vues. On aura ici, une vue administrateur de base de données. Les
objets créés ne seront pas utilisés directement par les utilisateurs mais aux travers d'une
application.
La table employe de mon application, contient toutes les informations sur les employées.
Pour le comptable, il faut avoir accès aux champs nom, prénom, téléphone du bureau,
statut et salaire de chaque employé. On fait donc un partitionnement vertical de la
table employe. La vue correspondante est la suivante :
• Principe
• Syntaxe et utilisation : verrous de table
• Syntaxe et utilisation : verrous de ligne
• Niveaux d'isolation
Principe
Lorsqu'une session MySQL pose un verrou sur un élément de la base de données, cela
veut dire qu'il restreint, voire interdit, l'accès à cet élément aux autres sessions MySQL qui
voudraient y accéder.
Il est possible de poser un verrou sur une table entière, ou seulement sur une ou plusieurs
0lignes d'une table. Étant donné qu'un verrou empêche l'accès d'autres sessions, il est en
général plus intéressant de poser un verrou sur la plus petite partie de la base possible.
• On peut poser un verrou sur toute la table Animal. Dans ce cas, les autres sessions
n'auront pas accès à cette table, tant que le verrou sera posé. Qu'elles veuillent en
utiliser les chiens, les chats, ou autre, tout leur sera refusé.
• On peut aussi poser un verrou uniquement sur les lignes de la table qui contiennent
des chiens. De cette manière, les autres sessions pourront accéder aux chats, aux
perroquets, etc. Elles pourront toujours travailler, tant qu'elles n'utilisent pas les
chiens.
Cette notion d'accès simultané aux données par plusieurs sessions différentes s'appelle
la concurrence. Plus la concurrence est possible, donc plus le nombre de sessions
pouvant accéder aux données simultanément est grand, mieux c'est. En effet, prenons
l'exemple d'un site web. En général, on préfère permettre à plusieurs utilisateurs de surfer
en même temps, sans devoir attendre entre chaque action de pouvoir accéder aux
informations chacun à son tour. Or, chaque utilisateur crée une session chaque fois qu'il
se connecte à la base de données (pour lire les informations ou les modifier). Préférez
donc (autant que possible) les verrous de ligne aux verrous de table !
Avertissements
Par ailleurs, je vous présente ici les principes généraux et les principales options, mais il
faut savoir qu'il y a énormément à dire sur les verrous, et que j'ai donc dû faire un sérieux
tri des informations avant de rédiger ce chapitre. À nouveau, en cas de doute, ou si vous
avez besoin d'informations précises, je vous conseille vraiment de consulter la
documentation officielle (si possible en anglais, car elle est infiniment plus complète qu'en
français).
Nous allons ajouter deux tables à notre base de données, afin d'illustrer au mieux l'intérêt
et l'utilisation des verrous : une table Client, qui contiendra les coordonnées des clients de
notre élevage, et une table Adoption, qui contiendra les renseignements concernant les
adoptions faites par nos clients. Dorénavant, certains animaux présents dans notre
table Animal ne seront plus disponibles, car ils auront été adoptés. Nous les garderons
cependant dans notre base de données. Avant toute adoption, il nous faudra donc
vérifier la disponibilité de l'animal.
Les verrous de table sont les seuls supportés par MyISAM. Ils sont d'ailleurs principalement
utilisés pour pallier en partie l'absence de transactions dans MyISAM. Les tables InnoDB
peuvent également utiliser ce type de verrou.
• En utilisant READ, un verrou de lecture sera posé ; c'est-à-dire que les autres sessions
pourront toujours lire les données des tables verrouillées, mais ne pourront plus les
modifier.
• En utilisant WRITE, un verrou d'écriture sera posé. Les autres sessions ne pourront plus
ni lire ni modifier les données des tables verrouillées.
Pour déverrouiller les tables, on utilise UNLOCK TABLES. Cela déverrouille toutes les tables
verrouillées. Il n'est pas possible de préciser les tables à déverrouiller. Tous les verrous de
table d'une session sont relâchés en même temps.
• Elle ne peut plus accéder qu'aux tables sur lesquelles elle a posé un verrou ;
• Elle ne peut accéder à ces tables qu'en utilisant les noms qu'elle a donnés lors du
verrouillage (soit le nom de la table, soit le/les alias donné(s)) ;
• S’il s'agit d'un verrou de lecture (READ), elle peut uniquement lire les données, pas
les modifier.
Exemples : on pose deux verrous, l'un READ, l'autre WRITE, l'un en donnant un alias au nom
de la table, l'autre sans.
id nom_courant
1 Chien
2 Chat
3 Tortue d'Hermann
4 Perroquet amazone
5 Rat brun
1ERROR 1100 (HY000): Table 'table_espece' was not locked with LOCK TABLES
Par contre, si l'on essaye d'utiliser un alias, cela ne fonctionne pas. Le verrou est posé
sur Espece, pas sur Espece AS table_espece.
1ERROR 1099 (HY000): Table 'Espece' was locked with a READ lock and can't be updated
Avec ou sans alias, impossible de modifier la table Espece, puisque le verrou que l'on
possède dessus est un verrou de lecture.
1ERROR 1100 (HY000): Table 'Adoption' was not locked with LOCK TABLES
client_id animal_id
4 26
4 41
1UPDATE Adoption
2SET paye = 0
3WHERE client_id = 10 AND animal_id = 49;
1ERROR 1100 (HY000): Table 'Adoption' was not locked with LOCK TABLES
Il faut donc penser à acquérir tous les verrous nécessaires aux requêtes à exécuter. De
plus, il faut les obtenir en une seule requête LOCK TABLES. En effet, LOCK
TABLES commence par enlever tous les verrous de table de la session avant d'en acquérir
de nouveaux. Il est bien entendu possible de poser plusieurs verrous sur la même table en
une seule requête afin de verrouiller son nom ainsi qu'un ou plusieurs alias.
Exemples : on pose un verrou de lecture sur Adoption, puis avec une seconde requête,
on pose deux verrous de lecture sur la table Espece, l'un avec alias, l'autre sans.
Une fois ces deux requêtes effectuées, nous aurons donc bien deux verrous de lecture sur
la table Espece : un avec son nom, l'autre avec un alias. Par contre, le verrou
sur Adoption n'existera plus puisqu'il aura été relâché par l'exécution de la seconde
requête LOCK TABLES.
id nom_courant
1 Chien
2 Chat
3 Tortue d'Hermann
4 Perroquet amazone
5 Rat brun
id nom_courant
1 Chien
2 Chat
3 Tortue d'Hermann
4 Perroquet amazone
5 Rat brun
Avec ou sans alias, on peut sélectionner les données de la table Espece, puisque l'on a
un verrou sur Espece et sur Espece AS table_espece.
3. Sélection dans Espece, avec mauvais alias.
1ERROR 1100 (HY000): Table 'table_esp' was not locked with LOCK TABLES
Bien entendu, cela ne fonctionne que pour l'alias que l'on a donné lors du verrouillage.
1ERROR 1100 (HY000): Table 'Adoption' was not locked with LOCK TABLES
Le verrou sur Adoption a été relâché lorsque l'on a posé les verrous sur Espece. On ne
peut donc pas lire les données d'Adoption (avec ou sans alias).
Si une session a obtenu un verrou de lecture sur une table, les autres sessions :
Si par contre une session a obtenu un verrou d'écriture, les autres sessions ne peuvent
absolument pas accéder à cette table tant que ce verrou existe.
Session 1 :
Session 2 :
Session 2 :
1SELECT *
2FROM Adoption
3WHERE client_id = 4;
Par contre, la sélection sur Adoption ne passe pas. La session se bloque, jusqu'à ce que la
session 1 déverrouille les tables avec UNLOCK TABLES.
Session 2 :
1UPDATE Client
2SET pays = 'Suisse'
3WHERE id = 5;
Session 2:
1UPDATE Adoption
2SET paye = 1
3WHERE client_id = 3;
Bien entendu, la modification sur la table Adoption attend également que les verrous
soient relâchés par la session 1.
En ce qui concerne la pose de verrous de table par les autres sessions, faites vos propres
tests, mais simplement : si une session peut lire les données d'une table, elle peut
également poser un verrou de lecture. Si une session peut modifier les données d'une
table, elle peut également poser un verrou d'écriture.
Interaction avec les transactions
Si l'on utilise des tables MyISAM, il n'y a évidemment aucune précaution particulière à
prendre par rapport aux transactions lorsqu'on utilise des verrous de table (les tables
MyISAM étant non-transactionnelles). Par contre, si on utilise des tables InnoDB, il convient
d'être prudent. En effet :
Pour utiliser à la fois les transactions et les verrous de table, il faut renoncer à démarrer
explicitement les transactions, et donc utiliser le mode non-autocommit. Lorsque l'on est
dans ce mode, il est facile de contourner la validation implicite provoquée par LOCK
TABLES et UNLOCK TABLES : il suffit d'appeler LOCK TABLES avant toute modification de
données, et de commiter/annuler les modifications avant d'exécuter UNLOCK TABLES.
Exemple :
1SET autocommit = 0;
2LOCK TABLES Adoption WRITE; -- La validation implicite ne commite rien puisque aucun cha
3
4UPDATE Adoption SET date_adoption = NOW() WHERE client_id = 9 AND animal_id = 54;
5SELECT client_id, animal_id, date_adoption FROM Adoption WHERE client_id = 9;
6
7ROLLBACK;
8UNLOCK TABLES; -- On a annulé les changements juste avant donc la validation implicite n
9SELECT client_id, animal_id, date_adoption FROM Adoption WHERE client_id = 9;
10 SET autocommit = 1;
Ces verrous ne peuvent pas être posés sur une table utilisant le moteur MyISAM ! Tout ce
qui est dit ici concerne les tables InnoDB uniquement.
Comme les verrous de table, les verrous de ligne peuvent être de deux types :
• Les verrous partagés : permettent aux autres sessions de lire les données, mais pas
de les modifier (équivalents aux verrous de table de lecture) ;
• Les verrous exclusifs : ne permettent ni la lecture ni la modification des données
(équivalents aux verrous d'écriture).
Requêtes de sélection
Les requêtes de sélection, par défaut, ne posent pas de verrous. Il faut donc en poser
explicitement au besoin.
Verrou partagé
Cette requête pose donc un verrou partagé sur les lignes de la table Animal pour
lesquelles espece_id vaut 5.
Ce verrou signifie en fait, pour les autres sessions : "Je suis en train de lire ces données.
Vous pouvez venir les lire aussi, mais pas les modifier tant que je n'ai pas terminé.".
Verrou exclusif
Pour poser un verrou exclusif, on utilise FOR UPDATE à la fin de la requête SELECT.
Ce verrou signifie aux autres sessions : "Je suis en train de lire ces données dans le but
probable de faire une modification. Ne les lisez pas avant que j'aie fini (et bien sûr, ne les
modifiez pas).".
Les verrous de ligne ne sont donc pas posés par des commandes spécifiques, mais par
des requêtes de sélection, insertion ou modification. Ces verrous existent donc
uniquement tant que la requête qui les a posés interagit avec les données.
Par conséquent, ce type de verrou s'utilise en conjonction avec les transactions. En effet,
hors transaction, dès qu'une requête est lancée, elle est effectuée et les éventuelles
modifications des données sont immédiatement validées. Par contre, dans le cas d'une
requête faite dans une transaction, les changements ne sont pas validés tant que la
transaction n'a pas été commitée. Donc, à partir du moment où une requête a été
exécutée dans une transaction, et jusqu'à la fin de la transaction
(COMMIT ou ROLLBACK), la requête a potentiellement un effet sur les données. C'est à ce
moment-là (quand une requête a été exécutée mais pas validée ou annulée) qu'il est
intéressant de verrouiller les données qui vont potentiellement être modifiées (ou
supprimées) par la transaction.
Un verrou de ligne est donc lié à la transaction dans laquelle il est posé. Dès que l'on fait
un COMMIT ou un ROLLBACK de la transaction, le verrou est levé.
Exemples
Verrou posé par une requête de modification
Session 1 :
1START TRANSACTION;
2
3UPDATE Client SET pays = 'Suisse'
4WHERE id = 8; -- un verrou exclusif sera posé sur la ligne avec id = 8
Session 2:
1START TRANSACTION;
2
3SELECT * FROM Client
4WHERE id = 8; -- pas de verrou
5
6SELECT * FROM Client
7WHERE id = 8
8LOCK IN SHARE MODE; -- on essaye de poser un verrou partagé
La seconde session fait d'abord une simple sélection, sans poser de verrou. Pas de
problème, la requête passe.
On lui demande de poser un verrou ! Lorsqu'une session pose un verrou sur une table, elle
est obligée de travailler vraiment avec la table, et pas sur sa photo. Elle va donc aller
chercher les dernières infos disponibles, et actualiser sa photo par la même occasion. On
le voit bien avec la seconde requête, qui tente de poser un verrou partagé (qui vise
donc uniquement la lecture). Elle va d'abord chercher les lignes les plus à jour et tombe
sur le verrou posé par la première session ; elle se retrouve alors bloquée jusqu'à ce que la
première session ôte le verrou exclusif.
Session 1 :
1COMMIT;
On peut également essayer la même manœuvre, avec cette fois-ci un UPDATE plutôt
qu'un SELECT ... LOCK IN SHARE MODE (donc une requête qui va tenter de poser un
verrou exclusif plutôt qu'un verrou partagé).
Session 1 :
1START TRANSACTION;
2
3UPDATE Adoption SET paye = 0
4WHERE client_id = 11;
Session 2 :
1START TRANSACTION;
2
3UPDATE Adoption SET paye = 1
4WHERE animal_id = 32; -- l'animal 32 a été adopté par le client 11
Comme prévu, la seconde session est bloquée, jusqu'à ce que la première session
termine sa transaction. Validez la transaction de la première session, puis de la seconde.
Le comportement sera le même si la deuxième session fait un DELETE sur les lignes
verrouillées, ou un SELECT ... FOR UPDATE.
1START TRANSACTION;
2
3INSERT INTO Adoption (client_id, animal_id, date_reservation, prix)
4VALUES (12, 75, NOW(), 10.00);
Session 2 :
La première session insère une adoption pour le client 12 et pose un verrou exclusif sur
cette ligne. La seconde session fait deux requêtes SELECT en posant un verrou partagé :
l'une qui sélectionne les adoptions des clients avec un id supérieur à 13 ; l'autre qui
sélectionne les adoptions des clients avec un id inférieur à 13. Seule la seconde
requête SELECT se heurte au verrou posé par la première session, puisqu'elle tente de
récupérer notamment les adoptions du client 12, dont une est verrouillée.
Session 1 :
1COMMIT;
Voyons d'abord le comportement d'un verrou partagé, posé par SELECT ... LOCK IN
SHARE MODE.
Session 1 :
1START TRANSACTION;
2
3SELECT * FROM Client
4WHERE id < 5
5LOCK IN SHARE MODE;
Session 2 :
1START TRANSACTION;
2
3SELECT * FROM Client
4WHERE id BETWEEN 3 AND 8;
5
6SELECT * FROM Client
7WHERE id BETWEEN 3 AND 8
8LOCK IN SHARE MODE;
9
10 SELECT * FROM Client
11 WHERE id BETWEEN 3 AND 8
12 FOR UPDATE;
La première session pose un verrou partagé sur les clients 1, 2, 3 et 4. La seconde session
fait trois requêtes de sélection. Toutes les trois concernent les clients 3 à 8 (dont les deux
premiers sont verrouillés).
• Requête 1 : ne pose aucun verrou (travaille sur une "photo" de la table et pas sur les
vraies données) donc s'effectue sans souci.
• Requête 2 : pose un verrou partagé, ce qui est faisable sur une ligne verrouillée par
un verrou partagé. Elle s'effectue également.
• Requête 3 : tente de poser un verrou exclusif, ce qui lui est refusé.
Bien entendu, des requêtes UPDATE ou DELETE (posant des verrous exclusifs) faites par la
deuxième session se verraient, elles aussi, bloquées.
Quant aux requêtes SELECT ... FOR UPDATE posant un verrou exclusif, elles provoqueront
exactement les mêmes effets qu'une requête UPDATE ou DELETE (après tout, un verrou
exclusif, c'est un verrou exclusif).
Session 1 :
1START TRANSACTION;
2
3SELECT * FROM Client
4WHERE id < 5
5FOR UPDATE;
Session 2 :
1START TRANSACTION;
2
3SELECT * FROM Client
4WHERE id BETWEEN 3 AND 8;
5
6SELECT * FROM Client
7WHERE id BETWEEN 3 AND 8
8LOCK IN SHARE MODE;
Cette fois-ci, même la requête SELECT ... LOCK IN SHARE MODE de la seconde session est
bloquée (comme le serait une requête SELECT ... FOR UPDATE, ou une requête UPDATE,
ou une requête DELETE).
En résumé
• On pose un verrou partagé lorsqu'on fait une requête dans le but de lire des
données.
• On pose un verrou exclusif lorsqu'on fait une requête dans le but (immédiat ou non)
de modifier des données.
• Un verrou partagé sur les lignes x va permettre aux autres sessions d'obtenir
également un verrou partagé sur les lignes x, mais pas d'obtenir un verrou exclusif.
• Un verrou exclusif sur les lignes x va empêcher les autres sessions d'obtenir un verrou
sur les lignes x, qu'il soit partagé ou exclusif.
Session 1 :
1START TRANSACTION;
2UPDATE Animal
3SET commentaires = CONCAT_WS(' ', 'Animal fondateur.', commentaires) -On
4ajoute une phrase de commentaire
WHERE date_naissance < '2007-01-01'; -- à tous les animaux nés
avant 2007
Session 2 :
1START TRANSACTION;
2UPDATE Animal
3SET commentaires = 'Aveugle' -- On modifie les commentaires
4WHERE date_naissance = '2008-03-10 13:40:00'; -- De l'animal né le 10 mars 2008 à 13h40
Dans la session 1, on fait un UPDATE sur les animaux nés avant 2007. On s'attend donc à
pouvoir utiliser les animaux nés après dans une autre session, puisque InnoDB pose des
verrous sur les lignes et pas sur toute la table. Pourtant, la session 2 semble bloquée
lorsque l'on fait un UPDATE sur un animal né en 2008. Faites un rollback sur la session 1 ;
ceci débloque la session 2. Annulez également la requête de cette session.
Une partie des colonnes du résultat montré ici a été retirée pour des raisons de clarté.
Il semblerait donc que lorsque l'on pose un verrou, avec dans la clause WHERE de la
requête une colonne indexée (espece_id), le verrou est bien posé uniquement sur les
lignes pour lesquelles espece_id vaut la valeur recherchée. Par contre, si dans la
clause WHERE on utilise une colonne non-indexée (date_naissance), MySQL n'est pas
capable de déterminer quelles lignes doivent être bloquées, donc on se retrouve avec
toutes les lignes bloquées.
C'est très simple ! Vous savez que lorsqu'une colonne est indexée (que ce soit un index
simple, unique, ou une clé primaire ou étrangère), MySQL stocke les valeurs de cette
colonne en les triant. Du coup, lors d'une recherche sur l'index, pas besoin de parcourir
toutes les lignes, il peut utiliser des algorithmes de recherche performants et trouver
facilement les lignes concernées. S'il n'y a pas d'index par contre, toutes les lignes doivent
être parcourues chaque fois que la recherche est faite, et il n'y a donc pas moyen de
verrouiller simplement une partie de l'index (donc une partie des lignes). Dans ce cas,
MySQL verrouille toutes les lignes.
Cela fait une bonne raison de plus de mettre des index sur les colonnes qui servent
fréquemment dans vos clauses WHERE !
Encore une petite expérience pour illustrer le rôle des index dans le verrouillage de lignes :
Session 1 :
1START TRANSACTION;
2UPDATE Animal -- Modification de tous les rats
3SET commentaires = CONCAT_WS(' ', 'Très intelligent.', commentaires)
4WHERE espece_id = 5;
Session 2 :
1START TRANSACTION;
2UPDATE Animal
3SET commentaires = 'Aveugle'
4WHERE id = 34; -- Modification de l'animal 34 (un chat)
5UPDATE Animal
6SET commentaires = 'Aveugle'
7WHERE id = 72; -- Modification de l'animal 72 (un rat)
La session 1 se sert de l'index sur espece_id pour verrouiller les lignes contenant des rats
bruns. Pendant ce temps, la session 2 veut modifier deux animaux : un chat et un rat, en
se basant sur leur id. La modification du chat se fait sans problème, par contre, la
modification du rat est bloquée, tant que la transaction de la session 1 est ouverte. Faites
un rollback des deux transactions.
On peut conclure de cette expérience que, bien que MySQL utilise les index pour
verrouiller les lignes, il n'est pas nécessaire d'utiliser le même index pour avoir des accès
concurrents.
Dans une session, démarrons une transaction et sélectionnons toutes les adoptions faites
par les clients dont l'id dépasse 13, avec un verrou exclusif.
Session 1 :
1START TRANSACTION;
2
3SELECT * FROM Adoption WHERE client_id > 13 FOR UPDATE; -- ne pas oublier le FOR UPDATE
La requête va poser un verrou exclusif sur toutes les lignes dont client_id vaut 14 ou plus.
Cette ligne nouvellement apparue malgré les verrous est une "ligne fantôme".
Pour pallier ce problème, qui est contraire au principe d'isolation, les verrous posés par
des requêtes de lecture, de modification et de suppression sont des verrous dits "de clé
suivante" ; ils empêchent l'insertion d'une ligne dans les espaces entre les lignes
verrouillées, ainsi que dans l'espace juste après les lignes verrouillées.
Nous avons vu que les verrous se basent sur les index pour verrouiller uniquement les lignes
nécessaires. Voici un petit schéma qui vous expliquera ce qu'est cet "index de clé
suivante".
On peut représenter l'index sur client_id de la table Adoption de la manière suivante (je
ne mets que les client_id < 10)
Si l'on insère une adoption avec 4 pour client_id, l'index va être réorganisé de la manière
suivante :
Mais, si l'on pose un verrou de clé suivante sur l'index, sur les lignes dont client_id vaut 4,
on va alors verrouiller les lignes, les espaces entre les lignes et les espaces juste après.
Ceci va bloquer l'insertion de la nouvelle ligne
Démonstration
On a toujours un verrou exclusif (grâce à notre SELECT ... FOR UPDATE) sur
les client_id supérieurs à 14 dans la session 1 (sinon, reposez-le).
Session 2 :
1START TRANSACTION;
2
3INSERT INTO Adoption (client_id, animal_id, date_reservation, prix)
4VALUES (15, 61, NOW(), 735.00);
L'insertion est bloquée ! Pas de risque de voir apparaître une ligne fantôme. Annulez les
deux transactions.
Exception
Si la clause WHERE concerne un index UNIQUE (cela inclut bien sûr les clés primaires) et
recherche une seule valeur (exemple : WHERE id = 4), alors seule la ligne concernée (si
elle existe) est verrouillée, et pas l'espace juste après dans l'index. Forcément, s'il s'agit
d'un index UNIQUE, l'insertion d'une nouvelle valeur ne changera rien : WHERE id = 4 ne
renverra jamais qu'une seule ligne.
Après tout, une requête SELECT ne fait jamais que lire des données. Que personne ne
puisse les modifier pendant qu'on est en train de les lire, c'est tout à fait compréhensible.
Mais pourquoi carrément interdire aux autres de les lire aussi ?
Tout simplement parce que certaines données sont lues dans le but prévisible et avoué
de les modifier immédiatement après.
L'exemple typique est la vérification de stock dans un magasin (ou dans un élevage
d'animaux). Un client arrive et veut adopter un chat, on vérifie donc les chats disponibles
pour l'adoption, en posant un verrou partagé :
Session 1 :
1START TRANSACTION;
2
3SELECT Animal.id, Animal.nom, Animal.date_naissance, Race.nom as race, COALESCE(Rac
4FROM Animal
5INNER JOIN Espece ON Animal.espece_id = Espece.id
6LEFT JOIN Race ON Animal.race_id = Race.id -- Jointure externe, on ne veut pas que
7WHERE Espece.nom_courant = 'Chat' -- Uniquement les chats...
8AND Animal.id NOT IN (SELECT animal_id FROM Adoption) -- ... qui n'ont pas encore été ad
9LOCK IN SHARE MODE;
Si, pendant que le premier client fait son choix, un second client arrive, qui veut adopter
un chat Maine Coon, il va également chercher la liste des chats disponibles. Et vu qu'on
travaille pour l'instant en verrous partagés, il va pouvoir l'obtenir.
Session 2 :
1START TRANSACTION;
2
3SELECT Animal.id, Animal.nom, Animal.date_naissance, Race.nom as race, COALESCE(Rac
4FROM Animal
5INNER JOIN Espece ON Animal.espece_id = Espece.id
6INNER JOIN Race ON Animal.race_id = Race.id -- Jointure interne cette fois
7WHERE Race.nom = 'Maine Coon' -- Uniquement les Maine Coon...
8AND Animal.id NOT IN (SELECT animal_id FROM Adoption) -- ... qui n'ont pas encore été ad
9LOCK IN SHARE MODE;
C'est alors que le premier client, M. Dupont, décide de craquer pour Bagherra.
Et M. Durant jette également son dévolu sur Bagherra (qui est décidément très très
mignon) !
L'insertion dans Client fonctionne mais l'insertion dans Adoption pose problème :
Et pour cause : Bagherra vient d'être adopté, à l'instant. Furieux, M. Durant s'en va, et
l'élevage a perdu un client. Il ne reste plus qu'à annuler sa transaction.
C'est pour éviter ce genre de situation qu'il vaut parfois mieux mettre un verrou exclusif sur
une sélection. Si l'on sait que cette sélection sert à déterminer quels changements vont
être faits, ce n'est pas la peine de laisser quelqu'un d'autre lire des informations qui
cesseront d'être justes incessamment sous peu.
Niveaux d'isolation
• lorsque l'on démarre une transaction, la session prend une photo des tables, et
travaille uniquement sur cette photo (donc sur des données potentiellement
périmées) tant qu'elle ne pose pas un verrou ;
• les requêtes SELECT ne posent pas de verrous si l'on ne le demande pas
explicitement ;
• les requêtes SELECT ... LOCK IN SHARE MODE, SELECT ... FOR
UPDATE, DELETE et UPDATE posent un verrou de clé suivante (sauf dans le cas d'une
recherche sur index unique, avec une valeur unique).
Syntaxe
1SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COM
READ | SERIALIZABLE }
• Le mot-clé GLOBAL définit le niveau d'isolation pour toutes les sessions MySQL qui
seront créées dans le futur. Les sessions existantes ne sont pas affectées.
• SESSION définit le niveau d'isolation pour la session courante.
• Si l'on ne précise ni GLOBAL, ni SESSION, le niveau d'isolation défini ne concernera
que la prochaine transaction que l'on ouvrira dans la session courante.
Les différents niveaux
REPEATABLE READ
Il s'agit du niveau par défaut, celui avec lequel vous travaillez depuis le
début. Repeatable read signifie "lecture répétable", c'est-à-dire que si l'on fait plusieurs
requêtes de sélection (non-verrouillantes) de suite, elles donneront toujours le même
résultat, quels que soient les changements effectués par d'autres sessions. Si l'on pense à
bien utiliser les verrous là où c'est nécessaire, c'est un niveau d'isolation tout à fait suffisant.
READ COMMITTED
READ UNCOMMITTED
Exemple
Session 1 :
1START TRANSACTION;
2
3UPDATE Race
4SET prix = 0
5WHERE id = 7;
Session 2 :
SERIALIZABLE
Ce niveau d'isolation se comporte comme REPEATABLE READ, sauf que lorsque le mode
autocommit est désactivé, tous les SELECT simples sont implicitement convertis en SELECT
... LOCK IN SHARE MODE.
En résumé
• Les verrous permettent de restreindre, voire interdire l'accès, à une partie des
données.
• Les verrous de table peuvent s'utiliser sur des tables transactionnelles et non-
transactionnelles, contrairement aux verrous de ligne qui ne sont disponibles que
pour des tables transactionnelles.
• Les verrous de lecture (tables) et partagés (lignes) permettent aux autres sessions
de lire les données verrouillées, mais pas de les modifier. Les verrous d'écriture
(tables) et exclusif (lignes) par contre, ne permettent aux autres sessions ni de lire,
ni de modifier les données verrouillées.
• Les verrous de ligne s'utilisent avec les transactions, et dépendent des index.
• Les requêtes de suppression, modification et insertion posent automatiquement un
verrou de ligne exclusif de clé suivante sur les lignes concernées par la requête. Les
requêtes de sélection par contre, ne posent pas de verrou par défaut, il faut en
poser un explicitement.
• Le comportement par défaut des verrous de ligne est défini par le niveau
d'isolation des transactions, qui est modifiable.
InnoDB permet la gestion des verrous au niveau des enregistrements et non plus au niveau
des tables.
Ces verrous sont associés à une requête de sélection. Il en existe de deux sortes.
Même chose que pour LOCK IN SHARE MODE, sauf que les autres utilisateurs ne peuvent
lire les enregistrements verrouillés.
Cela peut être utile lorsque l'on doit modifier des enregistrements à partir de données dans
ces mêmes enregistrements.
La validation de la transaction implicite ou explicite permet de déverrouiller les tables et les
enregistrements.
Si vous projetez d'utiliser régulièrement les verrous sur les enregistrements, il est judicieux de
donner une valeur en secondes à innodb_lock_wait_timeout pour éviter des effets de
verrous permanents. Vous pouvez d'ailleurs vérifier vos tables et l'état des derniers verrous
bloqués avec innodb monitor.
Il est possible de poser un verrou sur une table entière, ou seulement sur une ou plusieurs
lignes d'une table. Étant donné qu'un verrou empêche l'accès d'autres sessions, il est en
général plus intéressant de poser un verrou sur la plus petite partie de la base possible.
On peut poser un verrou sur toute la table Animal. Dans ce cas, les autres sessions
n'auront pas accès à cette table, tant que le verrou sera posé. Qu'elles veuillent en utiliser
les chiens, les chats, ou autre, tout leur sera refusé.
On peut aussi poser un verrou uniquement sur les lignes de la table qui contiennent des
chiens. De cette manière, les autres sessions pourront accéder aux chats, aux perroquets,
etc. Elles pourront toujours travailler, tant qu'elles n'utilisent pas les chiens.
Cette notion d'accès simultané aux données par plusieurs sessions différentes s'appelle la
concurrence. Plus la concurrence est possible, donc plus le nombre de sessions pouvant
accéder aux données simultanément est grand, mieux c'est. En effet, prenons l'exemple
d'un site web. En général, on préfère permettre à plusieurs utilisateurs de surfer en même
temps, sans devoir attendre entre chaque action de pouvoir accéder aux informations
chacun à son tour. Or, chaque utilisateur crée une session chaque fois qu'il se connecte à
la base de données (pour lire les informations ou les modifier). Préférez donc (autant que
possible) les verrous de ligne aux verrous de table !
1
LOCK TABLES nom_table [AS alias_table] [READ | WRITE] [, ...];
En utilisant READ, un verrou de lecture sera posé ; c'est-à-dire que les autres sessions
pourront toujours lire les données des tables verrouillées, mais ne pourront plus les modifier.
En utilisant WRITE, un verrou d'écriture sera posé. Les autres sessions ne pourront plus ni lire
ni modifier les données des tables verrouillées.
Pour déverrouiller les tables, on utilise UNLOCK TABLES. Cela déverrouille toutes les tables
verrouillées. Il n'est pas possible de préciser les tables à déverrouiller. Tous les verrous de
table d'une session sont relâchés en même temps.
elle ne peut plus accéder qu'aux tables sur lesquelles elle a posé un verrou ;
elle ne peut accéder à ces tables qu'en utilisant les noms qu'elle a donnés lors du
verrouillage (soit le nom de la table, soit le/les alias donné(s)) ;
s'il s'agit d'un verrou de lecture (READ), elle peut uniquement lire les données, pas les
modifier.
MySql n'inclut pas d'outils de backup pour les tables InnoDB. Pour effectuer un backup des
tables et des transactions, il existe deux méthodes : la copie de fichiers ou la réplication de
tables.
La copie des fichiers s'effectue après l'arrêt du serveur, vous devez alors copier les fichiers
de données et les fichiers de logs dans un endroit sûr.
La réplication utilise un serveur secondaire où les données sont copiées. Le support des
tables InnoDB permet une copie propre des données et journaux.
La restauration dépend de la méthode utilisée. Il faut cependant savoir que MySQL vérifie
les logs à chaque redémarrage du serveur. Les transactions non abouties seront donc
totalement annulées.
Après avoir récupéré les fichiers venant soit d'une simple copie soit d'une réplication,
remplacez et redémarrez le serveur si possible à partir de la ligne de commande, pour
vérifier que les opérations se déroulent bien.
Si l'opération échoue pour cause de fichiers corrompus, tentez de trouver un jeu de fichiers
non corrompus. SI cela échoue, vous pouvez toujours tenter de recréer les tables et
d'insérer les enregistrements que vous avez conservés.
- Types de sauvegardes
(a faire en exposé)
- Stratégies de sauvegarde
(a faire en exposé)
- Types de restauration
(a faire en exposé)