2012-07-04 15 views
10

Estoy intentando comprender un punto muerto encontrado por MySQL durante el procesamiento simultáneo de clientes en las mismas tablas. Esta es la parte interesante del comando "show InnoDB ESTADO":Intentando entender el interbloqueo de MySQL en la tabla InnoDB

------------------------ 
LATEST DETECTED DEADLOCK 
------------------------ 
120704 16:17:51 
*** (1) TRANSACTION: 
TRANSACTION 0 3547576, ACTIVE 0 sec, process no 10886, OS thread id 140547111458560 inserting 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s), undo log entries 1 
MySQL thread id 41941, query id 1725666 localhost testsuite update 
insert into `INode` (`status`,`_type`,`group`,`ctime`,`parent`,`shared`,`basename`,`_rowid`,`displayname`,`user`,`content_type`,`mtime`,`position`,`atime`,`size`) values ('Published','Group','12','2012-07-04 16:17:48.996869','2',null,'1','12','1','3','application/x-empty','2012-07-04 16:17:48.996896','1','2012-07-04 16:17:48.996914',null) 
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547576 lock mode S waiting 
Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** (2) TRANSACTION: 
TRANSACTION 0 3547575, ACTIVE 0 sec, process no 10886, OS thread id 140547107845888 inserting, thread declared inside InnoDB 493 
mysql tables in use 1, locked 1 
13 lock struct(s), heap size 3024, 17 row lock(s), undo log entries 21 
MySQL thread id 41940, query id 1725808 localhost testsuite update 
replace into `INode` (`status`,`_type`,`position`,`group`,`ctime`,`parent`,`basename`,`_rowid`,`displayname`,`user`,`content_type`,`mtime`,`shared`,`atime`,`size`) values ('Published','Group','0','2','2012-07-04 16:17:49','1','groups','2','admin','3','application/x-empty','2012-07-04 16:17:49',null,'2012-07-04 16:17:49',null),('Published','Group','1','11','2012-07-04 16:17:51.064074','2','1','11','1','3','inode/directory','2012-07-04 16:17:51.064074',null,'2012-07-04 16:17:51.064074',null) 
*** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547575 lock_mode X locks rec but not gap 
Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 80000001; asc  ;; 1: len 6; hex 67726f757073; asc groups;; 2: len 4; hex 80000002; asc  ;; 

Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547575 lock_mode X waiting 
Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** WE ROLL BACK TRANSACTION (1) 

lo que entiendo de este registro es que la transacción (1) está a la espera de obtener un bloqueo compartido en el índice de la tabla INodeparent_basenametestsuite. INode. Ahora, la transacción (2) tiene un bloqueo exclusivo sobre este mismo índice. Pero lo que es extraño, es que la transacción (2) también está esperando un bloqueo X sobre la tabla dada. ¿Porqué es eso? Si la transacción (2) ya tiene el bloqueo, ¿por qué lo espera?

(en general, no he encontrado ninguna documentación que explica exactamente cómo leer la salida del comando de estado - que sería interesante si alguien podría señalar que a mí también)

+0

¿Encontró una respuesta a esto? Tengo el mismo problema. –

+0

No, no he podido encontrar una respuesta a este problema. Después de probar durante algunas horas a lo entienden, sólo tenía que codificar los procesos de programación diferente y serializar una parte de los accesos a las bases de datos con el fin de evitar cualquier posible situación de bloqueo encontrado por MySQL. En cuanto a rendimiento, probablemente sea peor, pero no tenía otra posibilidad. – RedGlow

+0

sobre cómo traducir la salida de comando de estado, usted (o cualquier otra persona que necesita ayuda en esto) puede que desee comprobar este blog que he encontrado https://www.percona.com/blog/2014/10/28/how- a-acuerdo-con-MySQL-estancamientos/ – CodeBurner

Respuesta

1

En este caso, 2 transacción adquiere un bloqueo compartido para una sentencia anterior. (* (2) mantiene el bloqueo (S) :)

a continuación, la transacción 1 intentó adquirir un bloqueo exclusivo en la misma fila, y está a la espera para el bloqueo compartido para eliminar.

Luego, la transacción 2, en otra instrucción, intentó adquirir un bloqueo exclusivo en la misma fila. Se produjo un punto muerto.

+0

No, (2) ya tiene un bloqueo exclusivo. (1) está tratando de obtener un bloqueo compartido tú. –

-1

No sé si ayudará o no, pero una cosa a considerar es la secuencia de operaciones que causan el bloqueo. Parece ser que en un solo lugar de la aplicación que está creando bloqueos como

Tabla 1 Tabla 2

y en otro haciendo

Tabla 2 Tabla 1 (solo ejemplo)

Sin al ver el código real, sugiero que se analice este tipo de cosas y se asegure de que las haga en la misma secuencia de trabajo/actualización/inserción de registros para que funcionen como

insertar/actualizar de la tabla 1 luego insertar/actualizar la tabla 2

De esta manera, siempre se intenta primero el primer candado en la tabla 1. si eso no puede funcionar, entonces ni siquiera prueba la tabla 2 hasta la mesa 1 es lanzado.

A continuación, se aplican independientemente de los cambios a la tabla 2 y terminar su transacción. Cuando se liberan las tablas 2 y 1, la próxima transacción que espera su publicación en la tabla 1 puede continuar.

Cuestiones relacionadas