Maison > Article > base de données > Une brève compréhension des verrous MySQL, des transactions et de MVCC
La colonne
Plus de recommandations d'apprentissage gratuites connexes : Tutoriel MySQL(vidéo)
Le contenu suivant est extrait de "High Performance MySQL" (3e édition)
"MySQL utilise la soumission automatique par défaut ( AUTOCOMMIT ). Autrement dit, si vous ne démarrez pas explicitement une transaction, chaque requête est traitée comme une transaction pour effectuer une opération de validation. Vous pouvez activer ou désactiver le mode de validation automatique en définissant la variable AUTOCOMMIT
”
journal de restauration. Undo_log est écrit sur le disque avant l'exécution du vrai SQL, puis les données de la base de données sont exploitées. Si une exception ou une restauration se produit, vous pouvez effectuer des opérations inverses basées sur undo_log pour restaurer les données telles qu'elles étaient avant l'exécution de la transaction.
Persistance Une fois qu'une transaction est validée normalement, son impact sur la base de données devrait être permanent. Même si le système tombe en panne à ce moment-là, les données modifiées ne seront pas perdues. InnoDB est le moteur de stockage de MySQL et les données sont stockées sur le disque. Cependant, si des E/S disque sont nécessaires à chaque fois pour lire et écrire des données, l'efficacité sera très faible. À cette fin, InnoDB fournit un cache (Buffer Pool) comme tampon pour accéder à la base de données : lors de la lecture des données de la base de données, elles seront d'abord lues depuis le Buffer Pool. S'il n'y a pas de Buffer Pool, elles seront lues depuis le Buffer Pool. disque et placés dans le pool de tampons ; lors de l'écriture des données dans la base de données, elles seront d'abord écrites dans le pool de tampons et les données modifiées dans le pool de tampons seront régulièrement actualisées sur le disque.
Une telle conception entraîne également des problèmes correspondants : si les données sont soumises et qu'elles sont toujours dans le pool de mémoire tampon (le disque n'a pas encore été vidé), que dois-je faire si MySQL tombe en panne ou perd de l'alimentation ? Les données seront-elles perdues ?
La réponse est non, MySQL assure la persistance grâce au mécanisme redo_log. redo_log est redo log En termes simples, lorsque les données sont modifiées, en plus de modifier les données dans le Buffer Pool, l'opération sera également enregistrée dans le redo_log lorsque la transaction est soumise, l'interface fsync ; sera appelé pour vider la plaque redo_log. Si MySQL tombe en panne, vous pouvez lire les données dans redo_log et récupérer la base de données au redémarrage.
Isolement
L'isolement est le plus complexe d'ACID, qui implique le concept de niveau d'isolement, il y en a quatre au total
Pour faire simple, le niveau d'isolement stipule : la modification des données dans une transaction, quelles transactions sont visibles et lesquelles ne le sont pas. L'isolation consiste à gérer la séquence d'accès de plusieurs demandes de lecture et d'écriture simultanées.
L'implémentation spécifique de l'isolation par MySQL sera discutée plus tard.
Cohérence
Assurez-vous de la cohérence grâce à la restauration, à la récupération et à l'isolation dans des environnements simultanés.
Par le biais du précédent question I Sachant qu'une seule exécution DDL sera automatiquement soumise en tant que transaction, qu'il s'agisse de la concurrence de plusieurs SQL ou de la concurrence de plusieurs transactions organisées manuellement contenant plusieurs SQL, cela entraînera des problèmes de concurrence de transactions.
Plus précisément :
Nous avons mentionné le niveau d'isolement de la transaction ci-dessus, tous les niveaux d'isolement de MySQL peut garantir qu'aucune écriture sale ne se produira, donc les seuls problèmes restants sont les lectures sales, les lectures non répétables et les lectures fantômes.
Regardons de plus près comment chaque niveau d'isolement résout ou ne résout pas les problèmes ci-dessus :
Lecture non validée. Ce niveau n'ajoute aucun verrou pendant le processus de lecture. Il se verrouille uniquement pendant la demande d'écriture, donc l'opération d'écriture modifie les données pendant le processus de lecture. . Provoquera des lectures sales. Des lectures non répétables et des lectures fantômes se produiront naturellement.
La lecture validée, comme la lecture non validée, est également déverrouillée en lecture et verrouillée en écriture. La différence est que le mécanisme MVCC est utilisé pour éviter le problème des lectures sales. Il existe également des problèmes de lectures non répétables et de lectures fantômes. Nous parlerons de MVCC en détail plus tard.
Niveau d'isolement par défaut de MySQL, à ce niveau MySQL utilise deux méthodes pour résoudre les problèmes
De plus, le verrouillage Next-Key est utilisé pour résoudre dans une certaine mesure le problème de la lecture fantôme. Nous en reparlerons plus tard.
Sous ce niveau d'isolement, les transactions sont exécutées en série. Si la validation automatique est désactivée, InnoDB convertit implicitement toutes les instructions SELECT ordinaires en SELECT ... LOCK IN SHARE MODE. Autrement dit, un verrou partagé en lecture est implicitement ajouté à l'opération de lecture, évitant ainsi les problèmes de lectures sales, de lectures non répétables et de lectures fantômes.
«En prenant comme exemple notre MySQL couramment utilisé, le moteur InnoDB de MySQL implémente MVCC.Contrôle de concurrence multiversion (MCC ou MVCC), est une méthode de contrôle de concurrence couramment utilisée par les systèmes de gestion de bases de données pour fournir un accès simultané à la base de données et dans les langages de programmation pour implémenter la mémoire transactionnelle (MCC ou MVCC) est une méthode de contrôle de concurrence qui est généralement utilisée par les systèmes de gestion de bases de données pour fournir un accès simultané à la base de données et pour implémenter le stockage des transactions dans les langages de programmation.
En termes simples, il s'agit d'une méthode utilisée par la base de données pour contrôler la concurrence. Chaque base de données peut avoir une implémentation différente de MVCC.
Quels problèmes MVCC peut-il résoudre ?
L'image suivante provient de "High Performance MySQL" (3e édition)
Ce livre est bien écrit et bien traduit. Ma compréhension systématique initiale de MySQL était également due à la lecture de ce livre. Cependant, je pense personnellement qu'il y a quelques problèmes avec la description de la façon dont MVCC est implémenté.
Jetons un coup d'œil à ce qui ne va pas
Tout d'abord, jetons un coup d'œil à la documentation officielle de MySQL I. par rapport aux versions 5.1, 5.6 et 5.7 du document [1] ont presque la même description de cette partie de MVCC.
D'après la documentation, il est évident que trois colonnes cachées sont ajoutées à chaque donnée :
Ici, j'ajoute un diagramme de structure interne MySQL comprenant un segment de restauration
Chaîne de versions
Avant nous, j'ai a parlé du concept de undo_log. Chaque journal d'annulation a un attribut roll_pointer. Ensuite, toutes les versions seront connectées dans une liste chaînée par l'attribut roll_pointer. Nous appelons cette liste chaînée une chaîne de versions. du dossier actuel.
LireVue
En masquant les colonnes et les chaînes de versions, MySQL peut restaurer les données vers une version spécifiée, mais la version vers laquelle restaurer doit spécifiquement être déterminée en fonction de ReadView ; Ce qu'on appelle ReadView signifie qu'une transaction (enregistrée comme transaction A) prend un instantané de l'ensemble du système de transaction (trx_sys) à un certain moment. Lorsqu'une opération de lecture est effectuée ultérieurement, l'ID de transaction dans les données lues sera comparé à. l'instantané trx_sys, de sorte que Déterminez si les données sont visibles par ReadView, c'est-à-dire si elles sont visibles par la transaction A.
Jusqu'à présent, nous avons découvert que MVCC est implémenté sur la base de champs cachés, de chaînes undo_log et de ReadView.
Nous avons parlé plus tôt de la solution utilisant MVCC dans le niveau d'isolement validé en lecture Problème de lecture sale. Ici je fais référence à deux articles :
InnoDB recherchera uniquement les lignes de données dont la version est antérieure à la version actuelle de la transaction (c'est-à-dire que le numéro de version de la ligne est inférieur ou égal au numéro de version du système de version de la transaction), cela garantit que les lignes lues par les données soit existent déjà avant le démarrage de la transaction, soit ont été insérées ou modifiées par la transaction elle-même. Par conséquent, aucune lecture sale ne se produira.
Lecture validée L'apparition de lectures non répétables sous le niveau d'isolement est due au mécanisme de génération de la vue en lecture. Au niveau Lecture validée, les données qui ont été validées avant l'exécution de l'instruction actuelle sont visibles. Lors de l'exécution de chaque instruction, la vue de lecture est fermée et la vue de lecture actuelle est recréée. De cette manière, l'intervalle de transactions de la vue de lecture peut être créé sur la base de la liste de transactions globale actuelle. En termes simples, sous le niveau d'isolement de lecture validée, MVCC génère une version d'instantané pour chaque sélection, de sorte que chaque sélection lira différentes versions de données, afin que des lectures non répétables se produisent .
Le niveau d'isolement de lecture répétable résout le problème de lecture non répétable dans une transaction Multiple les lectures ne produiront pas de résultats différents, garantissant des lectures répétables. Dans l'article précédent, nous avons dit que la lecture répétable avait deux méthodes d'implémentation, l'une est la méthode de verrouillage pessimiste et l'autre MVCC est la méthode de verrouillage optimiste.
Le niveau d'isolement de lecture répétable peut résoudre le problème de la lecture non répétable. La raison fondamentale est que le mécanisme de génération de la vue en lecture est différent de celui de la lecture validée.
Contrairement à la lecture validée, sous le niveau d'isolement de lecture répétable, lorsqu'une transaction est créée, la vue de lecture globale actuelle est générée et maintenue jusqu'à la fin de la transaction. Cela permet des lectures reproductibles.
Grâce au mécanisme MVCC, bien que les données deviennent répétables, les données que nous lisons peuvent être des données historiques, pas des données opportunes, ni les données actuelles de la base de données. ! Pour cette façon de lire les données historiques, nous l'appelons lecture instantanée (lecture instantanée), et la manière de lire la version actuelle des données de la base de données est appelée lecture actuelle (lecture actuelle) Référence[3]
Afin de résoudre le problème de lecture fantôme dans la lecture actuelle, MySQL la transaction utilise le verrouillage de la clé suivante.
La lecture répétable évite la lecture fantôme grâce au mécanisme de verrouillage de la touche suivante.
Le moteur de stockage InnoDB dispose de trois algorithmes de verrouillage de ligne, qui sont :
Le verrouillage à clé suivante est un type de verrouillage de ligne, qui équivaut au verrouillage d'enregistrement + verrouillage d'espace ; sa caractéristique est qu'il verrouille non seulement l'enregistrement lui-même (la fonction de verrouillage d'enregistrement), mais verrouille également une plage (la fonction de verrouillage de l'espace).
Lorsque InnoDB analyse l'enregistrement d'index, il ajoute d'abord un verrou de ligne (Record Lock) à l'enregistrement d'index, puis ajoute un verrou d'espace (Gap Lock) aux espaces des deux côtés de l'enregistrement d'index. Après avoir ajouté le verrou d'espacement, les autres transactions ne peuvent pas modifier ou insérer d'enregistrements dans cet espace.
Lorsque l'index interrogé contient des attributs uniques, Next-Key Lock sera optimisé et rétrogradé en Record Lock, qui verrouille uniquement l'index lui-même, pas la plage.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!