Apache 为何会失控并杀死 MySQL?

Apache 为何会失控并杀死 MySQL?

Apache 在过去几天里失控了,导致 MySQL 崩溃了两次。这一切都始于我将一个包含 phpBB 论坛的 WordPress 网站迁移到该网站上。

我对服务器管理不是很有经验,因此很难确定问题的原因。当我注意到 MySQL 已关闭时,我运行了 TOP,发现系统负载飙升至 98.00。服务器运行 10 个 V-HOSTS,所有 V-HOSTS 都接收大量流量,因此我显然看到许多 apache-2 进程正在运行。

服务器高负载持续了 10 分钟,然后恢复正常状态。此时我没有看到网络流量激增。

不幸的是,MySQL 错误日志记录已被禁用(现在已重新启用),因此没有任何线索。但我很确定这是因为 Apache 消耗了所有资源,所以 MySQL 进程 ID 被终止了。

我的问题是:

下次再发生这种情况时,我该如何确定是什么导致了系统负载激增?可能是 php 脚本出了问题?可能是 DDOS 攻击?

当 MySQL 崩溃时,有没有办法自动重新启动它?

我现在已经安装了htop。这难道比更有用吗top

这是我的服务器统计信息:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 

答案1

MySQL 可能仍不会记录任何内容,因为可能发生的情况是,由于 apache 子进程的系统内存压力,系统会毫不留情地将其杀死。/var/log/syslog 中应该有此记录。

MySQL 应该在崩溃或强制终止时尝试重新启动,但除非有足够的内存,否则它无法做到这一点……而且 mysqld_safe 不会将第二次失败视为“崩溃”,而是将其视为“拒绝启动”,因此它不会继续尝试。管理员经常将失败的重新启动尝试误解为“崩溃”,因为原始失败的性质隐藏在 MySQL 错误日志中容易被忽视的消息后面:

mysqld_safe Number of processes running now: 0

InnoDB 崩溃后分析我怀疑您的情况类似。

“为什么”的答案看似简单,是因为在 Apache 和 MySQL、您的负载以及当前配置之间,您的机器上没有足够的内存,并且存在与流量负载相关的某个临界点,从而导致这种情况。

Apache 通过子进程处理每个并发浏览器请求,因此并发连接数增加时,子进程数也会增加。您首先需要在 apache 配置中限制此值,以便了解导致并发连接数增加的实际原因... 这仅仅是一次严重但合法的流量高峰吗?某种拒绝服务?数据库查询由于运行时间过长而延迟请求?需要优化什么?

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

限制并发 Apache 进程应该有助于防止这种情况发生,但要明确的是,认为这是完整的解决方案是天真的,所以我不想暗示这一点。一旦将进程限制在合理或至少更安全的水平,您就可以继续确定到底发生了什么。(Apache 上还有其他限制控制,但这不是我的专业领域。)

“最佳实践”当然是在不同的硬件上运行数据库,这样应用程序就无法杀死它。虽然表面上通过共享一台机器来“最大化利用率”似乎更有效,但这是一种虚假的经济。在典型的工作负载中,MySQL 使用的大部分内存是在启动时分配的,并且在 MySQL 服务器运行时一直保留。对 CPU 的需求可能会在 MySQL 和 Apache 的高峰时间共享,因为它们最终服务于相同的负载。实际上,使用两台 m1.large 机器可能比使用一台 m1.xlarge 机器更好,而且成本会相同,因为较小的机器正好是较大的机器价格的一半……即使您已经提前支付了额外的折扣,这一改变是可以实现的

答案2

您需要检查以下几点:

-检查 /var/log/messages :如果没有更多内存可用,oomkiller 可以终止 mysql 进程。使用 free -lm 检查内存(无缓存)

-如果您使用带有 prefork mpm 的 apache:请检查进程数。如果 apache 堆栈中存在大量与 mysql 链接的进程(在负载较重时),则延迟和所用内存可能会快速增加。

-使用以下命令检查 mysql 启动的线程数显示全局状态:threads_cached、threads_created 和threads_running 的检查很重要(threads_created 应该接近 0)。

-检查Mysql使用的内存。

答案3

您还可以研究实施处理器集并为 mysql 保留资源。这最接近于在不同硬件上运行这些服务,但仍可让您享受维护单个服务器的好处。

相关内容