web-dev-qa-db-fra.com

Comment résoudre trop de connexions et une erreur fatale dans mysql fonctionnant sur vps

J'exécute une application PHPlist sur mon serveur linode, exécutant simultanément 12 PHP, chacun ouvrant une connexion MySQL. Maintenant, lorsque j'accède à PHPlist, il affiche souvent cette erreur:

Erreur fatale: Désolé, le serveur est actuellement trop occupé, veuillez réessayer plus tard.

Lorsque j'essaie d'accéder à phpMyAdmin, cela me montre une erreur # 1040. La sortie de mes scripts PHP qui traversent les travaux cron montre:

Avertissement PHP: mysqli_connect (): (HY000/1040): Trop de connexions

J'utilise la pile LAMP sur le serveur avec phpMyAdmin; la sortie top dans le terminal affiche mysqld en utilisant 100-130% CPU. Lorsque j'essaie de résoudre ce problème, j'ai obtenu des indices:

  • Augmenter la variable max_connection: j'utilise 200 (100 par défaut)
  • Cache de table ouvert: 512 (400 par défaut)

Il y a beaucoup de variables à définir mais je ne peux pas déterminer celles spécifiques, je reçois des références de: trop de connexions et http://dev.mysql.com/doc /refman/5.5/en/table-cache.html

Mais selon mon utilisation, comment augmenter la mémoire et quelle est la mémoire maximale difficile pour moi.

Sur mon serveur, j'utilise environ 12 PHP, une application PHPlist pour l'envoi d'e-mails et une base de données importante pour les enregistrements d'utilisateurs.

Veuillez m'aider à résoudre ce problème.

9
Shashank

Vous devez d'abord exécuter cette requête:

SELECT user,Host FROM mysql.user
WHERE super_priv='Y' AND
CONCAT(user,'@',Host) <> 'root@localhost';

Ceci listera tous les utilisateurs qui ont privilège SUPER . La plupart des utilisateurs qui effectuent un traitement de base de données lié à l'application ne nécessitent pas ce privilège. Selon la MySQL Documentation , ceux qui ont le privilège SUPER peuvent faire ce qui suit:

  • Exécutez CHANGE MASTER TO pour contrôler les coordonnées de réplication
  • TUER ou mysqladmin kill pour tuer les threads appartenant à d'autres comptes
  • PURGER LES JOURNAUX BINAIRES pour supprimer systématiquement les journaux binaires
  • Apportez des modifications de configuration à l'aide de SET GLOBAL pour modifier les variables système globales
  • commande de débogage mysqladmin
  • activation ou désactivation de la journalisation
  • effectuer des mises à jour même si la variable système * read_only * est activée
  • démarrage et arrêt de la réplication sur des serveurs esclaves
  • spécification de tout compte dans l'attribut DEFINER des programmes et vues stockés
  • ICI IS LE PLUS IMPORTANT POUR VOTRE PROBLÈME: : vous permet de vous connecter (une fois) même si la limite de connexion contrôlée par la variable système max_connections est atteinte.

Vous devrez vous connecter en tant que root @ localhost et révoquer le privilège SUPER comme suit:

UPDATE mysql.user SET super_priv='N'
WHERE super_priv='Y' AND
CONCAT(user,'@',Host) <> 'root@localhost';
FLUSH PRIVILEGES;

Une fois que vous faites cela, chaque fois que tous les utilisateurs inondent les connexions mysql, seulement root@localhost peut se connecter. Après tout, si tout le monde et sa grand-mère avaient un privilège SUPER, cela empêcherait root@localhost de toujours se connecter avant tout le monde. Si max_connections est à 200 et que vous devez le porter à 300 sans avoir à redémarrer mysqld, vous pouvez augmenter dynamiquement les max_connections avec cette commande:

mysql> SET GLOBAL max_connections = 300;

Cela permettra plus de connexions efficaces immédiatement, mais n'augmentez pas simplement arbitrairement le nombre sur un coup de tête. Vous devez vous assurer que mysql a suffisamment RAM pour s'adapter à l'augmentation.

CAVEAT: Si vous changez dynamiquement max_connections à 300, veuillez le mettre dans /etc/my.cnf

[mysqld]
max_connections=300

Vous pouvez exécuter mysqltuner.pl sur votre serveur de base de données MySQL. Si vous ne l'avez pas, exécutez ce qui suit:

cd
wget mysqltuner.pl
Perl mysqltuner.pl

La troisième ligne sous Performance Metrics a ceci

-------- Performance Metrics -------------------------------------------------
[--] Up for: 8d 20h 46m 22s (8M q [10.711 qps], 129K conn, TX: 90B, RX: 19B)
[--] Reads / Writes: 4% / 96%
[--] Total buffers: 2.1G global + 5.4M per thread (2000 max threads)
[OK] Maximum possible memory usage: 12.6G (80% of installed RAM)

Voir les 5,4 millions par thread? Cela est multiplié par max_connections. Dans cet exemple, ce serait un maximum d'environ 10,8 G de RAM. Par conséquent, chaque fois que vous augmentez max_connections, vous devez exécuter mysqltuner.pl et vérifier si vous appuyez sur le système d'exploitation pour trop de mémoire.

Dans tous les cas, limiter les privilèges SUPER donne à ces utilisateurs la possibilité d'atténuer l'inondation de mysqld avec DB Connections.

12
RolandoMySQLDBA
  1. La variable globale max_connections détermine le nombre maximal de connexions simultanées à MySQL. Assurez-vous que vous avez une valeur élevée pour cette variable. Vous pouvez augmenter cette valeur à 300 ou 400 et essayer de redémarrer MySQL après ces paramètres.
  2. Concevez votre application de telle sorte qu'une connexion MySQL reste ouverte pendant une très courte période.
  3. Vous devez également vérifier que le code client n'utilise pas les connexions persistantes (telles que mysql_pconnect ()) de manière incorrecte.

Exécutez également Flush status; commande sur le serveur MySQl pour réduire cette valeur.

J'espère que ces suggestions vous aideront.

2
Mahesh Patil

Vérifiez si votre disque est plein, cela peut provoquer la même erreur:

df -h

vous montrera l'espace restant sur chaque partition, vous devrez probablement vérifier la partition racine / (ou/var/si vous avez une partition supplémentaire pour cela):

df -h /
0
rubo77