¿Cómo puedo configurar MySQL Innodb para manejar 1000 inserciones por hora?

10

Tengo un sitio web de mucho tráfico donde es posible que se inserten miles de registros nuevos cada hora.

Este error está paralizando el sitio:

PDOException: SQLSTATE[40001]: Serialization failure: 1213 
Deadlock found when trying to get lock; 
try restarting transaction: INSERT INTO {location_instance} 
(nid, vid, uid, genid, lid) VALUES (:db_insert_placeholder_0, 
:db_insert_placeholder_1, :db_insert_placeholder_2, 
:db_insert_placeholder_3, :db_insert_placeholder_4); 
Array ( [:db_insert_placeholder_0] => 1059 [:db_insert_placeholder_1] => 
1059 [:db_insert_placeholder_2] => 0 [:db_insert_placeholder_3] => 
cck:field_item_location:1059 [:db_insert_placeholder_4] => 1000 )

Me sorprendería mucho si MySQL no pudiera manejar este tipo de carga. Entonces, mis preguntas son, ¿es un problema de base de datos y cómo puedo configurar MySQL para poder manejar tanto tráfico?

Tengo una copia de mi sitio web configurado en un servidor de desarrollo con scripts que simulan la carga de contenido que se agrega al sitio web. Estoy ejecutando Ubuntu, LAMP stack, con 16GB de RAM.

Es cierto que no conozco mucho las bases de datos. De hecho, estoy comenzando con el my.cnf predeterminado que viene con él después de que finaliza 'apt-get install'. Las tablas son todas Innodb. ¿Qué configuración y enfoque de configuración inicial recomendaría para comenzar a resolver este problema?

Déjame saber qué más información necesitas.

Gracias

usuario658182
fuente
¿Estás comenzando con el my.cnf predeterminado para producción? Hombre, tienes que optimizarlo más. Te detallaré más en mi respuesta. :-)

Respuestas:

11

Se trata de un punto muerto, no un problema de cuello de botella de rendimiento.

Si tiene mil registros nuevos por hora, está muy lejos de alcanzar los límites de MySQL. MySQL puede manejar al menos 50 veces su carga.

Los puntos muertos son causados ​​por el código de la aplicación y no son culpa del servidor de la base de datos. Los puntos muertos no se pueden arreglar en el lado del servidor MySQL, excepto en algunas situaciones específicas.

InnoDBpuede mostrarle información detallada sobre el punto muerto al ejecutar SHOW ENGINE INNODB STATUSen el indicador de MySQL o con mysql -uroot -p... -e "SHOW ENGINE INNODB STATUS".

Sin embargo, esto solo muestra el último punto muerto que ocurrió, no hay registro de punto muerto.

Afortunadamente, hay una herramienta pt-deadlock-logger que se ocupa de ese problema, se encarga del InnoDBestado de la encuesta y guarda toda la información detallada del punto muerto antes de que se actualice con un nuevo punto muerto.

Valor
fuente
¡Bueno saber! Veo en el comando show status la información sobre el bloqueo y la consulta y tabla relacionadas. Dado que esto está en mi código, ¿cómo puedo usar esta información del comando de estado para comenzar a depurar el problema? La consulta PHP PDO es bastante sencilla: conecta, prepara, ejecuta, repite. Me encantaría publicar cualquier código o mensaje de estado si eso ayudara.
usuario658182
@ user658182 revise esta publicación en stackoverflow sobre cómo lidiar con los puntos muertos: cómo evitar el punto muerto mysql encontrado al tratar de obtener el bloqueo
Valor
1
@ max-vernon gracias por la edición de la sintaxis, claramente en inglés, no es mi lengua materna :-).
Valor
1
-e "MOSTRAR ESTADO INNODB DEL MOTOR"
glifo
8

Esto podría ser tan simple como una parte de su código que ejecuta una transacción:

insert into t1...
insert into t2...
commit;

mientras que otra parte de su código modifica las mismas tablas en un orden diferente:

delete from t2 where...
delete from t1 where...
commit;

Si ambas transacciones se ejecutan al mismo tiempo, puede ocurrir una condición de carrera: la primera transacción no puede modificarse t2porque está bloqueada por la segunda transacción; mientras que la segunda transacción está bloqueada de manera similar porque t1está bloqueada por la primera transacción. MySQL elige una transacción para ser la "víctima" donde falla la INSERT / UPDATE / DELETE. La aplicación necesita detectar ese error y volver a intentar la declaración, tal vez después de una pausa para que la otra transacción tenga tiempo de finalizar. Nada que ver con los límites de capacidad, solo un momento desafortunado que puede verse exacerbado por la forma en que se organiza el código. Cambie los DELETEs en la transacción # 2, o los INSERTs en la transacción # 1, y luego no hay conflicto: cada transacción esperará el acceso a la (s) tabla (s) que necesita.

En MySQL 5.6, puede ejecutar con la opción innodb_print_all_deadlocks habilitada para recopilar información sobre todos los puntos muertos (no solo el más reciente) en el registro de errores de MySQL.

[Descargo de responsabilidad obligatorio: soy un empleado de Oracle. Lo anterior es mi opinión personal, no una declaración oficial.]

Max Webster
fuente