我有一台装有 CentOS 7.1、Apache 2.4.6 和 MariaDB 5.5 的 Azure VM。该 VM 有 2 个核心和 3.5 GB RAM。该服务器仅托管一个几乎没有流量的小型 WordPress 网站。
在过去的两天里,MariaDB 不断因 OOM 错误而崩溃。我尝试了很多不同的方法来调整性能,但到目前为止,没有任何帮助。这是文件中的当前配置my.cnf
:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
performance_schema = off
innodb_buffer_pool_size = 1024M
key_buffer_size = 50M
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
Apache 是一个预分叉版本,我添加了以下调整:
KeepAlive On
KeepAliveTimeout 3
StartServers 1
MinSpareServers 3
MaxSpareServers 6
ServerLimit 24
MaxClients 24
MaxRequestsPerChild 3000
我也尝试过默认设置,但没什么区别。以下是 MariaDB 日志中的错误示例:
160124 15:04:53 mysqld_safe Number of processes running now: 0
160124 15:04:53 mysqld_safe mysqld restarted
160124 15:05:47 [Note] /usr/libexec/mysqld (mysqld 5.5.44-MariaDB) starting as process 4014 ...
160124 15:05:47 InnoDB: The InnoDB memory heap is disabled
160124 15:05:47 InnoDB: Mutexes and rw_locks use GCC atomic builtins
160124 15:05:47 InnoDB: Compressed tables use zlib 1.2.7
160124 15:05:47 InnoDB: Using Linux native AIO
160124 15:05:48 InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137756672 bytes) failed; errno 12
160124 15:05:48 InnoDB: Completed initialization of buffer pool
160124 15:05:48 InnoDB: Fatal error: cannot allocate memory for the buffer pool
160124 15:05:48 [ERROR] Plugin 'InnoDB' init function returned error.
160124 15:05:48 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
160124 15:05:48 [ERROR] mysqld: Out of memory (Needed 128917504 bytes)
160124 15:05:48 [ERROR] mysqld: Out of memory (Needed 96681984 bytes)
160124 15:05:48 [ERROR] mysqld: Out of memory (Needed 72499200 bytes)
160124 15:05:51 [Note] Plugin 'FEEDBACK' is disabled.
160124 15:05:52 [ERROR] Unknown/unsupported storage engine: InnoDB
160124 15:05:52 [ERROR] Aborting
我该怎么办?我在 Azure 中拥有其他具有相同规格的 VM,并且运行着更多、更复杂的站点,但它们从未发生过崩溃。
编辑这是启动 MariaDB 后一分钟内的内存情况:
[root@linuxvm admin]# systemctl start mariadb
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 670 2573 2 198 2577
Swap: 511 68 443
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 1181 2052 2 207 2059
Swap: 511 64 447
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 1523 1709 2 209 1715
Swap: 511 64 447
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 1829 1397 2 214 1404
Swap: 511 64 447
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 2713 506 2 222 515
Swap: 511 63 448
[root@linuxvm admin]# free -m
total used free shared buff/cache available
Mem: 3442 3206 93 2 143 59
Swap: 511 63 448
答案1
我把它放在这里以防别人需要它,因为我实际上是在花了一整天时间排除这个问题后,通过反复试验才偶然发现了答案。我读了很多帖子和博客,没有一个建议将指令添加max_connections
到my.cnf
。
添加以下几行后,我的所有问题都解决了,MariaDB/MySQL 不再占用所有内存。您可能需要根据具体情况调整您的值。
[mysqld]
max_connections = 50
innodb_buffer_pool_size = 1024M
答案2
默认情况下,Linux VM 没有启用任何交换...
启动虚拟机时,会选择一个随机的“计算节点”,该节点的容量与您选择的虚拟机大小相符。计算节点只是一台经过高度修改并安装了 Hyper-V 的机器。您的操作系统磁盘;/dev/sda 不是该服务器的本地磁盘,因此速度不如本地存储快。(并且还会受到限制,请查看您的虚拟机大小允许的 IOPS 数量)。
但是,您将在 /dev/sdb 上获得一个适合交换的本地临时磁盘。(/dev/sdb)。问题是您的虚拟机可能并不总是托管在同一个计算节点上。(如果您的虚拟机调整大小或关闭超过 5 分钟,则被视为“已解除分配”,这意味着当您再次启动它时,它很有可能使用不同的计算节点,而该节点不会有您的本地磁盘。
为了解决这个问题,Linux VM 使用名为 WALinuxAgent 的软件,该软件具有多种功能,其中包括允许您创建交换文件。每次启动 VM 时,代理都会在临时磁盘上创建一个交换文件。
默认情况下它未启用,但您可以在 /etc/waagent.conf 中启用它
# Create and use swapfile on resource disk.
ResourceDisk.EnableSwap=n
# Size of the swapfile.
ResourceDisk.SwapSizeMB=5120
将 n 更改为 y 并重新启动,这样,如果 mysqld 确实使用了太多内存,OOM-killer 就不会启动并关闭您的 VM。