问题描述

最近搭了个小说网站极点追更网,在调试的时候经常发现数据库无法连接。查看mysql状态

1
2
3
4
5
6
● mysqld.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: activating (start-post) since Tue 2017-12-19 16:08:05 CST; 25s ago
Process: 14156 ExecStart=/usr/bin/mysqld_safe --basedir=/usr (code=exited, status=0/SUCCESS)
Process: 14143 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
170406 16:17:42 mysqld_safe Logging to '/var/log/mysqld.log'.

发现mysql停留在activating状态。

查看日志var/log/mysqld.log发现有如下错误:

InnoDB: mmap(137363456 bytes) failed; errno 12
2017-12-19 16:08:05 14322 [ERROR] InnoDB: Cannot allocate memory for the buffer pool
2017-12-19 16:08:05 14322 [ERROR] Plugin ‘InnoDB’ init function returned error.
2017-12-19 16:08:05 14322 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
2017-12-19 16:08:05 14322 [ERROR] Unknown/unsupported storage engine: InnoDB
2017-12-19 16:08:05 14322 [ERROR] Aborting

原因

几经查找,发现是因为内存太小,当apache进程需要更多内存时内核会清理service占用的内存防止server崩溃,mysql服务在重启时由于内存不足所以一直停留在activating状态。

the solution is NOT more space, Problem is Apache web server not mysql, actually you need to decrease innodb-buffer-pool-size
This buffer is used by the mysql process right off the start, so when Apache needs more resources the kernel will clear RAM from services this means stopping mysql instead of crashing the server.

解决方案

由于是内存小导致的,所以可以通过添加swap交换分区解决。 笔者使用的是阿里云最便宜的ecs,只有1G内存,只等添加2G的交换分区。

  1. 创建swap文件
    fallocate -l 2G /swapfile,但笔者的服务器报错fallocate failed: Operation not supported,说是文件系统不支持。用dd if=/dev/zero of=/swapfile bs=4096 count=512k成功创建。
  2. 设置文件权限
    chmod 600 /swapfile
  3. 将/swapfile指定为交换文件
    mkswap /swapfile
  4. 启用
    swapon /swapfile
  5. 永久生效
    上面的设置只能当前有效,重启不没有了,在/etc/fstab末尾添加/swapfile swap swap sw 0 0使swap永久有效。

使用swapon -s查看交换,swapoff /swapfile停用。