Amazon EC2, mysql abandonne le démarrage car InnoDB: mmap (x octets) a échoué; errno 12

95

J'ai mis en place un micro serveur de instance sur EC2 en fonction de ce que j'ai lu ici

Le serveur mysql échoue fréquemment et pour la troisième fois, le serveur mysql est parti. Les journaux ne montrent que

120423 09:13:38 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
120423 09:14:27 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
120423  9:14:27 [Note] Plugin 'FEDERATED' is disabled.
120423  9:14:27 InnoDB: The InnoDB memory heap is disabled
120423  9:14:27 InnoDB: Mutexes and rw_locks use GCC atomic builtins
120423  9:14:27 InnoDB: Compressed tables use zlib 1.2.3
120423  9:14:27 InnoDB: Using Linux native AIO
120423  9:14:27 InnoDB: Initializing buffer pool, size = 512.0M
InnoDB: mmap(549453824 bytes) failed; errno 12
120423  9:14:27 InnoDB: Completed initialization of buffer pool
120423  9:14:27 InnoDB: Fatal error: cannot allocate memory for the buffer pool
120423  9:14:27 [ERROR] Plugin 'InnoDB' init function returned error.
120423  9:14:27 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
120423  9:14:27 [ERROR] Unknown/unsupported storage engine: InnoDB
120423  9:14:27 [ERROR] Aborting

Qu'est-ce que c'est vraiment failed; errno 12 ? Et comment pourrais-je donner plus d'espace / mémoire ou tout ce qui est nécessaire pour résoudre ce problème.

Je corrige ce problème à chaque fois en redémarrant tout le système et en supprimant tous les journaux et en redémarrant le serveur mysql. Mais je sais que quelque chose ne va pas avec ma configuration.

Aussi mon `my.cnf 'est comme ci-dessous:

[mysqld]
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under different user or group,
# customize your systemd unit file for mysqld according to the
# instructions in http://fedoraproject.org/wiki/Systemd
# max_allowed_packet=500M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0


innodb_buffer_pool_size         = 512M


[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
pmoubed
la source
J'ai le même problème sur ma micro-instance EC2. J'ai essayé de définir innodb_buffer_pool_size = 128M et je verrai comment cela se passe.
swxxii
Vous devrez peut-être ajouter un espace d'échange si vous utilisez une micro-instance: prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html
pmoubed
1
Sur les micro-instances EC2, il n'y a AUCUN espace de swap par défaut et il doit être configuré manuellement. Sinon, vous risquez de voir de nombreux plantages MySQL en raison d'un manque de mémoire.
pmoubed le

Réponses:

163

J'ai rencontré le même problème lorsque j'ai essayé d'exécuter un wordpress sur ma micro instance sans RDS.

L'ajout d'une page Swap a résolu le problème pour moi.

Vous pouvez suivre les étapes ci-dessous pour configurer l'espace d'échange.

Si cela ne fonctionne toujours pas pour vous, envisagez d'utiliser le service RDS.

===============================================

J'ai copié le contenu du blog pour mémoire. Le crédit revient à l'auteur du blog pmoubed :

Espace d'échange de micro-instance Amazon EC2 - Linux

J'ai une instance Amazon EC2 Linux Micro. Étant donné que les instances Micro ne disposent que de 613 Mo de mémoire, MySQL plantait de temps en temps. Après une longue recherche sur MySQL, Micro Instance et Gestion de la mémoire, j'ai découvert qu'il n'y avait pas d'espace SWAP par défaut pour l'instance Micro. Donc, si vous voulez éviter le crash, vous devrez peut-être configurer un espace d'échange pour votre micro-instance. En fait, en termes de performances, il est préférable d'activer le swap.

Les étapes ci-dessous montrent comment créer un espace d'échange pour votre instance Micro. Je suppose que vous avez un compte AWS avec une instance Micro en cours d'exécution.

  1. Courir dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. Courir mkswap /swapfile
  3. Courir swapon /swapfile
  4. Ajouter cette ligne /swapfile swap swap defaults 0 0à/etc/fstab

L'étape 4 est nécessaire si vous souhaitez activer automatiquement le fichier d'échange après chaque redémarrage.

Quelques commandes utiles liées à l'espace SWAP:

$ swapon -s   
$ free -k

$ swapoff -a
$ swapon  -a

Références:

  1. http://www.thegeekstuff.com/2010/08/how-to-add-swap-space/
  2. http://cloudstory.in/2012/02/getting-the-best-out-of-amazon-ec2-micro-instances/
  3. http://cloudstory.in/2012/02/adding-swap-space-to-amazon-ec2-linux-micro-instance-to-increase-the-performance/
  4. http://aws.amazon.com/ec2/instance-types/
Bohr
la source
Merci! Cela m'a aidé!
Annuler
8
Pour info, cela a fonctionné pour moi sur une gouttelette Digital Ocean (512 Mo). Cela ne devrait surprendre personne, mais au cas où quelqu'un ne serait pas sûr, cela fonctionnera probablement sur n'importe quel serveur avec les mêmes problèmes.
jfacemyer
Merci pour ce sauveur de vie! Exécutait également une micro-instance avec Ubuntu Server.
ECC-Dan
4
Pour les utilisateurs de Digital Ocean, j'ai suivi ce tutoriel et cela a fonctionné comme un charme: digitalocean.com/community/articles
Chris Ray
Merci beaucoup. Je me suis arraché les cheveux pendant les dernières 24 heures, j'ai joué avec toutes sortes de tailles de tampon / cache / requête. Vous êtes une bouée de sauvetage!
pranshus
23

J'ai également eu ce problème sur une micro-instance Amazon EC2. J'ai essayé de réduire l'utilisation de la mémoire d'inno_db en ajoutant ce qui suit à/etc/my.cnf

innodb_buffer_pool_size = 64M

Cela n'a pas fonctionné, j'ai essayé de le réduire à 16M et cela ne fonctionnait toujours pas. Ensuite, j'ai réalisé que l'instance n'avait pratiquement aucune mémoire libre. J'ai donc essayé de redémarrer Apache

redémarrage du système sudo httpd
redémarrage du système sudo mysqld

Et tout a bien fonctionné. Peut-être qu'une autre solution est de configurer apache pour ne pas consommer autant de mémoire.

wfbarksdale
la source
2
MySQL peut toujours se bloquer, vous devrez peut-être ajouter de l'espace d'échange à votre micro-instance.
pmoubed
Merci, cela a du sens. Je pense que je pourrais aussi essayer de limiter le nombre de threads qu'apache peut générer.
wfbarksdale
Fonctionne très bien. J'ai ce problème aussi et en redémarrant httpd, j'ai résolu le problème.
Lionel Chan
1
Super prise, même bateau ici. J'ai configuré mon apache pour utiliser moins de RAM et j'ai également créé un fichier d'échange de 512m, mais j'ai défini vm.swappiness sur 10 pour qu'il ne soit utilisé que dans un pincement.
newz2000
Le redémarrage de nginx et de php-fpm a également libéré suffisamment de mémoire pour permettre à mysql de démarrer! Merci!
msEmmaMay
4

Il semble que vous demandiez 128 Mo de mémoire pour innodb_buffer_pool_size dans le fichier my.cfg que vous affichez dans le message, mais MySQL pense que vous demandez 512 Mo de mémoire:

Initialisation du pool de mémoire tampon, taille = 512,0M

Quelques lignes plus bas, le message d'erreur vous indique que MySQL ne démarrera pas car il ne peut pas réserver suffisamment de mémoire (512 Mo) pour le pool de mémoire tampon InnoDB:

Erreur fatale: impossible d'allouer de la mémoire pour le pool de mémoire tampon

Cela soulève trois questions:

  1. Quelle est la quantité de mémoire sur votre instance? Devrait-il y avoir suffisamment de mémoire pour accueillir le 512M que InnoDB essaie de récupérer pour le pool de tampons, plus tout ce que MySQL alloue, plus vos applications, plus le système d'exploitation?
  2. Pourquoi InnoDB essaie-t-il d'en prendre plus que vous ne le pensez?
  3. Pourquoi MySQL redémarre-t-il de toute façon?

Vous pouvez répondre 1.

Quant à 2., il y a quelques endroits différents où les fichiers d'options MySQL peuvent être localisés. Les fichiers trouvés ultérieurement remplacent les options spécifiées dans les fichiers trouvés précédemment. Voir

http://dev.mysql.com/doc/refman/5.5/en/option-files.html

Le problème 3. peut être dû à une condition de mémoire insuffisante qui se produit quelque temps après le démarrage. Vous devriez voir une indication de cela plus loin dans les journaux si tel est le cas.

Enfin, mais sans aucun rapport, utilisez-vous des instances basées sur EBS? C'est généralement fortement recommandé pour les serveurs de base de données (en fait, pour toute instance sauf circonstances particulières). Pour en savoir plus, voir

https://stackoverflow.com/a/3630707/141172

Eric J.
la source
2

Pour moi, ce problème a été corrigé en ajoutant un volume de swap à mon instance EC2. Mes services consommaient simplement toute la mémoire de la boîte et plantaient. Pas quelque chose auquel j'étais habitué, étant un administrateur RedHat / CentOS pendant des années - Anaconda fait BEAUCOUP de travail que l'instance gratuite Ubuntu EC2 ne fait pas.

J'ai simplement créé un volume de 2 Go via la console Web, je l'ai attaché à mon instance, et j'ai fait "mkswap / dev / [peu importe]", édité / etc / fstab et le plantage s'est arrêté.

Ces instances ne s'installent PAS comme une installation de système d'exploitation basée sur un support à laquelle la plupart d'entre nous sommes habitués - elle est dépouillée sans paquet, sans système de fichiers approprié et des choses comme AppArmor, qui causent toutes sortes de problèmes si vous n'en êtes pas conscient et / ou ne sais pas comment le configurer.

Joël
la source
1

Le problème est que le serveur n'a pas assez de mémoire pour allouer au processus MySQL. Il existe quelques solutions à ce problème.

(1) Augmentez la RAM physique. L'ajout de 1 Go de RAM supplémentaire résoudra le problème. (2) Allouer de l'espace SWAP. L'instance Digital Ocean VPS n'est pas configurée pour utiliser l'espace d'échange par défaut. En allouant 512 Mo d'espace de swap, nous avons pu résoudre ce problème. Pour ajouter de l'espace d'échange à votre serveur, procédez comme suit:

## As a root user, perform the following:
# dd if=/dev/zero of=/swap.dat bs=1024 count=512M
# mkswap /swap.dat
# swapon /swap.dat
## Edit the /etc/fstab, and the following entry.
/swap.dat      none    swap    sw      0       0 

Réduisez la taille de la taille du pool de mémoire tampon MySQL

## Edit /etc/my.cnf, and add the following line under the [mysqld] heading.
[mysqld]
innodb_buffer_pool_size=64M

Veuillez également vérifier votre espace disque. Assurez-vous d'avoir suffisamment d'espace.

df-h

Ranjeet Ranjan
la source
1

RÉPONSE FACILE:

* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld

RÉPONSE DÉTAILLÉE:

C'est une question importante, en particulier pour les personnes qui utilisent un très petit VPS, par exemple 1 Go de RAM ou moins. Si MySQL abandonne, cela peut être un problème avec la configuration de votre serveur (Apache | nginx) ou avec la configuration MySQL. Les attaques DOS peuvent provoquer une augmentation de l'utilisation des ressources système (voir l'image). Le résultat final est que le processus MySQL est arrêté par le noyau. Pour une solution à long terme, vous devriez envisager d'optimiser vos configurations Apache ou MySQL.

Pic de ressources système provoquant un pic de RAM (juste avant 18 heures) et un pic de ressources système provoquant uniquement un pic de CPU à minuit le mardi 18

Il y a plusieurs autres discussions Stack Overflow ces sujets ainsi que le manuel MySQL et le blog Percona:

Manuel MySQL - Comment MySQL utilise la mémoire:

https://dev.mysql.com/doc/refman/8.0/en/memory-use.html

Percona - Meilleures pratiques pour configurer l'utilisation optimale de la mémoire MySQL:

https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/

Comment optimiser les performances de MySQL à l'aide de MySQLTuner:

https://www.linode.com/docs/databases/mysql/how-to-optimize-mysql-performance-using-mysqltuner/

Configuration de l'utilisation de la mémoire Apache:

/server/254436/apache-memory-usage-optimization

Manuel Apache sur le réglage des performances:

https://httpd.apache.org/docs/2.4/misc/perf-tuning.html

Réglage du serveur Apache:

https://www.linode.com/docs/web-servers/apache-tips-and-tricks/tuning-your-apache-server/

Cependant, en ce qui concerne votre question initiale, oui, vous pouvez créer un script pour une solution temporaire qui vérifie si le service MySQL est chargé et actif et redémarrera MySQL s'il n'est pas chargé et actif.

Vous n'avez pas mentionné le système d'exploitation que vous utilisez. Cela aiderait à vous donner une commande spécifique. Je vais vous donner un exemple pour CentOS linux.
Regardez la sortie suivante de la commande systemctl status mysql. Vous pouvez voir en haut que le service est chargé et actif .

[root@centos-mysql-demo ~]# systemctl status mysqld
 mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-06-18 18:28:18 UTC; 924ms ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 3350 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 3273 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 3353 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─3353 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Jun 18 18:28:11 centos-mysql-demo systemd[1]: Starting MySQL Server...
Jun 18 18:28:18 centos-mysql-demo systemd[1]: Started MySQL Server.

Si le service n'est pas chargé, une commande telle que:

systemctl status mysqld || systemctl restart mysqld 

fera le tour de redémarrer le processus. Vous pouvez cron que:

* * * * * systemctl status mysqld || systemctl restart mysqld

Cependant, dans le cas où mysql est chargé , mais que le service n'est pas actif , votre cron ne fera rien. Vous devez donc utiliser une commande plus détaillée telle que:

* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld

Dans ce cas, si le service est chargé mais inactif tel que l'état selon lequel une attaque DOS peut quitter votre service mysql, la commande redémarrera également mysql. L'utilisation de l' --quietindicateur spécifie simplement la commande pour renvoyer un code d'état, sans rien afficher à l'écran. Si vous omettez l' --quietindicateur, vous verrez une sortie d'état de l'un activeou l' autre inactive.

Vous pouvez également créer un espace de swap pour ajouter plus de ressources RAM disponibles à votre serveur, telles que:

sudo dd if=/dev/zero of=/swapfile count=2096 bs=1MiB
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon --show
swapon --summary
free -h
jonnyjandles
la source
0

Utilisez l'une des solutions suivantes:

  1. Augmentez la RAM physique. L'ajout de 1 Go de RAM supplémentaire résoudra le problème.

  2. Allouez de l'espace SWAP en utilisant les modifications de configuration ci-dessous:

config

dd if=/dev/zero of=/extraswap bs=1024 count=512M
mkswap  /extraswap 
swapon  /extraswap 
## Edit the /etc/fstab, and the following entry.
/extraswap      none    swap    sw      0       0
cloud_geek
la source