Un article pour comprendre en détail les verrous de ligne MySQL, les verrous de table et les verrous d'espacement

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;

1.png

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;

2.png

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;

3.png

À 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;

4.png

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

5.png

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;

6.png

À 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

7.png

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");

8.png

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%»;

9.png

  • 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.


Je suppose que tu aimes

Origine blog.51cto.com/14849432/2542676
conseillé
Classement