Prêt à travailler
Créer la table tb_innodb_lock
supprimer la table si elle existe test_innodb_lock; CREATE TABLE test_innodb_lock ( a INT (11), b VARCHAR (20) ) ENGINE INNODB DEFAULT charset = utf8; insérer dans les valeurs test_innodb_lock (1, 'a'); insérer dans les valeurs test_innodb_lock (2, 'b'); insérer dans les valeurs test_innodb_lock (3, 'c'); insérer dans les valeurs test_innodb_lock (4, 'd'); insérer dans les valeurs test_innodb_lock (5, 'e');
Créer un index
créer l'index idx_lock_a sur test_innodb_lock (a); créer l'index idx_lock_b sur test_innodb_lock (b);
Démo de verrouillage MySQL
Commencez par changer la transaction de validation automatique en validation manuelle:
set autocommit=0;
Nous démarrons deux fenêtres de session A et B, simulant une saisie de la serrure et l'autre étant bloquée sans saisir.
Verrouillage de ligne (écriture et lecture)
Une exécution de fenêtre
update test_innodb_lock set b = 'a1' où a = 1;
SELECT * à partir de test_innodb_lock;
Nous pouvons voir le résultat mis à jour dans la fenêtre A
Exécution de la fenêtre B
SELECT * à partir de test_innodb_lock;
Nous pouvons voir que la fenêtre B ne peut pas voir les résultats mis à jour, mais les anciennes données sont toujours visibles. En effet, l'enregistrement de a = 1 a été verrouillé par l'instruction SQL exécutée par la fenêtre A et l'opération de validation n'a pas été exécutée. Ainsi, la fenêtre B voit toujours les anciennes données. Il s'agit de la "lecture validée" dans le niveau d'isolement MySQL.
La fenêtre A exécute l'opération de validation
COMMETTRE;
Requête de la fenêtre B
SELECT * à partir de test_innodb_lock;
À ce stade, nous avons constaté que la fenêtre B avait lu les dernières données
Verrouillage de ligne (écriture et écriture)
La fenêtre A effectue la mise à jour d'un enregistrement = 1
update test_innodb_lock set b = 'a2' où a = 1;
Pour le moment, il n'y a pas de validation et le verrou est maintenu par la fenêtre A.
La fenêtre B met également à jour l'enregistrement de a = 1
update test_innodb_lock set b = 'a3' où a = 1;
Comme vous pouvez le voir, la fenêtre B a été dans un état bloqué parce que la fenêtre A n'a pas encore exécuté la validation et détient toujours un verrou. La fenêtre B ne peut pas saisir le verrou enregistré dans la ligne a = 1, elle a donc été bloquée en attente.
La fenêtre A exécute l'opération de validation
COMMETTRE;
Changements dans la fenêtre B
Vous pouvez voir que la fenêtre B a été exécutée avec succès à ce moment
Verrouillage de la table
Lorsqu'un index échoue, le verrou de ligne est mis à niveau vers un verrou de table. L'une des méthodes d'échec d'index consiste à modifier automatiquement ou manuellement l'index. Le champ a lui-même est un entier, nous ajoutons des guillemets, il devient une chaîne, cette fois l'index sera invalide.
La fenêtre A met à jour l'enregistrement de a = 1
update test_innodb_lock set b = 'a4' où a = 1 ou a = 2;
La fenêtre B met à jour l'enregistrement de a = 2
mise à jour test_innodb_lock set b = 'b1' où a = 3;
À ce moment, il a été découvert que bien que les lignes mises à jour des fenêtres A et B étaient différentes, la fenêtre B était toujours bloquée, car l'index de la fenêtre A a échoué, ce qui a entraîné la mise à niveau du verrou de ligne en verrou de table, le verrouillage de la table entière et la fenêtre d'index B est bloqué.
La fenêtre A exécute l'opération de validation
COMMETTRE;
Changements dans la fenêtre B
Vous pouvez voir que la fenêtre B a été exécutée avec succès à ce moment
Verrouillage d'espacement
Qu'est-ce qu'un verrou d'écart
Lorsque nous utilisons des conditions de plage pour interroger des données, InnoDB verrouille les données de cette plage. Par exemple, il y a 4 éléments de données avec un identifiant: 1, 3, 5 et 7, nous recherchons des données comprises entre 1 et 7. Ensuite, 1-7 sera verrouillé. 2, 4 et 6 sont également dans la plage de 1 à 7, mais ces enregistrements de données n'existent pas, ces 2, 4 et 6 sont appelés intervalles.
Le mal du verrouillage de l'écart
Lors de la recherche d'une plage, toutes les données de l'ensemble de la plage seront verrouillées. Même certaines données qui n'existent pas dans cette plage seront verrouillées de manière innocente. Par exemple, je souhaite insérer 2 en 1, 3, 5 et 7, à ce moment 1. -7 est verrouillé et 2 ne peut pas du tout être inséré. Dans certains scénarios, cela aura un impact important sur les performances
Démo de Gap Lock
Nous modifions d'abord la valeur du champ a en 1, 3, 5, 7, 9
La fenêtre A met à jour les données dans la plage a = 1 ~ 7
update test_innodb_lock set b = 'b5' où a> 1 et a <7;
La fenêtre B insère les données à a = 2
insérer dans les valeurs test_innodb_lock (2, "b6");
A ce moment, on constate que l'opération de mise à jour de a = 2 dans la fenêtre B est en attente, car les données dans la plage de 1 à 7 sont verrouillées par l'écart et verrouillées. La mise à jour ne peut réussir que lorsque la fenêtre A exécute la validation
Analyse de verrouillage de ligne
Exécuter des commandes d'analyse SQL
afficher le statut comme «innodb_row_lock%»;
Description du nom de la variable
Innodb_row_lock_current_waits: Le nombre de verrous actuellement en attente.
Innodb_row_lock_time: la durée entre le démarrage du système et le verrou actuel.
Innodb_row_lock_time_avg: Le temps moyen passé à attendre le verrou à chaque fois.
Innodb_row_lock_time_max: Le temps le plus long qu'il faut au verrou pour attendre depuis le démarrage du système.
Innodb_row_lock_waits: Le nombre total d'attentes pour les verrous après le démarrage du système jusqu'à présent.
Enfin
Merci à tous d'avoir vu ici, l'article a des lacunes, et vous êtes invités à le signaler; si vous pensez qu'il est bien écrit, veuillez me donner un coup de pouce.