Amazon RDS MySQL/Aurora 查询有时会永远挂起。关于我们可以对其进行分类并防止其发生的指标和方法的任何 2 美分?

Amazon RDS MySQL/Aurora query sometimes hangs forever. Any 2 cents on the metrics and approaches we can triage it and prevent it from happening?

只是一些上下文:在我们的旧数据管道系统中,我们是 运行ning MySQL 5.6。或亚马逊 rds 上的 Aurora。我们旧数据管道的坏处是 运行 在数据库服务器上进行大量繁重的计算,因为我们被设计的东西铐住了:将事务数据库视为数据仓库,而我们的后端 API 直接“钓鱼”我们旧系统中的数据库很重。我们目前正在修补这个旧的数据管道,同时在 SnowFlake 中重新设计新的数据仓库。

在我们旧的数据管道系统中,数据管道计算是一系列顺序的 MySQL 查询。随着我们的数据在旧数据管道中变得越来越大,现在的问题是计算可能会永远挂起,例如,第 3 步 MySQL 查询,而我们正在监控 Amazon CloudWatch/grafana 中的所有指标(CPU、数据库连接、可用内存、网络吞吐量、交换使用、读取延迟、可用存储、写入延迟等)看起来很正常。 MySQL 慢速查询日志在这里并不是很有用,因为我们在数据管道中的每个查询本质上都很慢(可能需要数小时才能 运行 查询,因为旧数据管道是 运行在数据库服务器上进行大量繁重的计算)。我们通常解决这些问题的方法是“盲目”升级 MySQL/Aurora Amazon rds 服务,希望它能解决问题。我在想

(1) MySQL 5.6 中推荐的数据库指标是什么。或 Aurora on Amazon rds 我们应该实时监控以帮助我们确定为什么查询永远冻结?喜欢 innodb_buffer_pool_size?

(2) 是否有任何现有工具 and/or 内部方法可以预测我们需要多少硬件资源才能自信地执行查询并知道它会成功?有人可以分享一些 2 美分吗?

一个想法:由于 Amazon rds 有时有点黑盒,一种可能的方法是在与我们的 Amazon MySQL 5.6/Aurora rds 并行的 Amazon EC2 实例上托管我们自己的 MySQL 服务器生产服务器,所以我们可以通过 ssh 进入 MySQL 服务器和 运行 很多命令工具,比如 mytop (https://www.tecmint.com/mysql-performance-monitoring/) 来收集更多实时 MySQL 指标,这可以提供帮助我们对问题进行分类。对大师的任何 2 美分开放。谢谢!

None 中提到的工具 link 应该需要 运行 on 数据库服务器本身,并且在某种程度上这是真的,如果他们不是,他们的行为应该没有区别。 运行 他们在任何 Linux 服务器上,给出适当的 --host--user--password 参数(以他们可能期望的任何形式)。甚至 mysqladmin 也可以远程工作。大多数 MySQL 命令行工具都可以(例如 mysql cli、mysqldumpmysqlbinlog,甚至 mysqlcheck)。

大多数管理实用程序无法通过 运行 在与 MySQL 服务器本身相同的服务器上获得神奇的耦合——这是一个常见的误解,但事实上,即使 运行在同一台机器上,他们仍然需要连接到服务器,就像任何其他客户端一样。他们可能会在本地连接到 unix 套接字而不是使用 TCP,但它仍然是一个普通的客户端连接,并且不提供额外的功能。

也可以在您自己的 EC2 实例(甚至您自己的数据中心)上 运行 RDS/MySQL 或 Aurora/MySQL 服务器的外部副本。但这不太可能告诉您很多您无法从 RDS 指标中学到的东西,尤其是考虑到上述情况。 (另请注意,即使是副本服务器也使用返回主服务器的普通客户端连接来获取其复制流。)

避免调整服务器参数的诱惑。在 RDS 上,大多数默认值都非常合理,除非您明确而准确地知道为什么要调整参数...不要这样做。

查询慢的最可能解释...是查询编写不当 and/or 索引设计不当。

如果您不熟悉 EXPLAIN SELECT,那么您需要学习它,体验它,热爱它。 SQL 是声明性的,而不是程序性的。也就是说,SQL 告诉服务器您想要什么——而不是具体说明如何在内部获取它。例如: SELECT ... FROM x JOIN y 告诉服务器匹配来自 table x 和 y 的行 ON 某个条件,但不告诉服务器是否从 x 读取 then在 y 中找到匹配的行...或从 y 中读取并在 x 中找到匹配的行。无论哪种方式,最终结果都是相同的——服务器首先在内部检查 table 并不重要——但如果查询或索引不允许服务器正确推断出最佳路径您请求的结果,它可能会花费无数小时来进行不必要的努力。

举一个极端和过于简化的例子,table 有数百万行,table 有 1 行。首先阅读小 table 是有意义的,这样您就知道您要在大 table 中加入什么 1 值。通读大 table 中的每一行,然后检查小 table 以匹配数百万行中的每一行是没有意义的。您加入 table 的顺序可能与实际加入的顺序不同。

这就是 EXPLAIN 的用武之地。这允许您检查 查询计划 -- 内部 查询优化器 [=51] 的策略=] 已经得出结论,将以最少的努力得到您需要的答案。这就是关系数据库系统的核心魅力——根据它对数据的了解,在最佳时间找到正确的解决方案。 EXPLAIN 显示 table 的访问顺序、它们的连接方式、使用的索引以及每个 table 的估计行数涉及 - 这些数字相乘可以让您估计解决查询所涉及的排列数量。两个小 tables,每个有 50,000 行,没有适当的索引连接,意味着必须评估两个 tables 之间完全不合理的 2,500,000,000 个唯一组合;每一行都必须与其他每一行进行比较。简而言之,如果事实证明这是您(在不知不觉中)要求服务器做的事情,那么您肯定做错了什么。每当您编写复杂查询时,检查您的查询计划应该是第二天性,以确保服务器使用明智的策略来解决它。

输出是隐秘的,但可以使用秘密解码器环。

https://dev.mysql.com/doc/refman/5.7/en/explain.html#explain-execution-plan