文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

今年早些时候,我们 升级了数据库集群到 MySQL 5.6. MySQL 5.6 包含很多 提升 以及新特性,特别是性能模型这方面。

MySQL 的 performance schema 包含一组表用来跟踪 MySQL 内部的性能指标。这些表给我们提供了一个窗口来检视数据库内部发生的行为,例如正在执行什么查询、IO 等待的统计以及历史的性能数据。

MySQL 5.6 在性能模型方面增加了一个新的表是 table_io_waits_summary_by_index. 它收集了每个索引的统计信息,包括存储引擎处理层关联了多少行记录。这个表给我们 深入了解 查询的性能以及索引的使用情况。我们可以导入这些数据到我们的指标系统,并根据时间显示出来以帮助我们跟踪复制延迟。例如跟踪前 10 个异常表操作的方法如下:

第 1 段(可获 2 积分)

top 10 most deviant update queries

MySQL 5.6.5 新特性 还包含另外一个概要表: events_statements_summary_by_digest. 该表跟踪了唯一查询以及它们执行的频度和执行耗费的时间等等。不同于 SELECT id FROM users WHERE login = 'zerowidth' 这样的查询,正常的形式应该是 SELECT `id` FROM `users` WHERE `login` = ?, 因此很容易对同一个查询进行分组显示。这些查询的汇总和计数可以很好的回答这样的问题:“最频繁更新的数据” 以及 “占用最多时间的查询”.

第 2 段(可获 2 积分)

当我们研究这个表中数据时,很多查询就会凸显出来。例如在我们一个最活跃而且非常大的表上执行一个简单的 UPDATE 语句占了所有 UPDATE 语句 25% ,这个 UPDATE 语句是  repositories: UPDATE `repositories` SET `health_status` = ? WHERE `repositories` . `id` = ?. 每次进行一个健康状态监测时就会去更新字段,相应的代码如下:

class Repository
  def update_health_status(new_status)
    update_column :health_status, new_status
  end
end

一旦被确定,我们就可以使用 scientist 去度量此列需要更新的频度(状态是否更改)以及该数据被使用的频度:

第 3 段(可获 2 积分)

health status update % required

上表显示的结果就是我们想要的。列需要更新的时间不到 5%,对代码做一些简单的改动:

class Repository
  def update_health_status(new_status)
    if new_status != health_status
      update_column :health_status, new_status
    end
  end
end

5% 下降到 2%。两行代码的改动带来的效果明显。下图来自于 VividCortex, 显示了查询数量:

vividcortex screenshot showing drop in update query volume

GitHub 是一个已经有 7 年历史的 Rails 应用,会有很多不可预料的热点以及瓶颈,因为负载不断的在变化。而 MySQL 的 performance schema 对我们来说是一个非常有价值的工具,我们也鼓励你把它用起来。你可能惊奇一些小的改动会大幅降低数据库的负载。

下面是一个示例查询,显示了最频繁执行的 10 个 UPDATE 语句:

SELECT
  digest_text,
  count_star / update_total * 100 as percentage_of_all
FROM events_statements_summary_by_digest,
( SELECT sum(count_star) update_total
  FROM events_statements_summary_by_digest
  WHERE digest_text LIKE 'UPDATE%'
) update_totals
WHERE digest_text LIKE 'UPDATE%'
ORDER BY percentage_of_all DESC
LIMIT 10

 

第 4 段(可获 2 积分)

文章评论