为啥这个 UPDATE 查询会杀死我的 CPU?

Posted

技术标签:

【中文标题】为啥这个 UPDATE 查询会杀死我的 CPU?【英文标题】:Why would this UPDATE query be killing my CPU?为什么这个 UPDATE 查询会杀死我的 CPU? 【发布时间】:2019-02-09 20:17:32 【问题描述】:

所以随着时间的推移,我注意到我的网站变得越来越慢,通常在高峰时段和周末 - CPU 负载会达到应有的 10 倍,并且网站通常会变得无响应。

经过大量修改后,我发现注释掉这一行会使 CPU 负载降至正常水平:

$this->file_hits++;
$this->weekly_file_hits++;
$this->daily_file_hits++;
$this->file_last_dl_ip = $downloader_ip;
$this->file_last_dl_time = current_time('mysql');

$wpdb->query("UPDATE " . $wpdb->wpfilebase_files
    . " SET file_hits = file_hits + 1, weekly_file_hits = weekly_file_hits + 1, daily_file_hits = daily_file_hits + 1, file_last_dl_ip = '"
    . $downloader_ip . "', file_last_dl_time = '"
    . $this->file_last_dl_time . "' WHERE file_id = "
    . (0+$this->file_id));

这是来自 WordPress 插件的代码。它在下载文件时触发,并且非常不言自明,只需将命中/IP/日期等记录到数据库中的相应行中。

我不明白为什么这个非常简单的更新查询会导致这种情况?

一些信息:

    该网站在正常流量下可以很好地处理约 150 个同时用户,其中大多数人没有登录,因此会收到缓存页面。 在大约 300 个同时用户的大流量下,情况会变得很糟糕。但即使在正常流量下,CPU 也可以跳到“坏”范围。关键是,极端的 CPU 负载似乎非常零星,但随着流量的增加肯定会更加明显。 删除此查询 - 因此仍然提供下载服务,并且除了正在更新的数据库之外,仍然执行所有其他与下载相关的代码 - 并且 CPU 负载保持在“良好”到“正常”范围内,即使有大约 300 个用户在线。所以这个查询肯定是罪魁祸首,或者至少是最大的罪魁祸首。 有问题的 DB 表包含大约 23,000 行。如果有的话,我认为文本搜索可能是造成这种情况的原因,但禁用用户的前端搜索并没有解决任何问题。

【问题讨论】:

表中有多少个file_id?是否已编入索引? 你查看慢查询日志了吗?要么它很慢,你可能只需要一个索引。或者它只是执行得太频繁了。 参见。 wordpress.org/plugins/query-monitor 我认为你已经达到了 wordpress 的极限。如果您有 150 个 并发 用户,恕我直言,您应该考虑一些缓存/集群解决方案。以某种方式解决此更新问题可能会有所帮助 - 直到您不会遇到下一个主要问题。 请显示查询之后它被拼接在一起。 【参考方案1】:

您的 UPDATE 查询似乎运行缓慢。那可能是因为

    您的数据库中的表已变得碎片化或以某种方式混乱,或者 它需要在file_id 列上建立索引,以便WHERE file_id = something 可以在您的UPDATE 中运行得更快。

这是 WP-Filebase 插件吗?如果是这样,联系插件作者的通常建议不适用,因为该插件已被 wordpress.org 当局关闭。

你在做备份,对吧?如果没有,请在执行其他任何操作之前备份您的数据库。

您需要自己修复慢表。最好在您网站的低流量时间执行此操作。

打开 phpmyadmin,打开您的 WordPress 数据库,然后查找名称为 wp_filebase_fileswp_filebasefiles 的表。单击名称。 (具体表名是什么我不知道。)

然后单击屏幕顶部的操作选项卡。

然后,在表维护下单击优化表链接。它可能会运行一段时间。然后看看性能是否有所提高。如果这没有帮助,请单击修复表链接。然后再次尝试性能。

如果这些都没有帮助,您可能需要在您的表上建立一个索引。以下是添加方法。

在 phpMyAdmin 的左侧,点击表格旁边的 [+] 号,然后点击列和索引旁边的 [+] 号。

如果它将file_id 显示为索引,则您已经拥有查询所需的索引,我的建议对您没有帮助。 (对不起。)

如果没有,请单击索引下的新建。你会得到一个对话框。像这样填写。

索引名称:filebase_file_id 索引选择:从下拉菜单中选择“索引”。 列:从下拉列表中选择 file_id。 尺寸:留空。

然后单击“开始”。创建索引可能需要一段时间。然后看看你的表现是否有所好转。

这种事情发生在繁忙的数据库中;很正常,就是脖子疼。

【讨论】:

如果它无法为您提供INDEX,这听起来像是一个草率的插件。 是的,我想这就是 wordpress.org 关闭它的部分原因。 有趣。 postmeta 的索引很差,但对 WP 至关重要。所以,肯定不止这些。 非常感谢您的深入评论,好奇您是否认出了插件数据库代码或查找它?它是 WP Filebase,多年来我已经将它深深地集成到我的网站中,甚至在它被废弃之前就已经对其进行了黑客攻击/添加。无论如何,我确实相信 file_id 已编入索引,“主要”不是“索引”而是同一件事(i.imgur.com/INiQHKi.png)?立即运行优化并观察会发生什么。

以上是关于为啥这个 UPDATE 查询会杀死我的 CPU?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 SELECT 查询不需要我的 UPDATE 查询需要这么长时间?

为啥我的客户端会杀死我的服务器?

为啥我在 Android 中杀死我的应用程序时服务会重新启动?

为啥我的 UPDATE sql 查询不起作用?不会更新表

其他 - 批量查单词

其他 - 批量查单词