96

我在 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
4

7 回答 7

163

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

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

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

如果它仍然不适合您,请考虑使用 RDS 服务。

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

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

Amazon EC2 微实例交换空间 - Linux

我有一个 Amazon EC2 Linux Micro 实例。由于 Micro 实例只有 613MB 的内存,MySQL 时不时地崩溃。在对 MySQL、Micro Instance 和 Memory Managment 进行了长时间搜索后,我发现 Micro 实例没有默认的 SWAP 空间。所以如果你想避免崩溃,你可能需要为你的微实例设置一个交换空间。实际上,性能方面最好启用交换。

下面的步骤展示了如何为您的 Micro 实例创建交换空间。我假设您有一个正在运行 Micro 实例的 AWS 账户。

  1. dd if=/dev/zero of=/swapfile bs=1M count=1024
  2. mkswap /swapfile
  3. swapon /swapfile
  4. 将此行添加/swapfile swap swap defaults 0 0/etc/fstab

如果您想在每次重新启动后自动启用交换文件,则需要第 4 步。

一些与 SWAP 空间相关的有用命令:

$ swapon -s   
$ free -k

$ swapoff -a
$ swapon  -a

参考:

  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/
于 2012-12-22T03:26:22.620 回答
24

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

innodb_buffer_pool_size = 64M

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

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

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

于 2012-08-22T16:14:18.807 回答
5

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

初始化缓冲池,size = 512.0M

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

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

这就引出了三个问题:

  1. 您的实例上有多少内存?是否应该有足够的内存来容纳 512M InnoDB 试图为缓冲池抓取,加上 MySQL 分配的所有其他内容,加上你的应用程序,加上操作系统?
  2. 为什么 InnoDB 试图比你想象的要多?
  3. 为什么MySQL无论如何都会重新启动?

你可以回答1。

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

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

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

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

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

于 2012-04-24T22:30:01.270 回答
2

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

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

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

于 2012-11-30T01:09:51.903 回答
1

问题是服务器没有足够的内存来分配给 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

于 2016-09-08T08:51:24.710 回答
1

简单的答案:

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

详细回答:

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

系统资源峰值导致 RAM 峰值(就在下午 6 点之前)和系统资源峰值仅导致 CPU 峰值在星期二 18 午夜

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

在这种情况下,如果服务已加载处于非活动状态,例如 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
于 2019-06-18T19:36:24.280 回答
0

使用以下任一解决方案:

  1. 增加物理内存。添加 1GB 的额外 RAM 将解决该问题。

  2. 使用以下配置更改分配 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
于 2015-10-19T05:18:14.513 回答