为什么 Apache 疯狂运行并杀死 MySQL?

Bob*_*ing 8 mysql ubuntu php apache-2.2

这几天Apache失控了,导致MySQL两次崩溃。这一切都始于我迁移了一个 WordPress 网站,该网站还包含一个 phpBB 论坛。

我在服务器管理方面不是很有经验,所以我很难确定导致问题的原因。当我注意到 MySQL 宕机时,我运行 TOP 并看到我的系统负载飙升至 98.00。服务器运行 10 个 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 
Run Code Online (Sandbox Code Playgroud)

Mic*_*bot 9

MySQL 可能仍然不记录任何内容,因为可能发生的情况是由于 apache 的孩子的系统内存压力,它被系统毫不客气地杀死了。/var/log/syslog 中应该有这样的记录。

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

mysqld_safe Number of processes running now: 0
Run Code Online (Sandbox Code Playgroud)

有关我怀疑与您类似的情况,请参阅InnoDB Crash Post Mortem

对“为什么”的看似简单的答案是,在 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 机器可能会更好,而且成本是相同的,因为较小的机器的价格正好是较大机器的一半......即使您已经提前付款对于额外的折扣,可以完成此更改