| 7.3 Verrouillage de tables
 7 Optimisation de MySQL
 Manuel de Référence MySQL 4.1 : Version Française
 
 . Méthodes de verrouillage
 ->Problème de verrouillage de tables
 
 
 | 
  7.3.2 Problème de verrouillage de tables  
 
MySQL utilise le verrouillage de table (au lieu du verrouillage de ligne
ou de colonne) sur tous les types de tables, sauf  
InnoDB
  et  
BDB
 ,
pour obtenir un système de verrou à très haute vitesse. 
Pour les tables  
InnoDB
  et  
BDB
 , MySQL n'utilise le
verrouillage de table que vous le demandez explicitement avec 
 
LOCK TABLES
 . Pour ces tables, nous vous recommandons de ne
jamais utiliser la commande  
LOCK TABLES
 , car  
InnoDB
  
utilise un verrouillage de ligne automatique, et  
BDB
  utilise 
un verrouillage de pages, pour assurer l'isolation des transactions. 
Pour les grandes tables, le verrouillage de table est meilleur que le 
verrouillage de lignes, pour la plupart des applications, mais il recèle
quelque pièges.
Le verrouillage de tables permet à de nombreux threads de lire dans la
même table, mais si un thread désire écrire dans la table, il doit
obtenir un verrou en écriture pour avoir un accès exclusif. Durant la
modification, les autres threads qui voudront lire dans cette table, devront
attendre. 
Comme les modifications de tables sont considérées comme plus importantes
que les lectures avec  
SELECT
 , toutes les commandes qui modifient
la table ont priorités sur les lectures. Cela devrait vous assurer que
les modifications ne sont pas retenues trop longtemps, à cause de nombreuses
lectures sur une même table. Vous pouvez toutefois modifier cela
avec l'option  
LOW_PRIORITY
  des commandes de modification, et
l'option  
HIGH_PRIORITY
  de  
SELECT
 ).
Depuis MySQL version 3.23.7, vous pouvez utiliser la variable
 
max_write_lock_count
  pour forcer MySQL à laisser temporairement
la place à toutes les commandes  
SELECT
 , après un certain nombre
de modifications dans la table. 
Le verrouillage de table est une mauvaise technique dans les situations suivantes : 
 
Des solutions aux problèmes sont :
Un client exécute une commande  
SELECT
  qui prend très longtemps.
Un autre client exécute une commande  
UPDATE
  sur la table. Ce client va devoir
attendre que la commande  
SELECT
  soit finie.
Un autre client exécute une autre commande  
SELECT
  sur la même table. Comme
 
UPDATE
  a la priorité sur  
SELECT
 , cette commande  
SELECT
 
va attendre que  
UPDATE
  soit finit. Il va donc attendre que le premier
 
SELECT
  soit fini. 
Essayez d'accélérer au maximum les commandes  
SELECT
 . Vous pourriez
passer par une table de sommaire pour cela.
Démarrez  
mysqld
  avec l'option  
--low-priority-updates
 .  Cela va
donner aux commandes de modification une priorité plus faible que  
SELECT
 .
Dans ce cas, c'est la commande  
SELECT
  du précédent scénario qui
s'exécutera avant la commande  
INSERT
 .
Vous pouvez donner à une commande spécifique  
INSERT
 ,  
UPDATE
  ou
 
DELETE
 , une priorité plus basse avec l'attribut  
LOW_PRIORITY
 .
Démarrez  
mysqld
  avec une valeur faible pour  
max_write_lock_count
  afin
de donner plus souvent la chance aux verrous  
READ
  la possibilité de lire
des données, entre deux verrous  
WRITE
 .
Vous pouvez spécifier que toutes les modifications d'un thread spécifique doivent
être faites avec un priorité basse, en utilisant la commande SQL : 
 
SET LOW_PRIORITY_UPDATES=1
 .
 Syntaxe de 
SET
 .
Vous pouvez spécifier qu'une requête particulière  
SELECT
  est très importante,
en utilisant l'attribut  
HIGH_PRIORITY
 .  Syntaxe de 
SELECT
 .
Si vous avez des problèmes avec des  
INSERT
  combinés avec des  
SELECT
 ,
utilisez les tables  
MyISAM
  car elle supportent les commandes
 
SELECT
 s et  
INSERT
  simultanées.
Si vous voulez mélanger les commandes  
INSERT
  et  
SELECT
 , 
utilisez l'attribut  
DELAYED
  de la commande  
INSERT
  pour résoudre
ce problème.
 Syntaxe de 
INSERT
 .
Si vous avez des problèmes avec des combinaisons de 
 
SELECT
  et  
DELETE
 , l'option  
LIMIT
  de 
 
DELETE
  peut aider.  Syntaxe de 
DELETE
 .
Utiliser  
SQL_BUFFER_RESULT
  avec les commandes  
SELECT
  peut aider
à réduire la durée des verrous.
 Syntaxe de 
SELECT
 .
Vous pouvez changer le code de verrouillage dans le fichier  
mysys/thr_lock.c
  pour
n'utiliser qu'une queue unique. Dans ce cas, les lectures et écritures auront la même
priorité, ce qui peut aider certaines applications. 
Voici quelques conseils avec le système de verrouillage de MySQL :
 
Les accès concurents ne sont pas un problème si vous ne mélangez pas les
sélections et les modifications de nombreuses lignes dans la même table.
Vous pouvez utiliser  
LOCK TABLES
  pour accélérer les opérations : de nombreuses
modifications dans un même verrou seront plus rapides. Répartir le contenu de la table
en plusieurs tables peut aussi aider.
Si vous rencontrez des problèmes de vitesse avec les verrous de tables, vous devez être
capables d'améliorer les performances en convertissant certaines tables en  
InnoDB
  ou
 
BDB
 .
 Le moteur de tables 
InnoDB
 .  Tables 
BDB
 ou 
BerkeleyDB
 .
 |