Amazon EC2, mysql przerywa uruchamianie, ponieważ InnoDB: mmap (x bajtów) nie powiodło się; errno 12

95

Skonfigurowałem mikro serwer instancji na EC2 na podstawie tego, co przeczytałem tutaj

Serwer mysql często zawodzi i po raz trzeci serwer mysql zniknął. Dzienniki pokazują tylko

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

Co jest naprawdę failed; errno 12 ? I jak mogę dać więcej miejsca / pamięci lub cokolwiek potrzebnego, aby to naprawić.

Naprawiam to za każdym razem, restartując cały system i usuwając wszystkie logi i restartując serwer mysql. Ale wiem, że coś jest nie tak z moją konfiguracją.

Również mój plik `my.cnf 'wygląda jak poniżej:

[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
źródło
Mam ten sam problem na mojej instancji micro EC2. Próbowałem ustawić innodb_buffer_pool_size = 128M i zobaczę, jak to pójdzie.
swxxii,
Może być konieczne dodanie miejsca wymiany, jeśli używasz instancji mikro: prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html
pmoubed
1
W instancjach EC2 micro domyślnie NIE ma miejsca na wymianę i należy ją skonfigurować ręcznie. W przeciwnym razie możesz zobaczyć wiele awarii MySQL z powodu braku pamięci.
pmoubed

Odpowiedzi:

163

Napotkałem ten sam problem, gdy próbowałem uruchomić wordpress na mojej instancji micro bez RDS.

Dodanie strony wymiany rozwiązało problem za mnie.

Możesz wykonać poniższe czynności, aby skonfigurować przestrzeń wymiany.

Jeśli nadal nie działa, rozważ skorzystanie z usługi RDS.

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

Treść bloga skopiowałem do akt. Podziękowania dla autora bloga pmoubed :

Przestrzeń wymiany instancji Micro Amazon EC2 - Linux

Mam instancję Amazon EC2 Linux Micro. Ponieważ instancje Micro mają tylko 613 MB pamięci, MySQL ulega awarii od czasu do czasu. Po długich poszukiwaniach na temat MySQL, Micro Instance i Memory Managment stwierdziłem, że nie ma domyślnej przestrzeni SWAP dla instancji Micro. Jeśli więc chcesz uniknąć awarii, może być konieczne skonfigurowanie przestrzeni wymiany dla swojej mikroinstancji. Właściwie pod względem wydajności lepiej jest włączyć zamianę.

Poniższe kroki pokazują, jak zrobić miejsce wymiany dla instancji Micro. Zakładam, że masz konto AWS z uruchomioną instancją Micro.

  1. Biegać dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. Biegać mkswap /swapfile
  3. Biegać swapon /swapfile
  4. Dodaj tę linię /swapfile swap swap defaults 0 0do/etc/fstab

Krok 4 jest potrzebny, jeśli chcesz automatycznie włączać plik wymiany po każdym ponownym uruchomieniu.

Kilka przydatnych poleceń związanych z przestrzenią SWAP:

$ swapon -s   
$ free -k

$ swapoff -a
$ swapon  -a

Bibliografia:

  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
źródło
Dzięki! To mi pomogło!
Cofnij
8
FYI, to zadziałało dla mnie na kropli Digital Ocean (512 MB). Nie żeby to nikogo dziwiło, ale jeśli ktoś nie jest pewien, prawdopodobnie zadziała na każdym serwerze z tymi samymi problemami.
jfacemyer
Dziękuję za ten ratunek! Prowadził również mikro instancję z Ubuntu Server.
ECC-Dan,
4
Dla użytkowników Digital Ocean postępowałem zgodnie z tym samouczkiem i zadziałało to jak marzenie: digitalocean.com/community/articles/ ...
Chris Ray
Wielkie dzięki. Wyrywam sobie włosy przez ostatnie 24 godziny, bawiłam się różnymi rozmiarami buforów / pamięci podręcznych / zapytań .. Ratujesz życie!
pranshus
24

Miałem ten problem również na instancji mikro Amazon EC2. Próbowałem zmniejszyć użycie pamięci w inno_db, dodając następujące elementy do/etc/my.cnf

innodb_buffer_pool_size = 64 mln

To nie zadziałało, próbowałem obniżyć to do 16M i nadal nie działało. Wtedy zdałem sobie sprawę, że instancja ma w zasadzie zero wolnej pamięci. Więc spróbowałem zrestartować Apache

sudo system httpd restart
sudo system mysqld restart

I wszystko działało dobrze. Być może innym rozwiązaniem jest skonfigurowanie Apache, aby w jakiś sposób nie pochłaniał tak dużej ilości pamięci.

wfbarksdale
źródło
2
MySQL może nadal ulegać awarii, więc może być konieczne dodanie przestrzeni wymiany do instancji mikro.
pmoubed
Dzięki, to ma sens. Myślę, że mogę też spróbować ograniczyć liczbę wątków, które apache może tworzyć.
wfbarksdale
Działa świetnie. Ja też mam ten problem i ponowne uruchomienie httpd rozwiązało problem.
Lionel Chan
1
Niesamowity połów, ta sama łódź. Ustawiłem mój apache tak, aby używał mniej pamięci RAM, a także utworzyłem plik wymiany o wielkości 512 m, ale ustawiłem vm.swappiness na 10, aby był używany tylko w razie potrzeby.
newz2000
Ponowne uruchomienie nginx i php-fpm również zwolniło wystarczającą ilość pamięci, aby umożliwić uruchomienie mysql! Dzięki!
msEmmaMays
4

Wygląda na to, że żądasz 128 MB pamięci dla innodb_buffer_pool_size w pliku my.cfg, który pokazałeś w poście, ale MySQL uważa, że ​​prosisz o 512 MB pamięci:

Inicjalizacja puli buforów, rozmiar = 512,0M

Kilka wierszy dalej komunikat o błędzie informuje, że MySQL nie uruchomi się, ponieważ nie może zarezerwować wystarczającej ilości (512 MB) pamięci dla puli buforów InnoDB:

Błąd krytyczny: nie można przydzielić pamięci dla puli buforów

To nasuwa trzy pytania:

  1. Ile pamięci jest w Twojej instancji? Czy powinno być wystarczająco dużo pamięci, aby pomieścić 512 MB InnoDB, który próbuje pobrać pulę buforów, a także wszystko inne przydzielone przez MySQL, a także aplikacje i system operacyjny?
  2. Dlaczego InnoDB próbuje przyjąć więcej, niż myślisz, że powinien?
  3. Dlaczego mimo wszystko MySQL ponownie się uruchamia?

Możesz odpowiedzieć 1.

Jeśli chodzi o 2., istnieje kilka różnych miejsc, w których można znaleźć pliki opcji MySQL. Następnie znalezione pliki zastępują opcje określone we wcześniej znalezionych plikach. Widzieć

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

Problem 3. może być spowodowany brakiem pamięci, który występuje po pewnym czasie po uruchomieniu. Jeśli tak jest, powinieneś zobaczyć to w dalszej części dzienników.

Wreszcie, ale nieco niepowiązane, czy używasz instancji obsługiwanych przez EBS? Generalnie jest to wysoce zalecane dla serwerów baz danych (właściwie w każdym przypadku z wyjątkiem szczególnych okoliczności). Więcej na ten temat znajdziesz w

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

Eric J.
źródło
2

Dla mnie ten dokładnie problem został rozwiązany poprzez dodanie woluminu wymiany do mojej instancji EC2. Moje usługi po prostu zużywały całą pamięć w pudełku i ulegały awarii. Nie jest to coś, do czego byłem przyzwyczajony, będąc administratorem RedHat / CentOS przez lata - Anaconda wykonuje DUŻO pracy, której nie wykonuje bezpłatna instancja Ubuntu EC2.

Po prostu utworzyłem wolumin 2Gb za pomocą konsoli internetowej, podłączyłem go do mojej instancji i wykonałem polecenie „mkswap / dev / [cokolwiek]”, wyedytowałem / etc / fstab i awaria ustała.

Te instancje NIE instalują się jak instalacja systemu operacyjnego oparta na mediach, do której większość z nas jest przyzwyczajona - jest pozbawiona pakietów, bez odpowiedniego systemu plików i rzeczy takich jak AppArmor, które powodują wszelkiego rodzaju problemy, jeśli nie jesteś tego świadomy i / lub nie wiesz, jak to skonfigurować.

Joel
źródło
1

Problem polega na tym, że serwer nie ma wystarczającej ilości pamięci, aby przydzielić proces MySQL. Istnieje kilka rozwiązań tego problemu.

(1) Zwiększ fizyczną pamięć RAM. Dodanie 1 GB dodatkowej pamięci RAM rozwiąże problem. (2) Przydziel przestrzeń SWAP. Instancja Digital Ocean VPS nie jest domyślnie skonfigurowana do korzystania z przestrzeni wymiany. Przydzielając 512 MB przestrzeni wymiany, byliśmy w stanie rozwiązać ten problem. Aby dodać przestrzeń wymiany do swojego serwera, wykonaj następujące czynności:

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

Zmniejsz rozmiar puli buforów MySQL

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

Sprawdź również swoje miejsce na dysku. Upewnij się, że masz wystarczająco dużo miejsca.

df-h

Ranjeet Ranjan
źródło
1

ŁATWA ODPOWIEDŹ:

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

SZCZEGÓŁOWA ODPOWIEDŹ:

To ważne pytanie, szczególnie dla osób, które używają bardzo małego VPS, powiedzmy 1 GB pamięci RAM lub mniej. Jeśli MySQL się wycofuje, może to być problem z konfiguracją serwera (Apache | nginx) lub konfiguracją MySQL. Ataki DOS mogą powodować wzrost wykorzystania zasobów systemowych (patrz ilustracja). W rezultacie proces MySQL zostaje zamknięty przez jądro. Aby uzyskać długoterminowe rozwiązanie, należy spojrzeć na optymalizację konfiguracji Apache lub MySQL.

Skok zasobów systemowych powodujący skok pamięci RAM (tuż przed 18:00) i skok zasobów systemowych powodujący tylko wzrost mocy procesora O północy 18 wtorek

Istnieje kilka innych dyskusji na te tematy, a także podręcznik MySQL i blog Percona:

Podręcznik MySQL - Jak MySQL wykorzystuje pamięć:

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

Percona - najlepsze praktyki dotyczące konfigurowania optymalnego wykorzystania pamięci MySQL:

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

Jak zoptymalizować wydajność MySQL za pomocą MySQLTuner:

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

Konfiguracja wykorzystania pamięci Apache:

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

Podręcznik Apache dotyczący dostrajania wydajności:

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

Tuning serwera Apache:

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

Jednak w odniesieniu do twojego pierwotnego pytania, tak, możesz napisać skrypt tymczasowego rozwiązania, które sprawdza, czy usługa MySQL jest załadowana i aktywna i uruchomi ponownie MySQL, jeśli nie jest załadowana i aktywna.

Nie wspomniałeś, jakiego systemu operacyjnego używasz. Pomogłoby to w wydaniu konkretnego polecenia. Dam ci przykład dla CentOS linux.
Spójrz na następujące dane wyjściowe poleceniasystemctl status mysql . U góry widać, że usługa jest załadowana i aktywna .

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

Jeśli usługa nie jest załadowana, to polecenie takie jak:

systemctl status mysqld || systemctl restart mysqld 

załatwi sprawę ponownego uruchomienia procesu. ty mogłoby cron, że:

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

Jednak w przypadku załadowania mysql , ale usługa nie jest aktywna , twój cron nic nie zrobi. Dlatego powinieneś użyć bardziej szczegółowego polecenia, takiego jak:

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

W tym przypadku, jeśli usługa jest załadowana, ale nieaktywna przykład stan, w którym atak DOS może opuścić usługę mysql, polecenie spowoduje również ponowne uruchomienie mysql. Użycie --quietflagi tylko określa polecenie tylko w celu zwrócenia kodu stanu, a nie wyprowadzania niczego na ekran. Jeśli ommit na --quietflagę widać wyjście statusu albo activealbo inactive.

Możesz również utworzyć przestrzeń wymiany, aby dodać więcej dostępnych zasobów pamięci RAM do serwera, na przykład:

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
źródło
0

Użyj dowolnego z następujących rozwiązań:

  1. Zwiększ fizyczną pamięć RAM. Dodanie 1 GB dodatkowej pamięci RAM rozwiąże problem.

  2. Przydziel przestrzeń SWAP za pomocą poniższych zmian konfiguracyjnych:

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
źródło