【问题标题】:Measuring MySQL 'load' from query usage and query type frequency从查询使用情况和查询类型频率测量 MySQL 的“负载”
【发布时间】:2018-04-25 01:50:00
【问题描述】:

我有一个包含许多表的 mysql 数据库。该数据库为流量越来越大的网站提供支持。

我已经设计了我的数据库和查询,以有意避免会造成性能瓶颈的连接,这样我就可以根据需要将我的表拆分到单独的服务器上,以防特定表负载过多(稍后,我可以根据需要对单个表进行分片)。

我的问题是:考虑到我拥有的表数量,是否有一种简单的方法可以检测哪个表和查询接收的“负载”最多:我特别想知道读写使用率高的表。

我想通过某种方式(除了查看我的代码和日志)来确定应该将哪些表移动到其他服务器以分发请求和管理资源。我通常使用我知道的“负载”一词,也许是错误的(?)。

【问题讨论】:

    标签: mysql database database-performance


    【解决方案1】:

    这正是 Percona Toolkit 的用途(以及许多其他用途)。具体来说,pt-query-digest (Link) - 您可以将它用于大量实用程序,从慢速查询到检测 SQL 注入。

    在这种情况下,pt-query-digest 可以与设置long_query_time 的一般策略一起使用,通过设置long_query_time = 0 将所有查询记录到slow_query_log 文件。现在,所有查询都记录到慢查询文件(确保将时间重置为上一个值)。

    mysql> SELECT @@GLOBAL.slow_query_log_file;
    +------------------------------------------+
    | @@GLOBAL.slow_query_log_file             |
    +------------------------------------------+
    | /var/lib/ubuntu/mysql/slowquery.log            |
    +------------------------------------------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL slow_query_log_file='/tmp/sniffed_queries.log';
    mysql> SET GLOBAL long_query_time = 0; 
    mysql> FLUSH LOGS; #Clear the logs
    

    因此,现在您可以在服务器上运行所有查询的便捷日志,而不会弄乱您的常规日志或其他表,以便使用 pt-query-digest 进行分析:

    pt-query-digest /tmp/sniffed_queries.log 
    

    将产生一个非常有用的伟大输出,你对初学者感兴趣:

    3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

    # Profile
    # Rank Query ID           Response time Calls R/Call Apdx V/M   Item
    # ==== ================== ============= ===== ====== ==== ===== ==========
    #    1 0x92F3B1B361FB0E5B  4.0522 50.0%   312 0.0130 1.00  0.00 SELECT wp_options
    #    2 0xE71D28F50D128F0F  0.8312 10.3%  6412 0.0001 1.00  0.00 SELECT poller_output poller_item
    #    3 0x211901BF2E1C351E  0.6811  8.4%  6416 0.0001 1.00  0.00 SELECT poller_time
    #    4 0xA766EE8F7AB39063  0.2805  3.5%   149 0.0019 1.00  0.00 SELECT wp_terms wp_term_taxonomy wp_term_relationships
    #    5 0xA3EEB63EFBA42E9B  0.1999  2.5%    51 0.0039 1.00  0.00 SELECT UNION wp_pp_daily_summary wp_pp_hourly_summary wp_pp_hits wp_posts
    #    6 0x94350EA2AB8AAC34  0.1956  2.4%    89 0.0022 1.00  0.01 UPDATE wp_options
    #    7 0x7AEDF19FDD3A33F1  0.1381  1.7%   909 0.0002 1.00  0.00 SELECT wp_options
    #    8 0x4C16888631FD8EDB  0.1160  1.4%     5 0.0232 1.00  0.00 SELECT film
    #    9 0xCFC0642B5BBD9AC7  0.0987  1.2%    50 0.0020 1.00  0.01 SELECT UNION wp_pp_daily_summary wp_pp_hourly_summary wp_pp_hits
    #   10 0x88BA308B9C0EB583  0.0905  1.1%     4 0.0226 1.00  0.01 SELECT poller_item
    #   11 0xD0A520C9DB2D6AC7  0.0850  1.0%   125 0.0007 1.00  0.00 SELECT wp_links wp_term_relationships wp_term_taxonomy
    #   12 0x30DA85C940E0D491  0.0835  1.0%   542 0.0002 1.00  0.00 SELECT wp_posts
    #   13 0x8A52FE35D340A347  0.0767  0.9%     4 0.0192 1.00  0.00 TRUNCATE TABLE poller_time
    #   14 0x3E84BF7C0C2A3005  0.0624  0.8%   272 0.0002 1.00  0.00 SELECT wp_postmeta
    #   15 0xA01053DA94ED829E  0.0567  0.7%   213 0.0003 1.00  0.00 SELECT data_template_rrd data_input_fields
    #   16 0xBE797E1DD5E4222F  0.0524  0.6%    79 0.0007 1.00  0.00 SELECT wp_posts
    #   17 0xF8EC4434E0061E89  0.0475  0.6%    62 0.0008 1.00  0.00 SELECT wp_terms wp_term_taxonomy
    #   18 0xCDFFAD848B0C1D52  0.0465  0.6%     9 0.0052 1.00  0.01 SELECT wp_posts wp_term_relationships
    #   19 0x5DE709416871BF99  0.0454  0.6%   260 0.0002 1.00  0.00 DELETE poller_output
    #   20 0x428A588445FE580B  0.0449  0.6%   260 0.0002 1.00  0.00 INSERT poller_output
    # MISC 0xMISC              0.8137 10.0%  3853 0.0002   NS   0.0 
    <147 ITEMS>
    

    从这个示例中,您可以看到 SELECT...FROM wp_options 调用的 R/Call 导致了最大的负载。还有很多很棒的其他信息。 如果您要坚持使用 mysql,我强烈建议您尽早并经常使用 percona-toolkit - 我将它们推迟了很长时间,并且仍然为他们会遇到的头痛而自责预防。

    Percona 对此有一篇很棒的文章,这是针对他们的 Percona Server MySQL 构建的,非常棒,但仍然应该适用:Identifying the load with the help of pt-query-digest and Percona Server

    【讨论】:

    • 我还没有尝试过你的解决方案,但我研究了一下,它似乎会做我想做的事。已接受答案!
    • 哇!似乎它是我见过的最好的配置文件工具,您对如何使用它的详细回答非常完美!你让我开心!谢谢!
    • 就我而言,我还必须执行set global slow_query_log = 'ON' 才能使其正常工作。
    【解决方案2】:

    您可以在表上设置触发器,并让触发器将要操作的表名插入到单独的跟踪表中。

    我可以看到两种设置此类触发器的方法。

    1. 每次都将触发器插入到跟踪表中。您的跟踪表将存储要操作的表的名称。然后,您可以通过按表名对跟踪表进行分组来计算更新次数。这里的问题是每次更新都需要一个单独的行。

    1. 让跟踪表同时存储表名和计数。然后让触发器根据需要更新计数:
      例如。
      SELECT * FROM trackingTable WHERE table_name = 'sometablename';
      IF @@ROWCOUNT == 0 -- sometablename 不在 trackingTable
      开始
      INSERT INTO sometablename VALUES('sometablename, 1); -- 插入表格,count=1
      结束
      其他
      开始
      将@count 声明为 INT;
      SET @count = (SELECT thecount FROM trackingTable WHERE table_name = 'sometablename');
      SET @count = @count+1; -- 计数加 1
      UPDATE trackingTable SET theCount=@count WHERE table_name='sometablename';
      结束

    【讨论】:

      猜你喜欢
      • 2016-03-03
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      相关资源
      最近更新 更多