MySQL之性能剖析(二)

发布于:2024-05-24 ⋅ 阅读:(212) ⋅ 点赞:(0)

MySQL之性能剖析

通过性能剖析进行优化

一旦掌握并时间面向响应时间的优化方法,就会发现需要不断地对系统进行性能剖析(profiling).
性能剖析是测量和分析时间花费在哪里的主要方法。性能剖析一般有两个步骤:测量任务所花费的时间;然后对结果进行统计和排序,将重要的任务排到前面。性能剖析工具的工作方式基本相同。在任务开始时启动计时器,在任务结束时停止计时器,然后用结束时间减去启动时间得到响应时间。也有些工具会记录任务的夫人吴。这些结果数据可以用来绘制调用关系图,但对于哦我们的目标来说更重要的时,可以将相似的任务分组并进行汇总。对相似的任务分组并进行汇总可以帮助对那些分到一组的任务做更复杂的统计分析,但至少需要知道每一组有多少任务,并计算出总的响应时间。通过性能剖析报告(profile report)可以获得需要的结果。性能剖析报告会列出所有的任务列表。每行记录一个任务,包括任务名、任务的执行时间、任务的消耗时间、任务的平均执行时间,以及该任务执行时间占全部时间的百分比。性能剖析报告会按照任务的消耗时间进行降序排序。

我们将实际地讨论两种类型的性能剖析:基于执行时间的分析和基于等待的分析。基于执行时间的分析研究的是什么任务的执行时间最长,而基于等待的分析则是判断任务在什么地方被阻塞的时间最长。如果任务执行时间长是因为消耗了太多的资源且大部分时间花费在执行上,等待的时间不多,这种情况基于等待的分析作用就不大。反之亦然,如果任务一直在等待,没有消耗什么资源,去分析执行时间就不会有什么结果。如果不能确认问题是出在执行还是等待上,那么两种方式都需要试试。
事实上,当基于执行时间的分析发现一个任务需要花费太多时间的时候,应该深入去分析一下,可能会发现某些"执行时间"实际上是在等待。例如,SELECT查询花费了大量时间,如果深入研究,则可能会发现时间都花费在等待IO上。
在对系统进行性能剖析前,必须先要能够进行而苍凉,这需要系统测量化的支持。可测量的系统一般会有多个测量点可以捕获并手机数据,但实际系统很少可以做到可测量化。大部分系统都没有多少可测量点,即使有也只提供一些活动的技术,而没有活动花费的时间统计。

例子

# Profile
# Rank Query ID                      Response time  Calls R/Call V/M   Ite
# ==== ============================= ============== ===== ====== ===== ===
#    1 0xFFFCA4D67EA0A788813031B8... 328.2315 90.4% 30520 0.0108  0.01 COMMIT
#    2 0xB2249CB854EE3C2AD30AD7E3...   8.0186  2.2%  1208 0.0066  0.01 UPDATE sbtest?
#    3 0xE81D0B3DB4FB31BC558CAEF5...   6.6346  1.8%  1639 0.0040  0.01 SELECT sbtest?
#    4 0xDDBF88031795EC65EAB8A8A8...   5.5093  1.5%   756 0.0073  0.02 DELETE sbtest?
# MISC 0xMISC                         14.6011  4.0%  3334 0.0044   0.0 <13 ITEMS>

理解性能剖析

MySQL的性能剖析(profile)将最重要的任务展示在前面,但有时候没显式出来的信息也很重要。不幸的是,尽管性能剖析输出了排名、总计和平均值,但还是有很多需要的信息是却是的,如下所示:

  • 1.值得优化的查询(worthwhile query)
    性能剖析不会自当给出那些查询值得花时间去优化。这把我们带回到优化的不呢一,如果你读过Cary Millsap的书,对此就会有很多的理解。这里我们要再次强调两点:
    第一,一些只占总响应时间比重很小的查询是不值得优化的。根据阿姆达尔定律(Amdahl’s Law),对一个占总响应时间不超过5%的查询进行优化,无论如何努力,收益也不会超过5%.
    第二,如果花费了1000美元去优化一个任务,但业务的收入没有任何增加,那么可以说反而导致业务被逆优化了1000美元。如果优化的成本大于收益,就应当停止优化
  • 2.异常情况
    某些任务即使没有出现在性能剖析输出的前面也需要优化。比如某些任务执行次数很少,但每次执行都非常慢,严重影响用户体验。因为其执行频率低,所以总的响应时间占比并不突出。
  • 3.未知的未知
    一款好的性能剖析工具会显式可能的"丢失的时间"。丢失的时间指的是任务的总时间和实际测量到的时间之间的差。例如,如果处理器的CPU时间是10秒,二剖析到的任务总时间是9.7秒,那么就有300毫秒的丢失时间。这可能是有些任务没有测量到,也可能是由于测量的误差和精度问题的缘故。如果工具发现了这类问题,则要引起重视,因为有可能错过了某些重要的事情。即使性能剖析没有发现丢失时间,也需要注意考虑这类问题存在的可能性,这样才不会错过重要的信息。
  • 4.被掩藏的细节
    性能剖析无法显式所有响应时间的分布。只相信平均值是非常危险的,它会隐藏很多信息,而且无法表达全部情况。Peter经常举例说医院所有病人的平均提问没有任何价值。假如在前面的性能剖析的例子中,如果有两次查询的响应时间是1秒,而另外12771次查询的响应时间是几十微妙,结果会怎样?只从平均值里是无法发现两次1秒的查询的。要做出最好的决策,需要为性能剖析里输出的这一样中包含的12773次查询提供更多的信息,尤其是更多响应时间的信息,比如直方图、百分比、标准差、偏差指数。

剖析MySQL查询

对查询进行性能剖析有两种方式,每种方式都有各自的问题,可以剖析整个数据库服务器,这样可以分析出哪些查询时主要的压力来源.定位到具体需要优化的查询后,也可以钻取下去对这些查询进行单独的剖析,分析哪些子任务是响应时间的主要消耗者。

剖析服务器负载

服务器端的剖析很有价值,因为在服务器端可以有效地审计效率低下的查询。定位和优化"坏"查询能够显著地提升应用的性能,也能解决某些特定的难题。还可以降低服务器的整体压力,这样所有的查询都将因为减少了对共享资源的争用而收益(“间接的好处”)。降低服务器的负载也可以推迟或者避免升级更昂贵硬件的需求,还可以发现和定位糟糕的用户体验,比如某些极端情况.
MySQL的每一个新版本中都增加了更多的可测量点。如果当前的趋势可靠的话,那么在性能方面比较重要的测量需求很快能够在全球范围内得到支持。但如果只是需要剖析并找出代价高的查询,就不需要如此复杂。有一个工具很早之前就能帮到我们了,这就是慢查询日志。

捕获MySQL的查询到日志文件中

在MySQL中,慢查询最初只是捕获比较慢的查询,而性能剖析却需要针对所有的查询。而且在MySQL5.0及之前的版本中,慢查询日志的响应时间的单位是秒,粒度太粗了。幸运的是,这些限制都已经成为历史了。在MySQL5.1及更新的版本中,慢日志的功能已经被加强,可以通过设置long_query_time为0来捕获所有的查询,而且查询的响应时间单位已经可以做到微秒级。如果使用的是Percona Server,那么5.0版本就具备了这些特性,而且Percona Server提供了对日志内容和查询捕获的更多控制能力。
在MySQL的当前版本中,慢查询日志是开销最低,精度最高的测量查询时间的工具。如果还在担心开启慢查询日志会带来额外的I/O开销,那大可放心。已经在IO密集型场景做过基准测试,慢查询日志带来的开销可以忽略不计(实际上在CPU密集型场景的影响还稍微大一些)。更需要担心的是日志可能消耗大量的磁盘空间。如果长期开启慢查询日志,注意要部署日志轮转(log rotation)工具。或者不要长期启用慢查询日志,只在需要手机负载样本的期间开启即可。
MySQL还有另外一种查询日志,被称之为"通用日志",但很少用于分析和剖析服务器性能。通用日志在查询请求服务器时进行记录,所以不包含响应时间和执行计划等重要信息。MySQL5.1之后支持将日志记录到数据库的表中,但多数情况下这样做没什么必要。这不但对性能有较大影响,而且MySQL5.1在将慢查询记录到文件中时已经支持微秒级别的信息,然而将慢查询记录到表中会导致时间粒度退化为只能到秒级。而秒级别的慢查询日志没有太大的意义。

Percona Server得慢查询日志比MySQL官方版本记录了更多细节且有价值得信息,如查询执行计划、锁、IO活动等。这些特性都是随着处理各种不同得优化场景得需求而慢慢加进来得。另外在可管理性上也进行了增强。比如全局修改针对每个连接的long_query_time的阈值,这样当应用使用连接池或者持久连接的时候,可以不用重置会话级别的变量而启动或者停止连接的查询日志。总的来说,慢查询日志是一种轻量而且功能全面的性能剖析工具,是优化服务器查询的利器。
有时因为某些原因如权限不足等,无法在服务器上记录查询。这样的限制也常常碰到,所以官方开发了两种替代的技术,都集成到了Percona Toolkit中的
pt-query-digest中。

  • 1.第一种是通过–processlist选项不断查看SHOW FULL PROCESSLIST的输出,记录查询第一次出现的时间和消失的时间。某些情况下这样的精度也足够发现问题,但却无法捕获所有的查询。一些执行较快的查询可能在两次执行的间隙就执行完成了,从而无法捕获到。
  • 2.第二种技术是通过抓取TCP网络包,然后根据MySQL的客户端/服务端通信协议进行解析。可以先通过tcpdump将网络包数据保存到磁盘,然后使用pt-query-digest的–type=tcpdump选项来解决并分析查询.此方法的精度比较高,并且可以捕获所有查询。还可以解析更高级的协议特性,比如可以解析二进制协议,从而创建并执行服务器预解析的语句(prepared statement)及压缩协议。另外还有一种方法,就是通过MySQL Proxy代理曾的脚本来记录所有查询,但在实践中很少这样做
分析查询日志

强烈建议大家从现在起就利用慢查询日志捕获服务器上的所有查询,并且进行分析。可以在一些典型的时间窗口如业务高峰期的一个小时内记录查询。如果业务趋势比较均衡,那么一分钟甚至更短的时间内捕获需要优化的低效查询也是可以的。
不要直接打开整个慢查询日志进行分析,这样做只会浪费时间和金钱。首先应该生成一个剖析报告,如果需要则,则可以再查看日志中需要特别关注的部分。自顶向下是比价好的方式,否则有可能像前面提到的,反而导致业务的逆优化。
从慢查询日志中生成剖析报告需要有一款好工具,这里建议使用pt-query-digest,这毫无疑问是分析MySQL查询日志最有力的工具。该工具功能强大,包括可以将查询报告保存到数据库中,以及追踪工作负载随时间的变化。
一般情况下,只需要将慢查询日志文件作为参数传递给pt-query-digest,就可以正确地工作了,它将查询的剖析报告打印出来,并且能够选择将"重要"的查询逐条打印出更详细的信息。输出的报告细节详尽,绝对可以让生活更美好。