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
Respuestas:
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.
InnoDB
puede mostrarle información detallada sobre el punto muerto al ejecutarSHOW ENGINE INNODB STATUS
en el indicador de MySQL o conmysql -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
InnoDB
estado de la encuesta y guarda toda la información detallada del punto muerto antes de que se actualice con un nuevo punto muerto.fuente
Esto podría ser tan simple como una parte de su código que ejecuta una transacción:
mientras que otra parte de su código modifica las mismas tablas en un orden diferente:
Si ambas transacciones se ejecutan al mismo tiempo, puede ocurrir una condición de carrera: la primera transacción no puede modificarse
t2
porque está bloqueada por la segunda transacción; mientras que la segunda transacción está bloqueada de manera similar porquet1
está 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.]
fuente