Amazon EC2, MySQL прерывание запуска из-за сбоя InnoDB: mmap (x bytes); errno 12
Я установил сервер микроэкземпляров на EC2 на основе того, что я прочитал здесь
MySQL сервер часто выходит из строя и в третий раз сервер MySQL ушел. Логи только показывает
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
Что на самом деле failed; errno 12
? И как я мог бы дать больше места / памяти или что-то еще, чтобы это исправить.
Я исправляю это каждый раз, перезагружая всю систему, удаляя все журналы и перезагружая сервер mysql. Но я знаю, что что-то не так с моей конфигурацией.
Также мой `my.cnf'похож на ниже:
[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
6 ответов
Я столкнулся с той же проблемой, когда пытался запустить WordPress на своем микроэкземпляре без RDS.
Добавление страницы подкачки решило проблему для меня.
Вы можете следовать этому, чтобы настроить страницу подкачки:
http://www.prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html
Если это все еще не работает для вас, рассмотрите возможность использования службы RDS.
===============================================
Ссылка на блог иногда не срабатывает. Я скопировал содержание ниже для записи. Кредит идет к автору блога Педрама Мубеда:
Amazon EC2 Micro Swap Space - Linux
У меня есть экземпляр Amazon EC2 Linux Micro. Поскольку экземпляры Micro имеют только 613 МБ памяти, MySQL время от времени зависал. После долгих поисков MySQL, Micro Instance и Memory Managment я обнаружил, что для экземпляра Micro по умолчанию нет места для SWAP. Поэтому, если вы хотите избежать сбоя, вам может понадобиться установить пространство подкачки для вашего микро экземпляра. На самом деле производительность лучше включить своп.
Шаги ниже показывают, как сделать пространство подкачки для вашего экземпляра Micro. Я предполагаю, что у вас есть аккаунт AWS с запущенным экземпляром Micro.
- Бежать
dd if=/dev/zero of=/swapfile bs=1M count=1024
- Бежать
mkswap /swapfile
- Бежать
swapon /swapfile
- Добавить эту строку
/swapfile swap swap defaults 0 0
в/etc/fstab
Шаг 4 необходим, если вы хотите автоматически включать файл подкачки после каждой перезагрузки.
Некоторые полезные команды, связанные с пространством SWAP:
$ swapon -s
$ free -k
$ swapoff -a
$ swapon -a
Рекомендации:
У меня тоже была эта проблема на микроэкземпляре Amazon EC2. Я попытался уменьшить использование памяти inno_db, добавив следующее в /etc/my.cnf
innodb_buffer_pool_size = 64 млн.
Это не сработало, я попытался сбросить его до 16M, и все равно не сработало. Затем я понял, что у экземпляра практически нет свободной памяти. Поэтому я попытался перезапустить Apache
перезагрузка системы sudo httpd перезапуск системы sudo mysqld
И все работало нормально. Возможно, другое решение - настроить Apache так, чтобы он не потреблял так много памяти.
Похоже, что вы запрашиваете 128 МБ памяти для innodb_buffer_pool_size в файле my.cfg, который вы показываете в посте, но MySQL считает, что вы запрашиваете 512 МБ памяти:
Инициализирующий пул буферов, размер = 512.0M
Через несколько строк сообщение об ошибке сообщает, что MySQL не запустится, поскольку он не может зарезервировать достаточно (512 МБ) памяти для буферного пула InnoDB:
Неустранимая ошибка: невозможно выделить память для пула буферов
Это вызывает три вопроса:
- Сколько памяти у тебя на экземпляре? Должно ли быть достаточно памяти для размещения 512M, которые InnoDB пытается захватить для пула буферов, плюс все остальное, что выделяет MySQL, а также ваши приложения и операционная система?
- Почему InnoDB пытается взять больше, чем вы думаете?
- Почему MySQL перезапускается так или иначе?
Вы можете ответить 1.
Что касается 2., есть несколько разных мест, где могут быть расположены файлы опций MySQL. Впоследствии найденные файлы переопределяют параметры, указанные в ранее найденных файлах. Увидеть
http://dev.mysql.com/doc/refman/5.5/en/option-files.html
Проблема 3. может быть связана с нехваткой памяти, которая возникает через некоторое время после запуска. Вы должны увидеть указание на это еще раз в журналах, если это так.
Наконец, но несколько не связано, используете ли вы поддерживаемые EBS экземпляры? Как правило, это настоятельно рекомендуется для серверов баз данных (фактически, для любых случаев, исключая особые обстоятельства). Подробнее об этом смотрите
Для меня эта проблема была исправлена путем добавления тома подкачки в мой экземпляр EC2. Мои сервисы просто потребляли всю память на коробке и зависали. Не то, к чему я привык, будучи администратором RedHat/CentOS в течение многих лет - Anaconda выполняет МНОГО работы, чего не делает бесплатный экземпляр Ubuntu EC2.
Я просто создал том объемом 2 ГБ через веб-консоль, подключил его к своему экземпляру и выполнил "mkswap /dev/[what]]", отредактировал /etc/fstab, и сбой прекратился.
Эти экземпляры НЕ устанавливаются как установки на основе мультимедиа ОС, к которым привыкли большинство из нас - они разобраны без пакетов, без надлежащей файловой системы и таких вещей, как AppArmor, которые вызывают всевозможные проблемы, если вы об этом не знаете и / или не знаю, как его настроить.
Проблема в том, что на сервере недостаточно памяти для процесса MySQL. Есть несколько решений этой проблемы.
(1) Увеличить физическую оперативную память. Добавление 1 ГБ дополнительной оперативной памяти решит проблему. (2) Выделите пространство SWAP. Экземпляр Digital Ocean VPS не настроен на использование пространства подкачки по умолчанию. Выделив 512 МБ пространства подкачки, мы смогли решить эту проблему. Чтобы добавить пространство подкачки на ваш сервер, выполните следующие действия:
## 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
Уменьшить размер пула буферов MySQL
## Edit /etc/my.cnf, and add the following line under the [mysqld] heading.
[mysqld]
innodb_buffer_pool_size=64M
Также, пожалуйста, проверьте ваше дисковое пространство. Убедитесь, что у вас достаточно места.
df-h
ЛЕГКИЙ ОТВЕТ:
* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld
ПОДРОБНЫЙ ОТВЕТ:
Это важный вопрос, особенно для людей, которые используют очень маленький VPS, скажем, 1 ГБ ОЗУ или меньше. Если MySQL отключается, это может быть проблема с конфигурацией вашего сервера (Apache | nginx) или конфигурацией MySQL. Атаки DOS могут вызвать повышенный всплеск использования системных ресурсов (см. Изображение). Конечным результатом является то, что процесс MySQL завершается ядром. Для долгосрочного решения следует обратить внимание на оптимизацию конфигураций Apache или MySQL.
Есть еще несколько обсуждений этих тем, а также руководство по MySQL и блог Percona:
Руководство по MySQL - Как MySQL использует память:
https://dev.mysql.com/doc/refman/8.0/en/memory-use.html
Percona - Рекомендации по настройке оптимального использования памяти MySQL:
https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/
Как оптимизировать производительность MySQL с помощью MySQLTuner:
https://www.linode.com/docs/databases/mysql/how-to-optimize-mysql-performance-using-mysqltuner/
Конфигурация использования памяти Apache:
https://serverfault.com/questions/254436/apache-memory-usage-optimization
Руководство Apache по настройке производительности:
https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
Настройка сервера Apache:
https://www.linode.com/docs/web-servers/apache-tips-and-tricks/tuning-your-apache-server/
Однако, что касается вашего исходного вопроса, да, вы можете создать сценарий временного решения, которое проверяет, загружена и активна ли служба MySQL, и перезапускает MySQL, если она не загружена и не активна.
Вы не указали, какую операционную систему используете. Это поможет дать вам конкретную команду. Я приведу вам пример для CentOS linux.
Посмотрите на следующий вывод командыsystemctl status mysql
. Вы можете увидеть вверху, что служба загружена и активна.
[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.
Если служба не загружена, то такая команда как:
systemctl status mysqld || systemctl restart mysqld
сделает трюк повторного запуска процесса. Вы можете cron это:
* * * * * systemctl status mysqld || systemctl restart mysqld
Однако в случае, если mysql загружен, но служба не активна, ваш cron ничего не сделает. Итак, вам следует использовать более подробную команду, такую как:
* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld
В этом случае, если служба загружена, но неактивна, например в состоянии, когда атака DOS может покинуть вашу службу mysql, команда также перезапустит mysql. С использованием--quiet
flag просто указывает команду только для возврата кода состояния, но не выводит ничего на экран. Если вы опустите--quiet
флаг вы увидите вывод состояния либо active
или inactive
.
Вы также можете создать пространство подкачки, чтобы добавить на сервер больше доступных ресурсов ОЗУ, например:
sudo dd if=/dev/zero of=/swapfile count=2096 bs=1MiB
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon --show
swapon --summary
free -h
Используйте любое из следующих решений:
Увеличьте физическую память. Добавление 1 ГБ дополнительной оперативной памяти решит проблему.
Выделите пространство SWAP, используя изменения конфигурации ниже:
конфиг
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