最近几天我遇到了一个问题,我的数据库服务器有 2 个四核处理器和 24 GB 的 RAM,最近我们遇到了一个大问题,服务器正常运行时 CPU 使用率约为 130%,然后它会随机飙升到 750%,几乎占满所有核心,这会让我们的网站变得非常慢。我重新启动了 mysql 进程,它解决了这个问题,但大约 10 分钟后它又发生了。上次发生这种情况时,我让它保持在 750%,然后几分钟后它又降下来了。我在发生这种情况时进行了进程转储,队列中有大约 4,000 个查询,显示正在复制/发送到 tmp 表。
如果有人知道这个问题或者是 mysql innodb 数据库和 php 的专家,请告诉我,我甚至愿意付费来解决这个问题,价格不是问题,只是希望这个问题得到解决。
答案1
不要就这样重启 MySQL。通常这根本起不到任何作用 —— 麻烦的查询或情况迟早会再次出现,而且重启后 MySQL 无论如何都需要预热。重启会刷新其缓存等等。
我怀疑这是因为您的网站上存在某种异常活动(例如 DoS 攻击或 Slashdot/Reddit 效应),或者最近的更新包含一个新的奇特的数据库杀伤错误。检查您的 http 日志,或者为了获得更直观的视图,通过 Webalizer 或类似程序运行 Apache 日志。
如果您的问题不是由于网络活动引起的,或者您希望将来避免出现类似的问题,那么您刚才描述的尖峰的典型情况是:
my.cnf 未进行最佳调整 - 您是否已微调 InnoDB 设置?我们可以查看一下您的 my.cnf 吗?
一些使用频繁的表缺少索引。
表类型为 MyISAM,然后一些长时间运行的 SELECT 与大量 UPDATE/INSERT/DELETE 活动相结合会导致巨大的查询队列。我认为这实际上可能是你的问题:您是否绝对确定您的表是 InnoDB 格式,并且这个表不是意外地(甚至是故意地)采用 MyISAM 格式?
my.cnf 中的值太小
tmp_table_size
;如果您的数据库运行具有大量排序、大结果集或类似内容的查询,则可能会出现这种情况。太小的 tmp_table_size 会导致 MySQL 将查询所需的临时表创建到硬盘而不是将其存储到 RAM 中。对于一个查询来说,这本质上不是一件坏事,但如果许多查询同时执行此操作,您的硬盘性能将成为一个严重的瓶颈。我怀疑这可能是您目前遇到的另一件事。数据库位于 SAN 或其他存储设备上,出于某种原因,SAN 本身的速度会变慢;也许其他服务器正在大量使用它。
文件系统和/或 I/O 提升正在影响性能。例如,如果你有一个典型的 Linux 发行版,它们现在捆绑了CFQ作为默认 I/O 提升。这可能远不是数据库使用的最佳选择 -最后期限或者预期的更好,我通常使用最后期限。如果您有疑问,我可以指导您如何检查和/或更改当前的 I/O 提升率 - 该操作是安全的,并且可以在线完成。对于文件系统,ext3 可能不是具有巨大数据库文件的最佳系统,尤其是在并发性很高的情况下。
接下来是一些问题:
如果是 InnoDB,那么
SHOW GLOBAL INNODB STATUS
在峰值期间会告诉您什么?您的网站需要访问的表格是否很大?我们谈论的是数千行、数百万行……?从存储角度来看,它们是否占用大量磁盘空间?
您使用的是什么操作系统?文件系统是什么?文件系统是否经过了调整?数据库是位于本地磁盘还是某种共享存储(如 SAN)上?
是的,您有 24 GB 的内存。但是
free
在峰值期间会向您报告什么?您运营的网站类型是怎样的?网站是否易于缓存(例如新闻网站,内容变化相对较少),还是像 Facebook 那样的超级动态网站?