Amazon EC2, avvio interrotto da mysql perché InnoDB: mmap (x byte) non è riuscito; errno 12


95

Ho impostato un server di microistanza su EC2 in base a ciò che ho letto qui

il server mysql fallisce frequentemente e per la terza volta il server mysql non c'è più. I registri vengono visualizzati solo

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

Cos'è veramente failed; errno 12? E come potrei dare più spazio / memoria o qualsiasi altra cosa necessaria per risolvere il problema.

Risolvo questo problema ogni volta riavviando l'intero sistema ed eliminando tutti i registri e riavviando il server mysql. Ma so che qualcosa non va nella mia configurazione.

Anche il mio "my.cnf" è come di seguito:

[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

Ho lo stesso problema sulla mia microistanza EC2. Ho provato a impostare innodb_buffer_pool_size = 128M e vedremo come va.
swxxii

Potrebbe essere necessario aggiungere spazio di swap se si utilizza una microistanza: prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html
pmoubed

1
Sulle micro istanze EC2 NON c'è spazio di swap per impostazione predefinita ed è necessario impostarlo manualmente. Altrimenti potresti vedere molti arresti anomali di MySQL a causa della mancanza di memoria.
pmoubed

Risposte:


163

Ho incontrato lo stesso problema quando ho provato a eseguire un wordpress sulla mia microistanza senza RDS.

L'aggiunta di una pagina di scambio ha risolto il problema per me.

È possibile seguire i passaggi seguenti per configurare lo spazio di swap.

Se ancora non funziona, considera l'utilizzo del servizio RDS.

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

Ho copiato il contenuto del blog per la cronaca. Il merito va all'autore del blog pmoubed :

Spazio di swap di microistanze Amazon EC2 - Linux

Ho un'istanza Linux Micro Amazon EC2. Poiché le istanze Micro hanno solo 613 MB di memoria, MySQL ogni tanto si bloccava. Dopo una lunga ricerca su MySQL, Micro Instance e Memory Managment, ho scoperto che non esiste uno spazio SWAP predefinito per l'istanza Micro. Quindi, se vuoi evitare il crash, potresti dover configurare uno spazio di swap per la tua microistanza. In realtà, dal punto di vista delle prestazioni è meglio abilitare lo scambio.

I passaggi seguenti mostrano come creare uno spazio di swap per la tua istanza Micro. Presumo che tu abbia un account AWS con un'istanza micro in esecuzione.

  1. Correre dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. Correre mkswap /swapfile
  3. Correre swapon /swapfile
  4. Aggiungi questa riga /swapfile swap swap defaults 0 0a/etc/fstab

Il passaggio 4 è necessario se si desidera abilitare automaticamente il file di scambio dopo ogni riavvio.

Alcuni comandi utili relativi allo spazio SWAP:

$ swapon -s   
$ free -k

$ swapoff -a
$ swapon  -a

Riferimenti:

  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/

Grazie! Questo mi ha aiutato!
Annulla

8
Cordiali saluti, questo ha funzionato per me su una gocciolina Digital Ocean (512 MB). Non che questo dovrebbe sorprendere nessuno, ma nel caso in cui qualcuno non sia sicuro, probabilmente funzionerà su qualsiasi server con gli stessi problemi.
jfacemyer

Grazie per questo salvavita! Stava anche eseguendo una microistanza con Ubuntu Server.
ECC-Dan

4
Per gli utenti di Digital Ocean, ho seguito questo tutorial e ha funzionato a meraviglia
Chris Ray

Molte grazie. Mi sono strappato i capelli nelle ultime 24 ore, ho giocato con tutti i tipi di dimensioni di buffer / cache / query .. Sei un salvavita!
pranshus

23

Ho avuto questo problema anche su una microistanza Amazon EC2. Ho provato a diminuire l'utilizzo della memoria di inno_db aggiungendo quanto segue a/etc/my.cnf

innodb_buffer_pool_size = 64M

Non ha funzionato, ho provato a ridurlo a 16M e ancora non ha funzionato. Poi ho capito che l'istanza aveva praticamente zero memoria libera. Quindi ho provato a riavviare Apache

sudo sistema httpd riavvio
sudo sistema mysqld riavvio

E tutto ha funzionato bene. Forse un'altra soluzione è configurare Apache per non consumare così tanta memoria in qualche modo.


2
MySQL potrebbe ancora bloccarsi, quindi potrebbe essere necessario aggiungere spazio di swap alla microistanza.
pubblicato il

Grazie, ha senso. Penso di poter anche provare a limitare il numero di thread che Apache può generare.
wfbarksdale

Funziona alla grande. Anch'io ho questo problema e riavviando httpd ho risolto il problema.
Lionel Chan

1
Cattura fantastica, stessa barca qui. Ho impostato il mio apache per utilizzare meno ram e ho anche creato un file di scambio di 512 m, ma ho impostato vm.swappiness su 10 in modo che venisse utilizzato solo in caso di necessità.
newz2000

Anche il riavvio di nginx e php-fpm ha rilasciato abbastanza memoria per consentire l'avvio di mysql! Grazie!
msEmmaMays

4

Sembra che si chiede il 128M di memoria per l'innodb_buffer_pool_size nel file my.cfg si mostra nel post, ma MySQL pensa si sta chiedendo per 512M di memoria:

Inizializzazione del pool di buffer, dimensione = 512,0 MB

Poche righe dopo, il messaggio di errore ti dice che MySQL non si avvia perché non può riservare memoria sufficiente (512 M) per il pool di buffer InnoDB:

Errore irreversibile: impossibile allocare memoria per il pool di buffer

Ciò pone tre domande:

  1. Quanta memoria c'è nella tua istanza? Dovrebbe esserci memoria sufficiente per ospitare il 512M che InnoDB sta cercando di catturare per il pool di buffer, oltre a tutto il resto che MySQL alloca, più le tue applicazioni, più il sistema operativo?
  2. Perché InnoDB sta cercando di prendere più di quanto pensi dovrebbe?
  3. Perché MySQL si riavvia comunque?

Puoi rispondere 1.

Per quanto riguarda 2., ci sono diversi posti dove possono essere localizzati i file delle opzioni MySQL. I file trovati successivamente sovrascrivono le opzioni specificate nei file trovati in precedenza. Vedere

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

Il problema 3. potrebbe essere dovuto a una condizione di memoria insufficiente che si verifica qualche tempo dopo l'avvio. Dovresti vedere un'indicazione di questo più indietro nei log, se è il caso.

Infine, ma in qualche modo non correlato, stai utilizzando istanze supportate da EBS? Questo è generalmente altamente raccomandato per i server di database (in realtà, per qualsiasi istanza salvo circostanze speciali). Per ulteriori informazioni su questo vedere

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


2

Per me, esattamente questo problema è stato risolto aggiungendo un volume di swap alla mia istanza EC2. I miei servizi stavano semplicemente consumando tutta la memoria sulla scatola e si sarebbero bloccati. Non qualcosa a cui ero abituato, essendo un amministratore di RedHat / CentOS per anni - Anaconda fa MOLTO lavoro che l'istanza EC2 di Ubuntu gratuita non fa.

Ho semplicemente creato un volume da 2 Gb tramite la console web, l'ho collegato alla mia istanza e ho eseguito "mkswap / dev / [qualunque]", modificato / etc / fstab e l'arresto anomalo si è interrotto.

Queste istanze NON si installano come un'installazione del sistema operativo basata su supporti a cui la maggior parte di noi è abituata: è spogliata senza pacchetti, nessun file system appropriato e cose come AppArmor, che causano tutti i tipi di problemi se non ne sei consapevole e / o non sai come configurarlo.


1

Il problema è che il server non dispone di memoria sufficiente da allocare per il processo MySQL. Esistono alcune soluzioni a questo problema.

(1) Aumenta la RAM fisica. L'aggiunta di 1 GB di RAM aggiuntiva risolverà il problema. (2) Allocare lo spazio di SWAP. L'istanza Digital Ocean VPS non è configurata per utilizzare lo spazio di swap per impostazione predefinita. Assegnando 512 MB di spazio di swap, siamo stati in grado di risolvere questo problema. Per aggiungere spazio di swap al tuo server, segui i seguenti passaggi:

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

Riduci la dimensione del pool di buffer di MySQL

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

Inoltre, controlla lo spazio su disco. Assicurati di avere spazio sufficiente.

df-h


1

RISPOSTA FACILE:

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

RISPOSTA DETTAGLIATA:

Questa è una domanda importante soprattutto per le persone che utilizzano un VPS molto piccolo, ad esempio 1 GB di RAM o meno. Se MySQL sta abbandonando, potrebbe essere un problema con la configurazione del server (Apache | nginx) o con la configurazione di MySQL. Gli attacchi DOS possono causare un aumento del picco nell'utilizzo delle risorse di sistema (vedi immagine). Il risultato finale è che il processo MySQL viene arrestato dal kernel. Per una soluzione a lungo termine, dovresti cercare di ottimizzare le tue configurazioni Apache o MySQL.

Le risorse di sistema aumentano causando un picco della RAM (poco prima delle 18:00) e le risorse di sistema aumentano causando solo un picco della CPU Mezzanotte di martedì 18

Ci sono molte altre discussioni Stack Overflow su questi argomenti così come il manuale MySQL e il blog di Percona:

Manuale MySQL - Come MySQL utilizza la memoria:

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

Percona - Best practice per la configurazione dell'utilizzo ottimale della memoria MySQL:

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

Come ottimizzare le prestazioni di MySQL utilizzando MySQLTuner:

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

Configurazione dell'utilizzo della memoria di Apache:

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

Manuale di Apache sull'ottimizzazione delle prestazioni:

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

Ottimizzazione del server Apache:

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

Tuttavia, rispetto alla tua domanda originale, sì, puoi scrivere una soluzione temporanea che controlla se il servizio MySQL è caricato e attivo e riavvierà MySQL se non è caricato e attivo.

Non hai menzionato quale sistema operativo stai utilizzando. Ciò aiuterebbe a darti un comando specifico. Ti darò un esempio per CentOS Linux.
Guarda il seguente output del comando systemctl status mysql. Puoi vedere in alto che il servizio è caricato e attivo .

[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.

Se il servizio non è caricato, allora un comando come:

systemctl status mysqld || systemctl restart mysqld 

farà il trucco di riavviare il processo. Si potrebbe cron che:

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

Tuttavia, nel caso in cui mysql sia caricato , ma il servizio non è attivo , il tuo cron non farà nulla. Quindi, dovresti usare un comando più dettagliato come:

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

In questo caso, se il servizio è caricato ma inattivo come lo stato in cui un attacco DOS può lasciare il tuo servizio mysql, il comando riavvierà anche mysql. L'uso del --quietflag specifica il comando solo per restituire un codice di stato, non per visualizzare nulla sullo schermo. Se ometti il --quietflag, vedrai un output di stato di activeo inactive.

Puoi anche creare dello spazio di swap per aggiungere più risorse RAM disponibili al tuo server come:

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

Utilizza una delle seguenti soluzioni:

  1. Aumenta la RAM fisica. L'aggiunta di 1 GB di RAM aggiuntiva risolverà il problema.

  2. Allocare lo spazio SWAP utilizzando le modifiche di configurazione seguenti:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.