¿Por qué Apache se está volviendo loco y matando a MySQL?

8

Apache se ha salido de control en los últimos días y ha bloqueado MySQL dos veces. Todo comenzó cuando migré un sitio web de WordPress que también contiene un foro phpBB.

No tengo mucha experiencia en administración de servidores, por lo que me ha resultado muy difícil determinar qué está causando el problema. Cuando noté que MySQL estaba caído, ejecuté TOP y vi mi pico de carga del sistema a 98.00. El servidor ejecuta 10 V-HOSTS, todos los cuales reciben una buena cantidad de tráfico, por lo que obviamente vi muchos procesos apache-2 en ejecución.

La alta carga del servidor continuó durante 10 minutos y luego volvió a su estado normal. No vi un pico de tráfico de red en este punto.

Desafortunadamente, el registro de errores de MySQL se deshabilitó (ahora se vuelve a habilitar), por lo que no hay pistas allí. Pero estoy bastante seguro de que es porque Apache estaba consumiendo todos los recursos, por lo que se eliminó la identificación del proceso MySQL.

Mis preguntas son:

La próxima vez que ocurra esto, ¿cómo puedo identificar qué está causando el pico de carga del sistema? ¿Podría ser un script php que se volvió loco? ¿Podría ser un ataque DDOS?

¿Hay alguna manera de reiniciar MySQL automáticamente cuando falla?

Ya lo he instalado htop. ¿Podría esto ser más útil que top?

Aquí las estadísticas de mi servidor:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 
Bob Flemming
fuente
Aunque los registros estaban deshabilitados, ¿ dmesgayudaría?
Daniel

Respuestas:

9

Es posible que MySQL aún no registre nada, porque lo que probablemente esté sucediendo es que el sistema lo está eliminando sin ceremonias debido a la presión de la memoria del sistema por parte de los hijos de Apache. Debería haber un rastro de esto en / var / log / syslog.

MySQL debería intentar reiniciarse en un bloqueo o terminación forzada, pero a menos que haya suficiente memoria disponible, no puede hacer eso ... y mysqld_safe no ve este segundo fallo como un "bloqueo" sino más bien como un "rechazo a empezar ", por lo que no seguirá intentándolo. El intento de reinicio fallido a menudo es malinterpretado por los administradores como el "bloqueo", ya que la naturaleza de la falla original está oculta detrás de un mensaje fácilmente ignorado en el registro de errores de MySQL:

mysqld_safe Number of processes running now: 0

Vea InnoDB Crash Post Mortem para una circunstancia que sospecho que es similar a la suya.

La respuesta aparentemente simple a "por qué" es que entre Apache y MySQL, la carga que tiene y sus configuraciones actuales, no tiene suficiente memoria en la máquina, y hay algún punto de inflexión relacionado con la carga de tráfico que saca esta condición .

Apache atiende cada solicitud simultánea del navegador desde un proceso secundario, por lo que a medida que aumenta el número de conexiones simultáneas, aumentará el número de elementos secundarios. Primero tendrá que limitar este valor en la configuración de apache para que pueda comprender qué está causando realmente el aumento de las conexiones concurrentes ... ¿es simplemente un pico de tráfico pesado pero legítimo? ¿Algún tipo de denegación de servicio? ¿Consultas de bases de datos que retrasan las solicitudes porque se ejecutan demasiado tiempo? ¿Algo que necesita optimización?

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

Limitar los procesos concurrentes de Apache debería ayudar a prevenir esto, pero para ser claros, es ingenuo pensar que esta es la solución completa, por lo que no quiero dar a entender eso. Una vez que los procesos se limitan a un nivel razonable o al menos más seguro, puede proceder a identificar lo que realmente está sucediendo. (Hay otros controles de restricción en Apache, pero esa no es mi área de especialización).

La "mejor práctica" es, por supuesto, ejecutar su base de datos en un hardware diferente para que la aplicación no pueda eliminarla. Si bien parece más eficiente, en la superficie, "maximizar la utilización" de una máquina compartiéndola, esta es una economía falsa. La mayoría de la memoria utilizada por MySQL, en una carga de trabajo típica, se asigna en el momento del inicio y se mantiene durante el tiempo que MySQL Server se está ejecutando. Es probable que las demandas en la CPU compartan los tiempos pico para MySQL y Apache, ya que en última instancia están sirviendo la misma carga. En realidad, podría estar mejor con dos máquinas m1.large en lugar de la única m1.xlarge, y el costo sería el mismo ya que la más pequeña es exactamente la mitad del precio de la más grande ... incluso si ya pagó por adelantado para el descuento adicional, este cambio se puede lograr .

Michael - sqlbot
fuente
Gracias por su respuesta, fue realmente útil. Verifiqué / ver / log / syslog y encontré las siguientes líneas: 18 de diciembre 15:48:38 ip-10-33-164-173 kernel: [29714591.071719] Sin memoria: proceso de muerte 28369 (mysqld) puntaje 21 o sacrificio niño 18 de diciembre 15:48:38 ip-10-33-164-173 kernel: [29714591.071753] Proceso eliminado 28369 (mysqld) total-vm: 2520332kB, anon-rss: 335304kB, file-rss: 0kB Entonces, ¿piensa limitar el La configuración de maxclients en apache es la mejor opción para evitar que esto suceda ¿Cuál crees que sería un valor más seguro?
Bob Flemming
1
Sugeriría que limitar la cantidad máxima de clientes sería la mejor manera de comenzar el proceso de comprender las circunstancias que contribuyen a cualquier avalancha que esté experimentando. Tendrá que calcular un valor más seguro según sus circunstancias, la cantidad de memoria libre en el sistema y la cantidad típica de memoria que observa que usan los niños apache. Demasiado bajo, y las solicitudes comenzarán a respaldarse; demasiado alto y estás donde estás ahora. Luego, supervise los procesos generados y observe su memoria libre y los registros del servidor.
Michael - sqlbot
1

Tienes algunos puntos para verificar:

-Compruebe los mensajes / var / log /: oomkiller puede matar el proceso mysql si no hay más memoria para usar. Verifique el ram con free -lm (sin caché)

-Si usa apache con prefork mpm: verifique el número de procesos. Si apache apila un número importante de procesos (durante una carga de trabajo pesada) con un enlace a mysql, la latencia y la memoria utilizada pueden crecer rápidamente.

-Compruebe el número de subprocesos lanzados por mysql con un estado global de mostrar : threads_cached, threads_created y threads_running son importantes para verificar (threads_created debe estar cerca de 0).

-Compruebe el carnero utilizado por Mysql.

Jérémy Muñoz
fuente
0

También podría considerar implementar cpusets y reservar recursos para mysql. Eso es lo más cercano a ejecutar estos servicios en hardware diferente, y aún así le brinda los beneficios de mantener un solo servidor.

skohrs
fuente