MySQL 性能监控工具-mysqlreport

MySQL 性能监控工具--mysqlreport

管理 MySQL 最让人困扰的就是如何有效的掌握 MySQL 的健康状况,因为 MySQL 虽然有提供许多系统变数值供您参考,但这些零散的数据若要手动搜集与过滤将会是一件十分没有效率的事情(除非您写 Scripts 去分析)。而接下来要介绍的这套 "工具" 其实是由 hackmysql.com 的站长所撰写的 Perl Scritps,旨在协助 MySQL DBA 搜集与分析 MySQL 的运作状况。

官方网站: http://hackmysql.com/
软体下载: http://hackmysql.com/mysqlreport

这份文件有很大部份是参考 Daniel Nichter 的 mysqlreport Guide( http://hackmysql.com/mysqlreportguide),但不完全是翻译,里面加入了一些我觉得可能会对读者有帮助的资料,并删除了部份我认为会对读者产生混淆的资讯。小弟的功力不足,也许会有所错误,若是您发现我有地方写错了也请您不吝指正,谢谢。

接下来本文开始:

mysqlreport 可将重要的 MySQL 系统资讯整理为具有较高可读性的报表,使你更容易阅读与深入理解目前 MySQL 的实际运作状况。除了手动执行 SHOW STATUS 指令并以人眼去过滤与判断目前的系统状态以外,mysqlreport 大概是较好(八成也是唯一)的替代方案。

目前的 mysqlreport 版本可以产生大量、具有完善资讯的报表,其报表完整的覆盖了实务上所有重要的 MySQL 系统资讯,也可以产生只具有最重要资讯的较精简报表。完整的报表包含了 14 种不同面向,超过 121 行的完整资讯;精简的报表包含了 6 种不同面向,总计 29 行的最重要资讯。

此文件可教导您如何解读 mysqlreport 所产生出来的各项资讯。如此一来,当您在阅读 mysqlreport 所产生出来的报表时,您才可以回答最重要的问题:『MySQL Server 目前的运作状况究竟如何?』

为了让您有较深入的理解,此文件将从报表的第一行开始逐项的解释,当您阅读完此文件后,您应该具有完整的知识可以将 mysqlreport 佈署在任何 Server 上,并且有效的掌握 MySQL Server 的运作实况。

在开始之前,这里有一份范例报表,我们将以此份报表为蓝本开始进行教学。
(建议您将此报表列印出来和内文对照看,这样子会比较容易理解文章内容)

PHP 语法:
   1 MySQL 5.0.3              uptime 0 0:34:26       Fri Sep  1 19:46:02 2006
   2
   3 __ Key _________________________________________________________________
   4 Buffer used   380.00k of 512.00M  %Used:   0.07
   5   Current      59.32M            %Usage:  11.59
   6 Write ratio      0.93
   7 Read ratio       0.00
   8
   9 __ Questions ___________________________________________________________
  10 Total          98.06k   47.46/s
  11   DMS          81.23k   39.32/s  %Total:  82.84
  12   QC Hits      16.58k    8.02/s           16.91
  13   COM_QUIT        200    0.10/s            0.20
  14   Com_            131    0.06/s            0.13
  15   -Unknown         82    0.04/s            0.08
  16 Slow                0    0.00/s            0.00  %DMS:   0.00
  17 DMS            81.23k   39.32/s           82.84
  18   SELECT       64.44k   31.19/s           65.72         79.33
  19   INSERT       16.75k    8.11/s           17.08         20.61
  20   UPDATE           41    0.02/s            0.04          0.05
  21   REPLACE           0    0.00/s            0.00          0.00
  22   DELETE            0    0.00/s            0.00          0.00
  23 Com_              131    0.06/s            0.13
  24   change_db       119    0.06/s            0.12
  25   show_fields       9    0.00/s            0.01
  26   show_status       2    0.00/s            0.00
  27
  28 __ SELECT and Sort _____________________________________________________
  29 Scan               38    0.02/s %SELECT:   0.06
  30 Range              14    0.01/s            0.02
  31 Full join           3    0.00/s            0.00
  32 Range check         0    0.00/s            0.00
  33 Full rng join       0    0.00/s            0.00
  34 Sort scan          14    0.01/s
  35 Sort range         26    0.01/s
  36 Sort mrg pass       0    0.00/s
  37
  38 __ Query Cache _________________________________________________________
  39 Memory usage   17.81M of  32.00M  %Used:  55.66
  40 Block Fragmnt  13.05%
  41 Hits           16.58k    8.02/s
  42 Inserts        48.50k   23.48/s
  43 Prunes         33.46k   16.20/s
  44 Insrt rune    1.45:1    7.28/s
  45 Hit:Insert     0.34:1
  46
  47 __ Table Locks _________________________________________________________
  48 Waited          1.01k    0.49/s  %Total:   1.24
  49 Immediate      80.04k   38.74/s
  50
  51 __ Tables ______________________________________________________________
  52 Open              107 of 1024    %Cache:  10.45
  53 Opened            118    0.06/s
  54
  55 __ Connections _________________________________________________________
  56 Max used           77 of  600      %Max:  12.83
  57 Total             202    0.10/s
  58
  59 __ Created Temp ________________________________________________________
  60 Disk table         10    0.00/s
  61 Table              26    0.01/s
  62 File                3    0.00/s
  63
  64 __ Threads _____________________________________________________________
  65 Running            55 of   77
  66 Cache               0              %Hit:    0.5
  67 Created           201    0.10/s
  68 Slow                0    0.00/s
  69
  70 __ Aborted _____________________________________________________________
  71 Clients             0    0.00/s
  72 Connects            8    0.00/s
  73
  74 __ Bytes _______________________________________________________________
  75 Sent           38.46M  18.62k/s
  76 Received        7.98M   3.86k/s


Report Header: Line 1

    报表的第一行包含了三样不同的资讯:MySQL Server 的版本、自上次啟动后已经过多少时间、目前 Server 的日期与时间。有些人会定时让系统自动产生报表(eg. cron)然后用程序去分析进行分析,此时表头将可用来协助您辨识出不同时间点的报表。对於那些租用或使用虚拟主机的管理者,表头可以协助您了解自己所需面对的是什么样的 Server。MySQL Server 版本可以指出该 Server 有提供或没有提供那些功能,而它的 Uptime 则表示该报表具有多大的代表性。Uptime 是重要的指标,可让您了解此份报表所包含的资讯是否可能有偏误,一般来说 Uptime 最少要有一小时会比较适当,甚至光是一小时其实也还不够。例如您的 Server 可能已执行了六个小时,但此六小时皆是在使用率最低的午夜,此时产生出的报表就很不具有代表性。最理想的情况下,你会希望 MySQL Server 至少已经执行了一整天,这样子一来你就可以确定报表中的资讯已包含了 Server 负载的高峰与低峰期,而不是只包含其中之一。在范例报表中 Server 只执行了 34 分鐘,因此该报表的代表性是不足的,但因为这只是用来做范例,也就没什么关係。


Key Report: Lines 3 - 7

     第一个主要报告区块就是 Key Report,因为 Key(Indexes, 索引)是所有资讯中最重要的一项。虽然此报表无法告知您 Server 是否有善用 Index,但它可以告诉您 Server 对於 Shared Key Buffer 的使用状态。请注意,这里所指的 Key Buffer 是指 MyISAM Storage Engine 所使用的 Shared Key Buffer,InnoDB 所使用的 Key Buffer 并不包含在内。

     MySQL Server 支援许多种不同类型的资料表(比较正式的说法是 Storage Engine),你可以将它们想像为各种不同的资料结构,而不同的 Storage Engine 各有其优缺点。其中 MySQL Server 预设是使用 MyISAM Storage Engine。

    MySQL Server 的 Buffer 大略可分为二种:
    1. Global Buffer:由所有 Client 所共用的 Buffer

        key_buffer
        innodb_buffer_pool
        innodb_log_buffer
        innodb_additional_mem_pool
        net_buffer ...等等

    2. Thread Buffer:个别的 Connection 所需佔用的 Buffer

        例如:
        sort_buffer
        myisam_sort_buffer
        read_buffer
        join_buffer
        read_rnd_buffer ...等等

    计算 Server 至少需使用的总记忆体数量的方式为:
    min_memory_needed = global_buffer + (thread_buffers * max_connection)

    关於 MySQL 的 Cache 机制有一点需要特别注意,各位应该都知道 MyISAM Storage Engine 将每个 table 分成三个档案储存在硬盘之中,例如若您有一个资料表的名称为 example,那么您就会在硬盘上发现 example.FRM, example.MYD, example.MYI 等三个档案。这三个档案所储存的资料如下:

        FRM: 储存这个资料表的结构
        MYD: Row Data,也就是你存在 example 资料表里的资料
        MYI: 此资料表的索引

    接下来是重点:
    当 MySQL 要 Cache 某个资料表时,请问 MySQL 会 Cache 哪些资料?

    答案是:
    MySQL 只会 Cache 索引,也就是 *.MYI 档案,而 Row Data(*.MYD) 则是交由作业系统来负责 Cache。

    接下来我们再回到 Key Buffer,有个很重要的问题我们一直没有回答,就是『到底 Key Buffer 要设定多少才够呢?』。如前所述,MySQL 只会 Cache 索引(*.MYI),因此您只要将资料库中所有的 MYI 档案加总起来,你就会知道大概要设为多少。


Buffer used: Line 4

    身为 MySQL 的管理者您通常会问的第一个问题是:『Server 到底用掉了多少 key buffer?』。如果您发现 MySQL 只使用了一小部份的 Key Buffer,这并不是什么需要注意的问题,因为 MySQL 只会在需要的时候才实际分配与使用 System RAM。也就是说,当你设定 MySQL 可使用 512MB 的 RAM 时,并不代表 MySQL 啟动的时候将佔用 512MB 的 RAM(只有在 MySQL 认为需要这么做的时候才会)。报表中的第四行(Buffer used)指出 MySQL "曾经" 耗用过的最大记忆体数量,因此目前 "正在使用" 的记忆体数量有可能少於(甚至大於)这个数字。MySQL 称此数值为 "High Water Mark",但在报表的下一行我们将会看到它并不总是如此。无论如何,从 Buffer used 我们通常可以看出 key_buffer_size 这个系统变数值是否设定的够大,如果你的 MySQL 已经使用了 80~90% 以上的 Key Buffer,你就应该要调高 key_buffer_size。注意,Buffer used 永远不会有使用率超过 95% 的情况,因为 MySQL 的官方文件中指出 Share Key Buffer 中有部份将会挪用给内部资料结构使用,因此当 Buffer used 指出 Share Key Buffer 的使用率高达 95% 时,其实在实务上等於是已使用了 100% 的 Share Key Buffer。在这个例子中 Server 只使用了 380KB(0.07%) 的 Share Key Buffer,看到这里也许您会判断 Server 的 Share Key Buffer 是十分充足的,但请勿太早下定论,我们必须要接著考量报表中的下一行才能做出客观的判断......。


Current: Line 5

    mysqlreport 使用 Key_blocks_unused 这个系统变数来决定目前 MySQL "正在使用" 的 Share Key Buffer 大小,只有在 MySQL Server 4.1.2 以上的版本才会有这个功能。如果报表中的上一行(Buffer used)真的有如 MySQL 官方文件中所说的是 "High Water Mark",那么 Current 所载明的数值应该永远会小於或等於它。但在接下来的例子中我们将会看到,事情并不总是如此。目前这台 Server 已经使用了大约 60MB(12%) 的 Share Key Buffer,这是一个好现象因为它代表了你的 Share Key Buffer 仍然十分充足。Current 与 Buffer used 合在一起看即可提供一个很有用的指标,告诉您目前的 key_buffer_size 是否充足。

    设定 key_buffer_size 的方式也很简单,只要直接修改 MySQL 的设定档然后重新啟动 Server 即可。例如若要将 Key Buffer 设定为 2000MB,则只要在 /etc/my.cnf 中加上:
    [mysqld]
    key_buffer_size=2000M


Write ratio: Line 6

    索引(Indexes, Keys)主要是在记忆体内(RAM-Based)进行操作的,索引之所以如此有用有部份原因就归功於它们主要是在 RAM 里面运作,因此拥有极高的存取性能,不像储存在硬盘中的资料存取速度非常慢。然而,不可否认的是 MySQL 终究还是必须从硬盘中将索引读入 RAM 或是将储存在 RAM 中的索引写回硬盘之中。Write ratio 标示著 MySQL 将索引写入硬盘与 MySQL 将索引写入 RAM 的比值(Write Ratio = MySQL 将索引写入硬盘的次数 / MySQL 将索引写入 RAM 的次数)。具有接近於 1 的 Write Ratio 并不是一件很罕见的事,就像 MySQL 官方手册中所说的,如果你的 MySQL 最主要的活动是 Update、Insert 等等,那么 Write Ratio 将会很接近於 1。Write Ratio 若大於 1 表示 MySQL 将索引写入硬盘的次数大於将索引写入 RAM 的次数,很少有 MySQL Server 的 Write Ratio 会大於 1,绝大部份都应该会小於 1,即便是负载非常重的 Server。


Read ratio: Line 7

    Read Ratio 比 Write Ratio 来得重要一些,它标示了 MySQL 从硬盘读取索引与从 RAM 读取索引的比值(Read Ratio = MySQL 从硬盘读取索引的次数 / MySQL 从 RAM 读取索引的次数)。Read Ratio 的值应该要是 0.00 或 0.01,若大於这个值则表示 Server 有问题需要进一步的调查,通常此问题的成因是 Share Key Buffer 设得太小造成 MySQL 需要不断地从硬盘中读取所需要的索引资讯,而这个动作是十分没有效率的并且完全抵消了使用索引可以带来的好处。在 Server 刚啟动的头一个小时 Read Ratio 很常会出现大於 0.01 的数值,但 Server 执行过一阵子后它应该(也必须)降低至 0.01 或是 0.00。


Questions Report: Lines 9 - 26

    第二个主要的报表区块,Questions,是第二重要的资讯,因为它可以告诉你 MySQL 到底都在忙些什么事情。Questions 包含了 SQL queries 以及 MySQL protocol communications。大部份的人都只在意 Server 每秒可以处理多少查询(Queries Per Second, QPS),但若以整个 Server 的观点来考量,QPS 其实是非常不精确的数值,它无法有效的告诉您 Server 的整体运作状况。而 Questions 则提供了较完整的资讯,让您一窥 Server 的全貌。


Total: Line 10

    第一个栏位单纯的记载 MySQL 总共回应过多少查询,第二个栏位则记录回应的频率(QPS),当大部份的人说『我的 Server 平均每秒处理 XXX 个查询』时,他们指的其实就是第二个栏位所记录的回应频率。此时你应该要反问他们『在那 XXX 个查询之中,MySQL 到底做了哪些事情?』,接下来 mysqlreport 将可以协助您回答此问题......。


Distribution of Total Queries (DTQ): Lines 11 - 15

    所有的 Questions 可以大致区分为五个不同的类别:
    1.Data Manipulation Statements (DMS)
    2.query cache hits (QC Hits)
    3.COM_QUIT
    4.all other Com_ commands
    5.Unknown

    这五个类别将会展示在 Lines 11 至 15,但它们的顺序是会改变的。mysqlreport 预设是以查询的总数(第一个栏位)来排序,次数越多排得越上面,让您可以快速的分辨出 MySQL 大部份时间都在忙些什么东西。理想的情况下,你会希望 MySQL 把大部份的时间都花在 DMS 与 QC Hits 这两个类别,因为这两个类别才是真正在 "完成正事" 的类别。COM_QUIT、Com_、与 Unknown 也有其存在的必要,但它们应该只佔了其中的一小部份。在继续深入介绍之前,也许你会好奇第三个栏位是做什么用的,它代表了该分类(例如 DMS)佔全部 Queries 的百分比;若是在子分类(例如 Select)中,则表示该子分类佔所属分类(例如 DMS)的百分比。在此范例中 DMS 佔了所有 Queries 的 82.84%,这是一个很好的现象。

    Data manipulation statements(DMS) 包含了:ELECT, INSERT, REPLACE, UPDATE, 与 DELETE(技术上来说,其实不只这几个类别但 mysqlreport 只会用到这几类)。基本上,你可以将 DMS 想成是 MySQL 真正有在做些 "有用的事" 的情况,因此你会希望 DMS 是 MySQL 最忙著处理的事情。

    QC Hits 是 MySQL 不需要实际执行 Query 而只要直接从 Query Cache 中即可找到所需资料的次数。拥有高比例的 QC Hits 是让人梦寐以求的事,因为从 Query Cache 直接存取所需要的资料是十分快速且有效率的。然而大部份的 MySQL Server 因为各种原因,而无法具有非常有效率的 Query Cache。在本范例中 QC Hits 佔了所有 Questions 的 16.91%,这是非常好的情况。然而,千万不要被这个数值给误导了,在报表中的 38 至 45 行(Query Cache Report)将会告诉您完全不同的状况。这是一个很好的范例,展示了 mysqlreport 可以做为深入、相互参照与比对的分析工具。当 QC Hits 看来似乎十分完美时,这个 Server 的 Qeury Cache Report 却可以明确的告诉您其实事情没有表面上看起来的那样完美,我们在稍后会在回到这个问题。


    COM_QUIT 算是比较不重要的类别,若您不是真的很有兴趣其实您大可忽略这个类别的内容。

    COM_ 这个类别代表著所有 MySQL 所执行过的指令,通常与 MySQL protocol 相关。在正常的情况下,你会希望这个类别所佔的比例越低越好,因为当这个数值很高的时候就表示 MySQL 正忙碌於无关紧要的事情上。若这个数值很高通常代表 MySQL 正遭遇到某些很奇怪的问题,当我们深入讨论 COM_ 的子类别的时候,我们会在回来探讨这个问题。

    Unknown 是推论出来的类别,在理想的状况下,之前所述的四个分类加总起来应该要等於 Questions 总数,但它们通常不会刚好等於。这是因为有些 Questions MySQL 在处理时会增加 Total Questions 的计数器,但却没有相对应的系统变数用来记录所执行过的 Questions。在不同的 Server 上这个数值的变异很大,在有些 Server 上这个数值非常的高,在有些 Server 上则非常的低,但在大部份的情况下它应该要维持在很低的水準才是。如果这个数值非常的高,可能代表 MySQL Server 有什么地方出了问题。

Slow: Line 16

    第 16 行非常的重要:它记录了 MySQL 总共执行了多少次 Slow Query。Slow Query 就是指执行所需时间超过某个时间区间的 Query,例如执行超过 10 秒的 Query。用来判定是否为 Slow Query 的时间区间是可以透过 long_query_time 这个系统变数来设定的,MySQL 预设 long_query_time 为 10 秒,但通常我们会将它设定为 5 秒。在最理想的情况下,我们会希望看到这个数值等於零,但通常这数值不会是零。一般来说 Slow Query 佔 Total Questions 的比例应该要低於 0.05,Slow Query 的次数(第一个栏位)本身不是很重要,真正需要注意的是 Slow Query 佔 Total Questions 的比例,若这比例偏高就代表 Server 有些问题需要解决。第四个栏位中的『%DMS: 』表示 Slow Query 在所有 DMS 中所佔的比例。


DMS: Lines 17 - 22

    DMS 的子分类项目可以告诉我们,这台 MySQL Server 是属於哪一个类型的 MySQL Server,例如它是著重在 SELECT 操作或是 INSERT 操作,大部份的 MySQL Server 都是著重在 SELECT 操作。知道某台 Server 是属於哪一个类型的 MySQL Server 有助於我们思考报表中的其他资讯,例如一台著重在 SELECT 操作的 MySQL Server 的 Write Ratio 应该会非常的接近 1,并有著较高的 Lock 时间。同时它也隐含了一个意义,就是也许你可以考虑使用 InnoDB Storage Engine,因为 MySQL 预设採用的 MyISAM Storage Engine 所提供的 Lock 层级只有 Table Lock(只能针对整个资料表锁定),而 InnoDB 则提供 Row Lock 层级的锁定机制(可只针对特定的 ROW 进行锁定,减少等待时间)。若是著重在 SELECT 操作的 Server,它的 Read Ratio 应该会接近於零,并有著非常低的 Table Lock 时间。

    在范例中的 Server 是属於著重在 SELECT 操作的 Server:65.72% 的 Questions 是 SELECT(第三个栏位)、79.33% 的 DMS Questions 是 SELECT(第四个栏位)。很明显的,这是台著重在 SELECT 操作的 Server,知道了此项事实之后,我们才有办法对其进行最佳化。


Com_: Lines 23 - 26

    这个子分类只有在它的值偏高的时候才需要注意,因为过高的值表示 MySQL 正在忙著处理 "程序方面的东西",而不是回应使用者的查询。对大部份的 Server 来说这里应该都不会出现偏高的数值,但您最好还是定期的检查一下。


SELECT and Sort Report: Lines 28 - 36

    大致上来说,你只要注意第 29 行与第 31 行:Scan 与 Full Join。Scan 指的是有多少 SELECT statements 造成 MySQL 需要进行 Full Table Scan。Full Join 的意思与 Scan 差不多,但它是适用在多个 Tables 相互 Join 在一起的情况。这二种情况的执行性能都非常的差,因此原则上你会希望这两个数值越低越好。但这也不是绝对的,仍然要考虑实际的情况,例如虽然 Server 有很高比例的 Scan,但若这些 Scan 都是针对一些只有几十笔资料的 table,那么相对而言它依然是十分有效率的;但反之,若这些 Scan 是针对具有上百万笔资料的 table,那么就会严重影响系统性能。


Query Cache Report: Lines 38 - 45

    Query Cache Report 只有在 MySQL 有支援 Query Cache,以及 Query Cache 功能有开啟的情况下才会有这段资讯出现。


Memory usage: Line 39

    此项目指出 Query Cache 的使用状况,若系统已达到 Query Cache 的上限则会连带影响到 Prunes Value,因为当配给的 Memory 不足时,MySQL 必须不断地消除 RAM 中较不常使用的资料以挪出空间摆放新的资料。

你可能感兴趣的:(mysql,server,query,buffer,工具,报表)