Amazon EC2, mysql cancela el inicio porque InnoDB: mmap (x bytes) falló; errno 12


95

He configurado un servidor de microinstancias en EC2 según lo que leí aquí

El servidor mysql falla con frecuencia y, por tercera vez, el servidor mysql se ha ido. Los registros solo muestran

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é es realmente failed; errno 12? ¿Y cómo podría dar más espacio / memoria o lo que sea necesario para arreglar esto?

Soluciono esto cada vez reiniciando todo el sistema y borrando todos los registros y reiniciando el servidor mysql. Pero sé que algo anda mal con mi configuración.

También mi 'my.cnf' es como a continuación:

[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

Tengo el mismo problema en mi microinstancia EC2. He intentado configurar innodb_buffer_pool_size = 128M y veré cómo va.
swxxii

Es posible que deba agregar espacio de intercambio si está utilizando una micro instancia: prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html
pmoubed

1
En las microinstancias EC2, NO hay espacio de intercambio de forma predeterminada y es necesario configurarlo manualmente. De lo contrario, es posible que vea muchos bloqueos de MySQL debido a la falta de memoria.
pmoubed el

Respuestas:


163

Encontré el mismo problema cuando intenté ejecutar un wordpress en mi microinstancia sin RDS.

Agregar una página de intercambio me solucionó el problema.

Puede seguir los pasos a continuación para configurar el espacio de intercambio.

Si aún no le funciona, considere usar el servicio RDS.

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

Copié el contenido del blog para que conste. El crédito va al blog autor pmoubed :

Espacio de intercambio de microinstancias de Amazon EC2 - Linux

Tengo una micro instancia de Amazon EC2 Linux. Dado que las micro instancias tienen solo 613 MB de memoria, MySQL fallaba de vez en cuando. Después de una larga búsqueda sobre MySQL, Micro Instance y Memory Managment, descubrí que no hay un espacio SWAP predeterminado para Microinstancia. Entonces, si desea evitar el bloqueo, es posible que deba configurar un espacio de intercambio para su microinstancia. En realidad, el rendimiento es mejor para habilitar el intercambio.

Los pasos a continuación muestran cómo crear un espacio de intercambio para su instancia Micro. Supongo que tiene una cuenta de AWS con una instancia micro en ejecución.

  1. correr dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. correr mkswap /swapfile
  3. correr swapon /swapfile
  4. Agregar esta línea /swapfile swap swap defaults 0 0a/etc/fstab

El paso 4 es necesario si desea habilitar automáticamente el archivo de intercambio después de cada reinicio.

Algunos comandos útiles relacionados con el espacio SWAP:

$ swapon -s   
$ free -k

$ swapoff -a
$ swapon  -a

Referencias:

  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/

¡Gracias! ¡Esto me ayudó!
Deshacer

8
Para su información, esto funcionó para mí en una gota de Digital Ocean (512 MB). No es que esto deba sorprender a nadie, pero en caso de que alguien no esté seguro, probablemente funcionará en cualquier servidor con los mismos problemas.
jfacemyer

¡Gracias por este salvavidas! También estaba ejecutando una micro instancia con Ubuntu Server.
ECC-Dan

4
Para los usuarios de Digital Ocean, seguí este tutorial y funcionó a las mil maravillas
Chris Ray

Muchas gracias. He estado tirando de mi cabello durante las últimas 24 horas, jugado con todo tipo de tamaños de búfer / caché / consultas ... ¡Eres un salvavidas!
pranshus

23

También tuve este problema en una micro instancia de Amazon EC2. Intenté disminuir el uso de memoria de inno_db agregando lo siguiente a/etc/my.cnf

innodb_buffer_pool_size = 64M

Eso no funcionó, intenté bajarlo a 16M y todavía no funcionó. Luego me di cuenta de que la instancia tenía básicamente cero memoria libre. Así que intenté reiniciar Apache

reinicio de httpd del sistema sudo
reinicio de mysqld del sistema sudo

Y todo funcionó bien. Quizás otra solución sea configurar Apache para que no consuma tanta memoria de alguna manera.


2
MySQL aún puede fallar, por lo que es posible que deba agregar espacio de intercambio a su micro instancia.
pmoubed

Gracias, eso tiene sentido. Creo que también puedo intentar limitar la cantidad de subprocesos que apache puede generar.
wfbarksdale

Funciona genial. También tengo este problema y al reiniciar httpd resolví el problema.
Lionel Chan

1
Captura impresionante, el mismo barco aquí. Configuré mi apache para usar menos RAM y también creé un archivo de intercambio de 512 m, pero configuré vm.swappiness en 10 para que solo se usara en caso de apuro.
newz2000

¡Reiniciar nginx y php-fpm también liberó suficiente memoria para permitir que mysql se inicie! ¡Gracias!
msEmmaMays

4

Parece que está solicitando 128M de memoria para el innodb_buffer_pool_size en el archivo my.cfg mostrar en el puesto, pero MySQL piensa que está pidiendo 512M de la memoria:

Inicializando grupo de búfer, tamaño = 512.0M

Unas pocas líneas hacia abajo, el mensaje de error le dice que MySQL no se iniciará porque no puede reservar suficiente memoria (512M) para el grupo de búfer de InnoDB:

Error fatal: no se puede asignar memoria para el grupo de búferes

Eso plantea tres preguntas:

  1. ¿Cuánta memoria hay en tu instancia? ¿Debería haber suficiente memoria para acomodar el 512M que InnoDB está tratando de obtener para el grupo de búfer, más todo lo demás que MySQL asigna, más su (s) aplicación (es), más el sistema operativo?
  2. ¿Por qué InnoDB está tratando de tomar más de lo que cree que debería?
  3. ¿Por qué MySQL se reinicia de todos modos?

Puede responder 1.

En cuanto a 2., hay algunos lugares diferentes donde se pueden ubicar los archivos de opciones de MySQL. Los archivos encontrados posteriormente anulan las opciones especificadas en archivos encontrados anteriormente. Ver

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

El problema 3. podría deberse a una condición de falta de memoria que se produce en algún momento después del inicio. Debería ver una indicación de eso más atrás en los registros si ese es el caso.

Por último, pero sin relación alguna, ¿está utilizando instancias respaldadas por EBS? Por lo general, es muy recomendable para servidores de bases de datos (en realidad, para cualquier caso salvo circunstancias especiales). Para más sobre eso, vea

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


2

Para mí, este problema se solucionó exactamente agregando un volumen de intercambio a mi instancia EC2. Mis servicios simplemente consumían toda la memoria de la caja y fallaban. No es algo a lo que estuviera acostumbrado, siendo administrador de RedHat / CentOS durante años: Anaconda hace MUCHO trabajo que la instancia gratuita de Ubuntu EC2 no hace.

Simplemente creé un volumen de 2 Gb a través de la consola web, lo adjunté a mi instancia e hice "mkswap / dev / [lo que sea]", edité / etc / fstab, y la falla se detuvo.

Estas instancias NO se instalan como una instalación de sistema operativo basado en medios a la que la mayoría de nosotros estamos acostumbrados: se simplifica sin paquetes, sin un sistema de archivos adecuado y cosas como AppArmor, que causan todo tipo de problemas si no lo sabe. y / o no sé cómo configurarlo.


1

El problema es que el servidor no tiene suficiente memoria para asignar al proceso MySQL. Hay algunas soluciones a este problema.

(1) Aumente la RAM física. Agregar 1 GB de RAM adicional resolverá el problema. (2) Asignar espacio SWAP. La instancia de Digital Ocean VPS no está configurada para usar el espacio de intercambio de forma predeterminada. Al asignar 512 MB de espacio de intercambio, pudimos resolver este problema. Para agregar espacio de intercambio a su servidor, siga los siguientes pasos:

## 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 

Reducir el tamaño del grupo de búfer de MySQL

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

También verifique su espacio en disco. Asegúrese de tener suficiente espacio.

df-h


1

RESPUESTA FÁCIL:

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

RESPUESTA DETALLADA:

Esta es una pregunta importante especialmente para las personas que usan un VPS muy pequeño, digamos 1GB de RAM o menos. Si MySQL está cayendo, puede ser un problema con la configuración de su servidor (Apache | nginx) o la configuración de MySQL. Los ataques de DOS pueden causar un aumento en el uso de recursos del sistema (ver imagen). El resultado final es que el Kernel cierra el proceso de MySQL. Para una solución a largo plazo, debería buscar optimizar sus configuraciones de Apache o MySQL.

Los recursos del sistema aumentan provocando un pico de RAM (justo antes de las 6 p.m.) y los recursos del sistema aumentan provocando solo un pico de CPU a medianoche del martes 18

Hay varias otras discusiones sobre Stack Overflow sobre esos temas, así como el manual de MySQL y el blog de Percona:

Manual de MySQL - Cómo usa MySQL la memoria:

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

Percona - Mejores prácticas para configurar el uso óptimo de la memoria MySQL:

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

Cómo optimizar el rendimiento de MySQL con MySQLTuner:

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

Configuración de uso de memoria Apache:

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

Manual de Apache sobre ajuste del rendimiento:

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

Ajuste del servidor Apache:

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

Sin embargo, con respecto a su pregunta original, sí, puede escribir una solución temporal que verifique si el servicio MySQL está cargado y activo y reiniciará MySQL si no está cargado y activo.

No mencionaste qué sistema operativo estás usando. Eso ayudaría a darle un comando específico. Les daré un ejemplo para CentOS linux.
Mire la siguiente salida del comando systemctl status mysql. Puede ver en la parte superior que el servicio está cargado y activo .

[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 el servicio no está cargado, entonces un comando como:

systemctl status mysqld || systemctl restart mysqld 

hará el truco de reiniciar el proceso. Usted podría cron que:

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

Sin embargo, en el caso de que mysql esté cargado , pero el servicio no esté activo , su cron no hará nada. Entonces, debe usar un comando más detallado como:

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

En este caso, si el servicio está cargado pero inactivo , como el estado en el que un ataque de DOS puede salir de su servicio mysql, el comando también reiniciará mysql. El uso de la --quietbandera solo especifica el comando solo para devolver un código de estado, no mostrar nada en la pantalla. Si omite la --quietbandera, verá una salida de estado de activeo inactive.

También puede crear algo de espacio de intercambio para agregar más recursos RAM disponibles a su servidor, como:

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

0

Utilice cualquiera de las siguientes soluciones:

  1. Aumente la RAM física. Agregar 1 GB de RAM adicional resolverá el problema.

  2. Asigne espacio SWAP utilizando los cambios de configuración a continuación:

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.