2011-05-31 29 views
10

Tengo una gran aplicación web de producción (Glassfish 3.1 + MySQL 5.5). Todas las tablas son InnoDB. Una vez por varios días, la aplicación se cuelga por completo. SHOW FULL PROCESSLIST muestra muchas consultas de inserción o actualización simples en tablas diferentes, pero todos tengan la condición deMySQL InnoDB se bloquea esperando bloqueos a nivel de tabla

Esperando a nivel de tabla de bloqueo

Ejemplos:

update user<br> 
set user.hasnewmessages = NAME_CONST('in_flag',_binary'\0' COLLATE 'binary') 
where user.id = NAME_CONST('in_uid',66381) 

insert into exchanges_itempacks 
set packid = NAME_CONST('in_packId',332149), type = NAME_CONST('in_type',1), itemid = NAME_CONST('in_itemId',23710872) 

Las consultas con el 'tiempo' más largos son esperando el bloqueo del nivel de la mesa también. Por favor, ayuda a averiguar por qué MySQL intenta obtener el bloqueo de nivel y lo que puede bloquear todas estas tablas. Todos los artículos sobre el bloqueo de InnoDB dicen que este motor no usa bloqueo de tabla si no lo fuerza a hacerlo.

Mi my.cnf tiene esto:

innodb_flush_log_at_trx_commit = 0 
innodb_support_xa = 0 
innodb_locks_unsafe_for_binlog = 1 
innodb_autoinc_lock_mode=2 

registro binario está apagado. No tengo "LOCK TABLES" u otros comandos de bloqueo explícitos. Las transacciones son READ_UNCOMMITED.

SHOW ENGINE INNODB STATUS de salida: http://avatar-studio.ru:8080/ph/imonout.txt

+0

¿Por qué tiene el nivel de aislamiento en "READ_UNCOMMITED"., Es un modo sucio y nunca recomendaría configurarlo en servidores de producción. –

+0

Puede haber información útil aquí: [Modos de bloqueo InnoDB] (http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html), especialmente las bloqueos de intención y las posibles causas de interbloqueos, como se describe más adelante en el documento. También tenga en cuenta los comentarios de los usuarios al final. – Mike

Respuesta

1

Creo que hay algunas situaciones en las que MySQL un bloqueo de tabla completa (es decir, el uso de auto-inc). Encontré un enlace que puede ayudarlo: http://mysqldatabaseadministration.blogspot.com/2007/06/innodb-table-locks.html

También revise el código de persistencia de java que tiene todos los errores confirmados/revertidos y cerrados. (Cerrando siempre en bloque finalmente.)

Pruebe la configuración innodb_table_locks=0 en la configuración de MySQL. http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_table_locks

sólo algunas ideas ...

+1

Andrey ya tiene innodb_autoinc_lock_mode = 2 que se aseguraría de que ninguna instrucción similar a una inserción tome ningún bloqueo autoinc. –

0

Esto puede parecer simple, pero que no tiene una declaración de larga duración que se seleccione posiblemente bloqueando actualizaciones e inserciones? ¿No hay ninguna consulta que se esté ejecutando realmente y no bloqueada?

0

¿Ha considerado utilizar MyISAM en lugar de InnoDB?

Si no está utilizando ninguna característica transaccional, MyISAM podría tener más sentido. Es más simple, más fácil de optimizar y, dado que no tiene capacidades transaccionales sofisticadas, es más fácil de configurar en my.cnf.

Además, dependiendo del tipo de carga de db que cree su aplicación, MyISAM podría ser más apropiado. Prefiero MyISAM para aplicaciones de lectura pesada, de nuevo, es más fácil de configurar y entender.

Otras propuestas:

  • Podría ser una buena idea para encontrar una manera de no utilizar NAME_CONST en su SQL. "This function was added in MySQL 5.0.12. It is for internal use only." Cuando la documentación de un producto de código abierto dice esto, probablemente sea una buena idea prestar atención.

  • Por defecto, MySQL almacena todas las tablas InnoDB & esquemas de datos en 1 archivo enorme, podría haber algún tipo de nivel de sistema operativo de bloqueo en ese archivo en particular que propogates a MySQL que impide todo acceso mesa. Al usar la opción innodb_file_per_table, puede eliminar ese posible problema. Esto también hace que MySQL sea más eficiente en el uso del espacio.

0

en este caso, usted tiene que crear varias tabla de base de datos usando la misma columna entre sí y no hacer la inserción más de 3.000 fila por cada mesa, en este caso, si desea introducir más datos en la tabla que hay que crear otra tabla dinámica (generar tabla usando código) e insertar nuevos datos en esta tabla y acceder a los datos de esa tabla. en su condición si más y más tablas tendrán que generar, entonces debe crear una nueva base de datos.

Creo que este consejo le ayudará a diseñar su base de datos con más cuidado y resolver el error.

4

¿Está utilizando MSQLDump para hacer una copia de seguridad de su base de datos mientras la aplicación sigue accediendo a ella? Esto podría causar ese comportamiento.

+0

Este fue el problema con mi base de producción. Acabo de leer que esto se puede remediar utilizando las opciones -single-transaction -quick for innodb-databases, así que lo intentaré. – runholen

1

Veo que usted usa fuertemente NAME_CONST en su código. Solo trata de no usarlo. Ya sabes, mysql a veces puede tener problemas (también encontré varios errores), por lo que te recomiendo que no confíes en funciones que no son tan comunes ni están bien probadas. Está relacionado con los nombres de las columnas, ¿entonces tal vez bloquea algo? Bueno, no debería si solo afecta el resultado, pero ¿quién sabe? Esto es sospechoso Además, esto está marcado como una función para uso interno solamente.

Cuestiones relacionadas