Apache a perdu le contrôle au cours des derniers jours et a fait planter MySQL deux fois. Tout a commencé lorsque j'ai migré un site WordPress sur lequel contient également un forum phpBB.
Je ne suis pas très expérimenté en administration de serveur, il m'a donc été très difficile d'identifier la cause du problème. Quand j'ai remarqué que MySQL était en panne, j'ai exécuté TOP et j'ai vu mon pic de charge système à 98,00. Le serveur exécute 10 V-HOSTS qui reçoivent tous une bonne quantité de trafic, donc je voyais évidemment de nombreux processus apache-2 en cours d'exécution.
La charge élevée du serveur s'est poursuivie pendant 10 minutes, puis elle est revenue à un état normal. Je n'ai pas vu de pointe de trafic réseau à ce stade.
Malheureusement, la journalisation des erreurs MySQL a été désactivée (elle est maintenant réactivée), donc aucun indice là-bas. Mais je suis sûr que c'est parce qu'Apache consommait toutes les ressources, donc l'ID de processus MySQL a été tué.
Mes questions sont:
La prochaine fois que cela se produira - comment puis-je identifier la cause du pic de charge du système? Serait-ce un script php devenu fou? Serait-ce une attaque DDOS?
Existe-t-il un moyen de redémarrer automatiquement MySQL lorsqu'il se bloque?
J'ai maintenant installé htop
. Cela pourrait-il être plus utile que top
?
Voici mes statistiques de serveur:
m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS
la source
dmesg
aiderait-il?Réponses:
MySQL peut toujours ne rien enregistrer, car ce qui se passe probablement, c'est qu'il est tué sans cérémonie par le système en raison de la pression sur la mémoire système des enfants d'Apache. Il devrait y avoir une trace de ceci dans / var / log / syslog.
MySQL devrait essayer de se redémarrer en cas de plantage ou d'arrêt forcé, mais à moins que suffisamment de mémoire ne soit disponible, il ne peut pas le faire ... et ce deuxième échec n'est pas vu par mysqld_safe comme un "plantage" mais plutôt comme un "refus de ", il ne continuera donc pas à essayer. La tentative de redémarrage a échoué est souvent mal interprétée par les administrateurs comme le «plantage», car la nature de l'échec d'origine est cachée derrière un message facilement ignoré dans le journal des erreurs MySQL:
Voir InnoDB Crash Post Mortem pour une circonstance que je soupçonne est similaire à la vôtre.
La réponse apparemment simple à "pourquoi" est qu'entre Apache et MySQL, la charge que vous avez et vos configurations actuelles, vous n'avez pas assez de mémoire sur la machine, et il y a un point de basculement lié à la charge de trafic qui fait sortir cette condition .
Apache sert chaque demande de navigateur simultanée à partir d'un processus enfant, donc du nombre de connexions simultanées augmente, le nombre d'enfants augmentera. Vous devrez d'abord limiter cette valeur dans la configuration d'apache afin que vous puissiez comprendre ce qui cause réellement l'augmentation des connexions simultanées ... est-ce simplement un pic de trafic lourd mais légitime? Une sorte de déni de service? Les requêtes de base de données qui retardent les demandes parce qu'elles s'exécutent trop longtemps? Quelque chose à optimiser?
http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients
Limiter les processus Apache simultanés devrait aider à éviter cela, mais pour être clair, il est naïf de penser que c'est la solution complète, donc je ne veux pas impliquer cela. Une fois que les processus sont limités à un niveau raisonnable ou au moins plus sûr, vous pouvez procéder à l'identification de ce qui se passe réellement. (Il existe d'autres contrôles de restriction sur Apache, mais ce n'est pas mon domaine d'expertise.)
La "meilleure pratique" est bien sûr d'exécuter votre base de données sur un matériel différent afin que l'application ne puisse pas le tuer. Bien qu'il semble plus efficace, à première vue, de "maximiser l'utilisation" d'une machine en la partageant, il s'agit d'une fausse économie. La majorité de la mémoire utilisée par MySQL, dans une charge de travail typique, est allouée au démarrage et conservée aussi longtemps que MySQL Server est en cours d'exécution. Les demandes sur le CPU sont susceptibles de partager des heures de pointe pour MySQL et Apache, car elles servent finalement la même charge. Vous pourriez en fait être mieux avec deux machines m1.large au lieu de la seule m1.xlarge, et le coût serait le même puisque la plus petite est exactement la moitié du prix de la plus grande ... même si vous avez déjà payé à l'avance pour la remise supplémentaire, ce changement peut être accompli .
la source
Vous avez quelques points à vérifier:
-Vérifiez le / var / log / messages: oomkiller peut tuer le processus mysql s'il n'y a plus de mémoire à utiliser. Vérifiez le ram avec -lm gratuit (sans cache)
-Si vous utilisez apache avec prefork mpm: vérifiez le nombre de processus. Si apache empile un nombre important de processus (lors d'une lourde charge de travail) avec un lien vers mysql, la latence et la mémoire utilisée peuvent rapidement augmenter.
-Vérifiez le nombre de threads lancés par mysql avec un statut global show : threads_cached, threads_created et threads_running sont importants à vérifier (threads_created doit être proche de 0).
-Vérifiez le bélier utilisé par Mysql.
la source
Vous pouvez également étudier l'implémentation de cpusets et la réservation de ressources pour mysql. C'est le plus proche de l'exécution de ces services sur un matériel différent, tout en vous offrant toujours les avantages de la maintenance d'un serveur unique.
la source