【问题标题】:How to predict MySQL tipping points?如何预测 MySQL 的临界点?
【发布时间】:2009-02-17 20:55:36
【问题描述】:

我正在开发一个使用 MySQL 5.0 数据库和 InnoDB 表的大型 Web 应用程序。在过去的几个月里,我们两次经历了以下情况:

  1. 数据库服务器可以正常运行数周,负载低且查询速度慢。
  2. 以前快速运行的频繁执行的查询突然开始运行非常缓慢。
  3. 数据库负载达到峰值,网站挂起。

这两种情况的解决方案都是在慢查询日志中找到慢查询,并在表上创建一个新的索引来加速它。应用索引后,数据库性能恢复正常。

最令人沮丧的是,在这两种情况下,我们都没有对即将到来的厄运发出警告。我们所有的监控系统(例如,系统负载、CPU 使用率、查询执行率、慢查询)都告诉我们数据库服务器运行良好。

问题 #1:我们如何预测或完全避免这些临界点?

我们没有定期做的一件事是运行 OPTIMIZE TABLE 或 ANALYZE TABLE。我们很难找到关于手动执行这些操作的频率(如果有的话)的良好经验法则。 (由于这些命令 LOCK 表,我们不想不加选择地运行它们。)这些场景听起来像是未优化表的结果吗?

问题 #2:我们应该手动运行 OPTIMIZE 还是 ANALYZE?如果有,多久一次?

有关应用程序的更多详细信息:数据库使用模式约为 95% 读取,5% 写入;数据库每秒执行大约 300 个查询;在这两种情况下,慢查询中使用的表是相同的,并且有数十万条记录。

【问题讨论】:

    标签: mysql database innodb


    【解决方案1】:

    MySQL 性能博客是一个很棒的资源。也就是说,this 帖子涵盖了正确调整 InnoDB 特定参数的基础知识。

    我还发现MySQL Reference Manual 的PDF 版本是必不可少的。 Chapter 7 covers general optimizationsection 7.5 涵盖了您可以玩弄的特定于服务器的优化。

    从您的服务器的声音来看,query cache 对您来说可能具有巨大的价值。

    参考手册还为您提供了一些关于慢查询、缓存、查询优化甚至使用索引进行磁盘寻道分析的详细信息。

    可能值得您花时间研究多主复制,允许您完全锁定一台服务器并运行 OPTIMIZE/ANALYZE,而不会影响性能(因为 95% 的查询是读取的,另一台服务器可以管理写得很好)。

    第 12.5.2.5 节详细介绍了 OPTIMIZE TABLE,第 12.5.2.1 节详细介绍了 ANALYZE TABLE。

    更新您的编辑/强调:

    问题 #2 很容易回答。来自参考手册:

    优化:

    如果您删除了表的大部分或对具有可变长度行的表进行了许多更改,则应使用 OPTIMIZE TABLE。 [...]您可以使用 OPTIMIZE TABLE 来回收未使用的空间并对数据表进行碎片整理。

    然后分析:

    ANALYZE TABLE 分析并存储表的键分布。 [...] MySQL 使用存储的键分布来决定当您对常量以外的东西执行连接时应该连接表的顺序。此外,在决定为查询中的特定表使用哪些索引时,可以使用键分布。

    OPTIMIZE 适合在空闲时间运行。 MySQL 对已删除的行进行了很好的优化,但是如果您从表中删除 20GB 的数据,那么运行它可能是个好主意。在大多数情况下,这绝对不是良好性能所必需的。

    分析更为关键。如前所述,当涉及到几乎任何查询时,让 MySQL 所需的表数据可用(由 ANALYZE 提供)非常重要。它应该在共同的基础上运行。

    问题 #1 有点诡计。发生这种情况时,我会非常仔细地观察服务器,即磁盘 I/O。我敢打赌,您的服务器正在破坏您的交换或(InnoDB)缓存。在任何一种情况下,它都可能与查询、调整或负载相关。未优化的表可能会导致此问题。如前所述,运行 ANALYZE 可以极大地提高性能,并且可能也会有所帮助。

    【讨论】:

      【解决方案2】:

      我还没有找到任何预测 MySQL“临界点”的好方法——我遇到了一些。

      话虽如此,我发现引爆点与桌子大小有关。但不仅仅是原始表大小,而是查询的“感兴趣区域”有多大。例如,在一个超过 300 万行和大约 40 列(大约四分之三的整数)的表中,大多数可以根据索引轻松选择其中一部分的查询速度很快。但是,当一个索引列的查询中的一个值意味着三分之二的行现在“有趣”时,查询现在比正常情况慢约 5 倍。教训:尝试整理您的数据,这样就不需要进行此类扫描。

      但是,这种行为现在为您提供了一个可供查找的大小。这个大小将在很大程度上取决于您的服务器设置、MySQL 服务器变量以及表的模式和数据。

      同样,如果周期为两周,我看到报告查询在合理的时间内(约 45 秒)运行,但如果周期延长至四周,则需要半小时。

      【讨论】:

        【解决方案3】:

        使用slow query log,这将帮助您缩小要优化的查询范围。

        对于时间紧迫的查询,有时最好通过使用提示来保持稳定的计划。

        【讨论】:

          【解决方案4】:

          听起来您的处境令人沮丧,而且可能不是最好的代码审查流程和开发环境。

          每当您向代码添加新查询时,您都需要检查它是否已准备好适当的索引,并将其添加到代码版本中。

          如果您不这样做,您的第二个选择是持续监控慢查询日志,然后击败开发人员;我的意思是去添加索引。

          有一个选项可以启用对不使用索引的查询的日志记录,这对您有用。

          如果有一些查询“工作并停止工作”(但正在“使用和索引”),那么查询可能一开始就不是很好(索引中的基数低;连接效率低;。 ..) 并且在添加查询时仔细评估查询的第一条规则将适用。

          对于问题 #2 - 在 InnoDB 上,“分析表”基本上可以免费运行,因此如果您的连接性能不佳,运行它并没有什么坏处。除非表中键的平衡发生很大变化,否则它不太可能有帮助。它几乎总是归结为错误的查询。 “优化表”重建 InnoDB 表;根据我的经验,它的帮助足以值得让表在持续时间内不可用(或在它运行时进行主-主故障转移)的麻烦,这是相对罕见的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-04-02
            • 2015-07-31
            • 2018-11-02
            • 1970-01-01
            • 2018-09-18
            • 2019-06-25
            • 1970-01-01
            相关资源
            最近更新 更多