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 的内存使用量
这不起作用,我尝试将其降低到 16M,但仍然不起作用。然后我意识到该实例的可用内存基本上为零。所以我尝试重新启动apache
sudo 系统 httpd 重启 sudo 系统 mysqld 重启一切正常。也许另一种解决方案是将 apache 配置为不以某种方式占用这么多内存。
【讨论】:
MySQL 可能仍会崩溃,因此您可能需要向微实例添加交换空间。 谢谢,有道理。我想我也可以尝试限制 apache 可以产生的线程数。 效果很好。我也有这个问题,通过重新启动 httpd 解决了这个问题。 很棒的收获,同样的船。我将我的 apache 设置为使用更少的 ram,并创建了一个 512m 的交换文件,但将 vm.swappiness 设置为 10,这样它只会在紧要关头使用。 重启nginx和php-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
这种情况下,如果服务loaded但inactive比如DOS攻击可以离开你的mysql服务的状态,该命令也会重启mysql。使用--quiet
标志只是指定该命令只返回一个状态码,不向屏幕输出任何内容。如果您省略--quiet
标志,您将看到active
或inactive
的状态输出。
您还可以创建一些交换空间来为您的服务器添加更多可用的 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的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Java 中以编程方式启动和停止 Amazon EC2 实例
是否有引导脚本在启动时将 Amazon SSM 代理安装到 EC2 Windows 实例中?
使用 MySQL Workbench 安全组通过 EC2 实例连接到 Amazon RDS 实例