Un verrou est un mécanisme par lequel un ordinateur coordonne l'accès simultané à une ressource par plusieurs processus ou threads. Dans une base de données, outre la contention traditionnelle des ressources de calcul (CPU, RAM, I/O), les données sont aussi une ressource partagée par de nombreux utilisateurs. Comment assurer la cohérence et la validité de l'accès simultané aux données est un problème que toutes les bases de données doivent résoudre, et les conflits de verrouillage sont également un facteur important affectant les performances de l'accès simultané aux bases de données. De ce point de vue, les verrous sont particulièrement importants et plus complexes pour les bases de données.
Les verrous dans MySQL sont divisés en trois catégories selon la granularité des verrous :
- Verrouillage global : verrouille toutes les tables de la base de données.
- Verrouillage au niveau de la table : chaque opération verrouille toute la table.
- Verrouillage au niveau de la ligne : chaque opération verrouille les données de la ligne correspondante.
Ensuite, nous présenterons tour à tour ces trois aspects :
verrouillage global
Le verrou global consiste à verrouiller l'intégralité de l'instance de base de données. Après le verrouillage, l'intégralité de l'instance est en lecture seule. Les instructions d'écriture DML, les instructions DDL et les instructions de validation de transaction qui ont été mises à jour seront bloquées.
Son scénario d'utilisation typique consiste à effectuer une sauvegarde logique de l'intégralité de la base de données et à verrouiller toutes les tables pour obtenir une vue cohérente et garantir l'intégrité des données. Ensuite, regardons l'utilisation spécifique :
①Ajouter un verrou global
flush tables with read lock ;
②Sauvegarde des données
mysqldump -uroot –p1234 itcast > itcast.sql
-- 其中itcast是要备份的数据库的名称,itcast.sql是备份后的存储路径文件名
-- 注意,此命令不是mysql的命令,不能在mysql中执行,需要在windows或linux命令行中执行
③ Libérez le verrou
unlock tables ;
L'ajout d'un verrou global à la base de données est une opération relativement lourde et pose les problèmes suivants :
- S'il est sauvegardé sur la bibliothèque principale, aucune mise à jour ne peut être effectuée pendant la période de sauvegarde et l'entreprise doit essentiellement être fermée.
- Si elle est sauvegardée sur la bibliothèque esclave, la bibliothèque esclave ne peut pas exécuter le journal binaire (binlog) synchronisé à partir de la bibliothèque maître pendant la période de sauvegarde, ce qui entraînera un retard maître-esclave.
Remarque : Dans le moteur InnoDB, nous pouvons ajouter le paramètre --single-transaction lors de la sauvegarde pour terminer la sauvegarde cohérente des données sans verrouillage : mysqldump --single-transaction -uroot –p123456 itcast > itcast.sql
serrure de table
Les verrous au niveau de la table verrouillent la table entière pour chaque opération. La granularité du verrouillage est grande, la probabilité de conflits de verrouillage est la plus élevée et la simultanéité est la plus faible. Appliqué dans les moteurs de stockage tels que MyISAM, InnoDB et BDB.
Les verrous au niveau de la table sont principalement divisés en trois catégories :
- serrure de table
- Verrouillage des métadonnées (méta data lock, MDL)
- verrouillage d'intention
① verrou de montre
Pour les verrous de table, il existe deux types : verrou de lecture partagé de table (verrou de lecture) , verrou d'écriture exclusif de table (verrou d'écriture)
Si un verrou en lecture partagé est ajouté, ce client et les autres clients peuvent uniquement lire et ne peuvent pas écrire ; si un verrou en écriture exclusif est ajouté, ce client peut à la fois lire et écrire, tandis que les autres clients ne peuvent ni lire ni écrire.
-- 加锁
lock tables 表名... read/write。
-- 释放锁
unlock tables / 客户端断开连接 。
② Verrouillage des métadonnées (MDL)
Le processus de verrouillage MDL est automatiquement contrôlé par le système et n'a pas besoin d'être utilisé explicitement, il sera ajouté automatiquement lors de l'accès à une table . La fonction principale du verrou MDL est de maintenir la cohérence des données des métadonnées de la table. Lorsqu'il y a des transactions actives sur la table, les métadonnées ne peuvent pas être écrites. Afin d'éviter les conflits entre DML (ajout, suppression, modification et requête) et DDL (structure de la table des opérations), assurez-vous de l'exactitude de la lecture et de l'écriture.
Les métadonnées ici peuvent être simplement comprises comme la structure de table d'une table . C'est-à-dire que lorsqu'une certaine table implique des transactions non validées, la structure de table de cette table ne peut pas être modifiée.
Les verrous de métadonnées peuvent être divisés en deux catégories :
- Verrou de lecture partagé MDL : Lors de l'ajout, de la suppression, de la modification et de l'interrogation d'une table, le verrou partagé MDL est automatiquement ajouté
- Verrou exclusif en écriture MDL : lorsque la structure de la table est modifiée, le verrou exclusif MDL est automatiquement ajouté
-- 查看元数据锁的加锁情况
select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks ;
③ Verrouillage d'intention
Afin d'éviter les conflits entre les verrous de ligne et les verrous de table ajoutés lors de l'exécution DML, des verrous d'intention sont introduits dans InnoDB, de sorte que les verrous de table n'ont pas besoin de vérifier si chaque ligne de données a des verrous de ligne et utilisent des verrous d'intention pour réduire les contrôles de verrouillage de table. . Autrement dit : lors de l'exécution d'opérations DML, des verrous de ligne seront ajoutés aux lignes concernées et des verrous d'intention seront également ajoutés à la table. Et d'autres clients, lors de l'ajout d'un verrou de table à cette table, détermineront si le verrou de table peut être ajouté avec succès en fonction du verrou d'intention ajouté à la table, au lieu de juger la situation de verrouillage de ligne ligne par ligne.
Les verrous d'intention peuvent être divisés en deux catégories :
- Verrou partagé d'intention (IS) : ajouté par l'instruction select ... verrouiller en mode partage. Compatible avec le verrou partagé de verrouillage de table (lecture), mutuellement exclusif avec le verrou exclusif de verrouillage de table (écriture).
- Verrou exclusif d'intention (IX) : ajouté par insertion, mise à jour, suppression, sélection... pour mise à jour. Les verrous partagés (lecture) et les verrous exclusifs (écriture) s'excluent mutuellement avec les verrous de table, et les verrous d'intention ne s'excluent pas mutuellement
Une fois la transaction validée, le verrou partagé d'intention et le verrou exclusif d'intention seront libérés automatiquement.
-- 查看意向锁及行锁的加锁情况
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
verrouillage au niveau de la ligne
Verrouillage au niveau de la ligne, chaque opération verrouille les données de ligne correspondantes. La granularité de verrouillage est la plus petite, la probabilité de conflits de verrouillage est la plus faible et la simultanéité est la plus élevée. Appliqué dans le moteur de stockage InnoDB.
Les données d'InnoDB sont organisées en fonction des index, et les verrous de ligne sont implémentés en verrouillant les éléments d'index sur l'index, plutôt qu'en verrouillant les enregistrements. Pour les verrous au niveau de la ligne, il existe trois catégories principales :
- Verrou de ligne (Record Lock) : Un verrou qui verrouille un seul enregistrement de ligne, empêchant les autres transactions de mettre à jour et de supprimer cette ligne. Il est pris en charge sous les niveaux d'isolement RC et RR.
- Gap Lock : Verrouillez l'écart d'enregistrement d'index (à l'exclusion de cet enregistrement), assurez-vous que l'écart d'enregistrement d'index reste inchangé et empêchez d'autres transactions de s'insérer dans cet écart, ce qui entraînerait une lecture fantôme. Les deux sont pris en charge sous le niveau d'isolement RR.
- Next-Key Lock : une combinaison de verrouillage de ligne et de verrouillage d'espace, qui verrouille les données en même temps et verrouille l'écart devant les données. Pris en charge sous le niveau d'isolement RR.
① verrouillage de ligne
InnoDB implémente les deux types de verrous de ligne suivants :
- Verrou partagé (S) : permet à une transaction de lire une ligne, empêchant les autres transactions d'obtenir des verrous exclusifs sur le même ensemble de données.
- Verrou exclusif (X) : autorise les transactions qui acquièrent des verrous exclusifs à mettre à jour les données, empêchant d'autres transactions d'acquérir des verrous partagés et exclusifs sur le même ensemble de données.
Par défaut, InnoDB s'exécute au niveau d'isolement de la transaction REPEATABLE READ et InnoDB utilise des verrous de clé suivante pour les recherches et les analyses d'index afin d'empêcher les lectures fantômes.
- Lors de la recherche par rapport à un index unique , lors de l'exécution d'une correspondance équivalente sur des enregistrements existants, il sera automatiquement optimisé pour un verrou de ligne .
- Le verrou de ligne d'InnoDB est un verrou pour l'index. Si vous ne récupérez pas les données via la condition d'index, InnoDB verrouillera tous les enregistrements de la table, puis il sera mis à niveau vers un verrou de table.
② Gap lock / Pro key lock
Par défaut, InnoDB s'exécute au niveau d'isolement de la transaction REPEATABLE READ et InnoDB utilise des verrous de clé suivante pour les recherches et les analyses d'index afin d'empêcher les lectures fantômes.
- La requête équivalente sur l'index (index unique) est optimisée comme un gap lock lors du verrouillage d'un enregistrement qui n'existe pas.
- Dans la requête équivalente sur l'index (index ordinaire), lorsque la dernière valeur ne répond pas aux exigences de la requête lors du déplacement vers la droite, le verrou de la clé suivante dégénère en un verrou d'espace (c'est-à-dire la valeur actuelle et l'espace derrière elle sont verrouillés).
- La requête de plage sur l'index (index unique) accédera à la première valeur qui ne remplit pas la condition (c'est-à-dire, verrouille la plage).
Avis:Le seul but d'un verrou d'espace est d'empêcher d'autres transactions de s'insérer dans l'espace. Les verrous d'espace peuvent coexister, et un verrou d'espace pris par une transaction n'empêche pas une autre transaction de prendre un verrou d'espace sur le même espace.