Amazon EC2,mysql 中止启动,因为 InnoDB:mmap(x 字节)失败;错误号 12

Posted

技术标签:

【中文标题】Amazon EC2,mysql 中止启动,因为 InnoDB:mmap(x 字节)失败;错误号 12【英文标题】:Amazon EC2, mysql aborting start because InnoDB: mmap (x bytes) failed; errno 12 【发布时间】:2012-05-04 07:12:01 【问题描述】:

我有一个基于this的EC2上的微型实例服务器@

mysql server 经常出现故障,mysql server 第三次不见了。日志只显示

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

【问题讨论】:

我的 EC2 微型实例也有同样的问题。试过设置 innodb_buffer_pool_size=128M 看看效果如何。 如果您使用的是微型实例,您可能需要添加交换空间:prowebdev.us/2012/05/amazon-ec2-linux-micro-swap-space.html EC2 微实例默认没有交换空间,需要手动设置。否则你可能会看到大量的 MySQL 因内存不足而崩溃。 【参考方案1】:

看起来您为帖子中显示的 my.cfg 文件中的 innodb_buffer_pool_size 请求 128M 内存,但 MySQL 认为您请求 512M记忆:

初始化缓冲池,大小=512.0M

几行之后,错误消息告诉您 MySQL 将无法启动,因为它无法为 InnoDB 缓冲池保留足够的 (512M) 内存:

致命错误:无法为缓冲池分配内存

这引出了三个问题:

    您的实例有多少内存?是否应该有足够的内存来容纳 512M InnoDB 试图为缓冲池抓取,加上 MySQL 分配的所有其他内容,加上您的应用程序和操作系统? 为什么 InnoDB 试图采取的措施超出您的预期? 为什么 MySQL 会重新启动?

你可以回答1。

至于 2.,有几个不同的地方可以找到 MySQL 选项文件。随后找到的文件会覆盖先前找到的文件中指定的选项。见

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

问题 3. 可能是由于启动后某个时间发生的内存不足情况。如果是这种情况,您应该会在日志中看到进一步的指示。

最后,但有些无关紧要,您使用的是 EBS 支持的实例吗?这通常强烈建议用于数据库服务器(实际上,对于任何情况,除非有特殊情况)。有关更多信息,请参阅

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

【讨论】:

【参考方案2】:

我在 Amazon EC2 微型实例上也遇到了这个问题。我尝试通过将以下内容添加到 /etc/my.cnf 来减少 inno_db 的内存使用量

innodb_buffer_pool_size = 64M

这不起作用,我尝试将其降低到 16M,但仍然不起作用。然后我意识到该实例的可用内存基本上为零。所以我尝试重新启动apache

sudo 系统 httpd 重启 sudo 系统 mysqld 重启

一切正常。也许另一种解决方案是将 apache 配置为不以某种方式占用这么多内存。

【讨论】:

MySQL 可能仍会崩溃,因此您可能需要向微实例添加交换空间。 谢谢,有道理。我想我也可以尝试限制 apache 可以产生的线程数。 效果很好。我也有这个问题,通过重新启动 httpd 解决了这个问题。 很棒的收获,同样的船。我将我的 apache 设置为使用更少的 ram,并创建了一个 512m 的交换文件,但将 vm.swappiness 设置为 10,这样它只会在紧要关头使用。 重启nginxphp-fpm也释放了足够的内存让mysql启动!谢谢!【参考方案3】:

对我来说,通过向我的 EC2 实例添加交换卷来解决这个问题。我的服务只是消耗了盒子上的所有内存,并且会崩溃。多年来我一直是 RedHat/CentOS 管理员,这不是我习惯的事情 - Anaconda 做了很多免费的 Ubuntu EC2 实例没有的工作。

我只是通过 Web 控制台创建了一个 2Gb 卷,将它附加到我的实例,然后执行“mkswap /dev/[whatever]”,编辑 /etc/fstab,然后崩溃停止了。

这些实例的安装不像我们大多数人习惯的基于媒体的操作系统安装 - 它被剥离,没有软件包,没有适当的文件系统,以及 AppArmor 之类的东西,如果你不这样做会导致各种问题知道它和/或不知道如何配置它。

【讨论】:

【参考方案4】:

当我尝试在没有 RDS 的微型实例上运行 wordpress 时遇到了同样的问题。

添加交换页面为我解决了这个问题。

您可以按照以下步骤设置交换空间。

如果还是不行,请考虑使用 RDS 服务。

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

我复制了博客的内容以作记录。归功于博客作者pmoubed:

Amazon EC2 微实例交换空间 - Linux

我有一个 Amazon EC2 Linux Micro 实例。由于 Micro 实例只有 613MB 的内存,MySQL 时不时地崩溃。在对 MySQL、Micro Instance 和 Memory Management 进行了长时间的搜索后,我发现 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

参考资料:

    http://www.thegeekstuff.com/2010/08/how-to-add-swap-space/ http://cloudstory.in/2012/02/getting-the-best-out-of-amazon-ec2-micro-instances/ http://cloudstory.in/2012/02/adding-swap-space-to-amazon-ec2-linux-micro-instance-to-increase-the-performance/ http://aws.amazon.com/ec2/instance-types/

【讨论】:

仅供参考,这对我来说适用于 Digital Ocean 液滴 (512 MB)。并不是说这会让任何人感到惊讶,但如果有人不确定,它可能会在任何有相同问题的服务器上工作。 感谢您的救命之恩!还在使用 Ubuntu Server 运行一个微型实例。 对于 Digital Ocean 用户,我按照本教程进行操作,效果非常好:digitalocean.com/community/articles/… 非常感谢。在过去的 24 小时里一直在拉我的头发,玩各种缓冲区/缓存/查询大小.. 你是救生员! 这里是另一个很好的信息来源:support.rackspace.com/how-to/create-a-linux-swap-file【参考方案5】:

使用以下任一解决方案:

    增加物理 RAM。添加 1GB 额外 RAM 即可解决问题。

    使用以下配置更改分配 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

【讨论】:

【参考方案6】:

问题是服务器没有足够的内存来分配给 MySQL 进程。这个问题有几个解决方案。

(1) 增加物理内存。添加 1GB 的额外 RAM 将解决该问题。 (2)分配SWAP空间。 Digital Ocean VPS 实例默认未配置为使用交换空间。通过分配 512MB 的交换空间,我们能够解决这个问题。要为您的服务器添加交换空间,请按照以下步骤操作:

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

【讨论】:

【参考方案7】:

简单的答案:

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

详细回答:

这是一个重要的问题,特别是对于使用非常小的 VPS(例如 1GB 或更少的 RAM)的人来说。如果 MySQL 退出,可能是您的服务器配置 (Apache | nginx) 或 MySQL 配置有问题。 DOS 攻击可能会导致系统资源使用量激增(见图)。最终结果是 MySQL 进程被内核关闭。对于长期解决方案,应该着眼于优化您的 Apache 或 MySQL 配置。

还有其他几个讨论 Stack Overflow 这些主题以及 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/

如何使用 MySQLTuner 优化 MySQL 性能:

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

这种情况下,如果服务loadedinactive比如DOS攻击可以离开你的mysql服务的状态,该命令也会重启mysql。使用--quiet 标志只是指定该命令只返回一个状态码,不向屏幕输出任何内容。如果您省略--quiet 标志,您将看到activeinactive 的状态输出。

您还可以创建一些交换空间来为您的服务器添加更多可用的 RAM 资源,例如:

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

【讨论】:

以上是关于Amazon EC2,mysql 中止启动,因为 InnoDB:mmap(x 字节)失败;错误号 12的主要内容,如果未能解决你的问题,请参考以下文章

Amazon EC2安装mysql多实例并配置主从复制

如何在 Java 中以编程方式启动和停止 Amazon EC2 实例

是否有引导脚本在启动时将 Amazon SSM 代理安装到 EC2 Windows 实例中?

使用 MySQL Workbench 安全组通过 EC2 实例连接到 Amazon RDS 实例

如何将映像传输到 Amazon EBS 卷以供 EC2 使用?

Amazon RDS 停止实例 [重复]