Étude approfondie de l'insertion dans l'échec de la table de verrouillage d'instruction select (activé)


Quelques jours avant la description de l' erreur , un collègue chargé de l'
exploitation et de la maintenance de la base de données mysql a utilisé l'insertion dans l' instruction select from en production pour sauvegarder une table en production. Par conséquent, toute la table de sauvegarde a été verrouillée et l'entreprise a été affectée environ 10 minutes. . Voyant cette déclaration, ma première réaction est que l'instruction select peut également verrouiller la table, mais l'échec de la production prouve que la table est bien verrouillée. Par conséquent, il est nécessaire d' étudier minutieusement la situation de l' insertion dans le choix de l'acquisition des verrous.

Revue des pannes pour
créer des tables analogiques et des enregistrements analogiques

[root@localhost] 17:39:55 [testdb1]>show create table t_test_1\G;
*************************** 1. row ***************************
       Table: t_test_1
Create Table: CREATE TABLE `t_test_1` (
  `id` int(11) NOT NULL,
  `name` char(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

[root@localhost] 17:40:30 [testdb1]>select * from t_test_1;
+----+-------+
| id | name  |
+----+-------+
|  1 | trest |
|  2 | e99e  |
|  3 | test  |
|  4 | fresd |
|  5 | fsfa  |
+----+-------+
5 rows in set (0.00 sec)

[root@localhost] 17:40:17 [testdb1]>show create table t_test_2\G;
*************************** 1. row ***************************
       Table: t_test_2
Create Table: CREATE TABLE `t_test_2` (
  `id` int(11) NOT NULL,
  `name` char(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

Simuler l'insertion dans l'opération de sélection


[root@localhost] 17:41:32 [testdb1]>begin;
Query OK, 0 rows affected (0.00 sec)

[root@localhost] 17:41:33 [testdb1]>insert into t_test_2 select * from t_test_1 where name like 'trest';
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

Obtenir des informations de verrouillage sur innodb


[root@localhost] 17:42:00 [(none)]>show engine innodb status\G;
TRANSACTIONS
------------
Trx id counter 182551
Purge done for trx's n:o < 182551 undo n:o < 0 state: running but idle
History list length 0
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421524582451936, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 182546, ACTIVE 20 sec
3 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 1
MySQL thread id 7, OS thread handle 140049254979328, query id 82 localhost root

Les informations de verrouillage obtenues à partir du moteur innodb sont insuffisantes. Je ne vois que 3 structures de verrouillage et 6 verrous de ligne. Je ne connais pas les verrous appliqués dans ce tableau, ni le type de verrous appliqués pour. Je ne connais pas cette information. Juste des recherches et je ne comprends pas comment l'échec s'est produit.

Heureusement, la base de données mysql fournit un paramètre innodb_status_output_locks, qui peut afficher des informations de verrouillage plus détaillées.

Activez le paramètre innodb_status_output_locks pour
activer le paramètre innodb_status_output_locks, qui n'est pas activé par défaut, il doit donc être activé.

[root@localhost] 17:31:12 [(none)]>show variables like 'innodb_status_output_locks';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_status_output_locks | OFF   |
+----------------------------+-------+
1 row in set (0.00 sec)

[root@localhost] 17:47:41 [(none)]>set global innodb_status_output_locks=on;
Query OK, 0 rows affected (0.00 sec)

[root@localhost] 17:47:41 [(none)]>show variables like 'innodb_status_output_locks';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_status_output_locks | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

Obtenez
les informations détaillées sur le verrouillage d' InnoDB. Vous trouverez ci-dessous les informations détaillées sur le verrouillage obtenues après l'activation du paramètre innodb_status_output_locks.


[root@localhost] 17:48:28 [(none)]>show engine innodb status\G;
TRANSACTIONS
------------
Trx id counter 182552
Purge done for trx's n:o < 182551 undo n:o < 0 state: running but idle
History list length 0
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421524582451936, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 182551, ACTIVE 5 sec
3 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 1
MySQL thread id 11, OS thread handle 140049254979328, query id 100 localhost root
TABLE LOCK table `testdb1`.`t_test_1` trx id 182551 lock mode IS
RECORD LOCKS space id 97 page no 3 n bits 72 index PRIMARY of table `testdb1`.`t_test_1` trx id 182551 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 6; hex 00000002c710; asc       ;;
 2: len 7; hex af000000310110; asc     1  ;;
 3: len 10; hex 74726573742020202020; asc trest     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 00000002c710; asc       ;;
 2: len 7; hex af00000031011c; asc     1  ;;
 3: len 10; hex 65393965202020202020; asc e99e      ;;

Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 6; hex 00000002c710; asc       ;;
 2: len 7; hex af000000310128; asc     1 (;;
 3: len 10; hex 74657374202020202020; asc test      ;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000004; asc     ;;
 1: len 6; hex 00000002c710; asc       ;;
 2: len 7; hex af000000310134; asc     1 4;;
 3: len 10; hex 66726573642020202020; asc fresd     ;;

Record lock, heap no 6 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 00000002c710; asc       ;;
 2: len 7; hex af000000310140; asc     1 @;;
 3: len 10; hex 66736661202020202020; asc fsfa      ;;

TABLE LOCK table `testdb1`.`t_test_2` trx id 182551 lock mode IX

À partir des informations ci-dessus, nous pouvons clairement voir que t_test_1 a acquis le verrou IS et dispose de 5 informations de verrouillage d'enregistrement, c'est-à-dire que 5 enregistrements sont verrouillés et que cette table ne contient que 5 enregistrements, la table entière est donc verrouillée.
TABLE LOCK table testdb1.t_test_1 trx id 182551 lock mode IS

Verrouillez l'intégralité de l'
insertion de la solution de la table dans t_test_2 select * from t_test_1 où nom comme "trest"; Dans cette instruction sql, le champ de nom de la table t_test_1 n'a pas d'index et l'index a subi une analyse complète de la table. Si vous créez un index dans le champ de nom, que se passera-t-il? Modifiez-le pour
créer un index

[root@localhost] 17:54:33 [testdb1]>alter table t_test_1 add index idx_t_test_1_name (name);
Query OK, 0 rows affected (0.24 sec)
Records: 0  Duplicates: 0  Warnings: 0

[root@localhost] 17:54:52 [testdb1]>begin;
Query OK, 0 rows affected (0.00 sec)

[root@localhost] 17:54:55 [testdb1]>insert into t_test_2 select * from t_test_1 where name like 'trest';
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Réobtenir les détails du verrou innodb


TRANSACTIONS
------------
Trx id counter 182565
Purge done for trx's n:o < 182565 undo n:o < 0 state: running but idle
History list length 0
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421524582451936, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 182560, ACTIVE 3 sec
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 11, OS thread handle 140049254979328, query id 105 localhost root
TABLE LOCK table `testdb1`.`t_test_1` trx id 182560 lock mode IS
RECORD LOCKS space id 97 page no 4 n bits 72 index idx_t_test_1_name of table `testdb1`.`t_test_1` trx id 182560 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 10; hex 74726573742020202020; asc trest     ;;
 1: len 4; hex 80000001; asc     ;;

TABLE LOCK table `testdb1`.`t_test_2` trx id 182560 lock mode IX

Le voyez-vous? Ici, il n'y a qu'un seul verrou d'enregistrement, pas la table entière.

L'analyse de cet échec est incomplète, à suivre.

Je suppose que tu aimes

Origine blog.51cto.com/15061930/2642055
conseillé
Classement