为了排查问题,对数据库的监控是必不可少的,在此介绍下 MySQL 中的常用监控指标。
简介
MySQL 有多个分支版本,常见的有 MySQL、Percona、MariaDB,各个版本所对应的监控项也会有些区别,在此仅介绍一些通用的监控项。
通常,监控项的源码是在 mysql/mysqld.cc 文件中定义,其内容如下所示。
监控
对于数据库,通常可以主动监控以下四个与性能及资源利用率相关的指标:
- 查询吞吐量
- 查询执行性能
- 连接情况
- 缓冲池使用情况
吞吐量
在 MySQL 中有各种针对不同命令的统计,其监控项指标以 Com_XXX 方式命名,其中比较常用的统计项包括了 TPS/QPS。
而 MySQL 与 QPS 相关的包括了三个监控项,分别为 Queries、Questions、Com_select,一般会采用 Com_select 作为采集项;对于 TPS,一般认为是 Com_insert + Com_update + Com_delete 三个统计项的和。
Queries 和 Questioins 区别
如下是 Server Status Variables 中对这两个值的介绍。
也就是说,如果不使用 prepared statements ,那么两者的区别是 Questions 会将存储过程作为一个语句;而 Queries 会统计存储过程中的各个执行的语句。
上述的 questions 是会话级别的,当然可以通过 global 查看全局的变量。
另外,MySQL 会在执行 SQL 之前开始增加上述的统计计数;而当前正在执行的 SQL 数量则可以通过 threads_running 查看。
总结
执行性能
目前,有几种方式可以用来查看 MySQL 的执行性能问题,可以参考如下。
在 events_statements_summary_by_digest 表中保存了许多关键指标,均以微秒为单位,该表会忽略数值、规范化空格与大小写。
如果要以微秒为单位查看各个 database 的平均运行时间,或者出现的错误语句总数,可以通过如下方式查看:
sys
sys 存储引擎默认在 5.7.7 中添加,对于 5.6 可以手动安装,详细可以参考 github - sys schema 。
慢查询
MySQL 提供了一个 Slow_queries 计数器,当查询的执行时间超过 long_query_time 参数指定的值之后,该计数器就会增加,默认设置为 10 秒。
需要注意的是,需要关闭会话然后重新连接之后,才能使该参数生效。
总结
其它的一些比较适合发现性能问题后用于排查。
连接情况
监控客户端连接情况相当重要,因为一旦可用连接耗尽,新的客户端连接就会遭到拒绝,MySQL 默认的连接数限制为 151,可通过下面的方法在配置文件中进行设置。
通过如下方法查询和临时设置。
通常 Linux 可以处理 500~1000 个连接,如果 RAM 资源足够,可处理 1W+ 个连接,而 Windows 由于采用 Posix 兼容层,能处理的连接数一般不超过 2048 个。
监控连接使用率
如果采用每个连接一个线程的方式,可以通过 Threads_connected 查看,监控该指标与先前设置的连接限制,可以确保服务器拥有足够的容量处理新的连接。
另外,通过 Threads_running 指标,可以查看正在处理请求的线程,可以用来判断那些连接被占用但是却没有处理任何请求。
如果达到 max_connections 就会拒绝新的连接请求,Connection_errors_max_connections 指标就会开始增加,同时,追踪所有失败连接尝试的 Aborted_connects 指标也会开始增加。
另外,通过 Connection_errors_internal 这个指标,可以用来监控来自服务器本身导致的错误,例如内存不足。
总结
缓冲池使用情况
InnoDB 使用一片内存区域作为缓冲区,用来缓存数据表与索引数据,缓冲区太小可能会导致数据库性能下滑,磁盘 I/O 攀升。
默认值一般是 128MiB,建议将其设置为物理内存的 80%;不过需要注意的是,InnoDB 可能会使用超过缓冲池 10%,如果耗尽内存,则会使用分页,从而使数据库性能受损。
如果 innodb_buffer_pool_chunk_size 查询没有返回结果,则表示在你使用的 MySQL 版本中此参数无法更改,其值为 128 MiB,实际参数为 innodb_buffer_pool_size 。
在服务器启动时,你可以这样设置缓冲池的大小以及实例的数量:
监控指标
Innodb_buffer_pool_read_requests 记录了读取请求的数量,而 Innodb_buffer_pool_reads 记录了缓冲池无法满足,因而只能从磁盘读取的请求数量,也就是说,如果 Innodb_buffer_pool_reads 的值开始增加,意味着数据库性能大有问题。
缓存的使用率和命中率可以通过如下方法计算:
如果数据库从磁盘进行大量读取,而缓冲池还有许多闲置空间,这可能是因为缓存最近才清理过,还处于预热阶段。
总结
响应时间
“响应时间” (Response Time, RT) 在数据库应用中,尤其是 OLTP 的场景,非常重要,但官方版本中一直没有加上这个统计功能。开始使用的是 tcpdump+mk-query-digest,再后来 tcprstat,很快 Percona 提供了响应时间统计插件。
对于 MariaDB 也存在类似的方式,可以通过如下的方式安装、测试。
默认的时间统计区间是按照基数 10 增长的,也就是说默认的区间如下:
可以通过修改参数 query_response_time_range_base 来缩小时间区间,默认该是 10,实际的统计时间区间如上,可以修改为 2,则区间如下:
第一个区间总是最接近 0.000001 的区间开始;最后区间是到最接近且小于 10000000 处结束。
当然,有些比较从网上摘录的不错 SQL,可以根据自己需求修改。
其它监控项
除了上述的监控项,常见的还有如下常用的方法。
1. 是否可用
可以使用如下几条命令来查看当前 MySQL 服务是否处于运行状态。
2. 用户管理
严禁对用户的 “host” 部分采用 “%”,除非你想从世界任何一个地方登陆;默认不要使用 GRANT ALL ON . 给用户过度赋权,
3. 连接数是否正常
主要查看客户是否有由于没正确关闭连接而死掉的连接,有多少失败的连接,是否有恶意连接等。
4. 慢查询日志
慢查询日志对 SQL 调优来说是非常重要的,它记录了超过指定时间 long_query_time 的查询语句;一般只在需要时开启。
MyISAM
在对 MyISAM 存储引擎调优时,很多文章推荐使用 Key_read_requests 和 Key_reads 的比例作为调优的参考,来设置 key_buffer_size 参数的值,而实际上这是错误的,详细可以参考 Why you should ignore MySQL’s key cache hit ratio 这篇文章。
简单介绍如下。
rate VS. ratio
首先需要注意的是,这里有两个重要的概念:”miss rate” 一般是每秒 miss 的数目;”miss ratio” 表示从磁盘读取和从 cache 读取的比例,该参数没有单位。
如下的两个参数可以通过 SHOW GLOBAL STATUS 命令查看,官方文档的解释如下。
也就是说,两者分别对应了:A) 从缓存读取索引的请求次数;B) 从磁盘读取索引的请求次数。
NOTE: 实际上,Key_reads 统计的并非严格意义上的读磁盘,严格来说应该是发送系统请求的次数。如果文件系统中有缓存的话,实际耗时就是系统调用,并没有磁盘读取的耗时。
很多人认为 Key_reads/Key_read_requests 越小越好,否则就应该增大 key_buffer_size 的设置,但通过计数器的比例来调优有两个问题:
- 比例并不显示数量的绝对值大小,并不知道总共的请求有多少;
- 计数器并没有考虑时间因素。
假设有两台机器,其 miss ratio 分别为 23% 和 0.1% ,因为没有读的请求量,很难判断那台机器需要进行调优。比如,前者是 23/100,后者则是 10K/10M 。
参数指标
虽说 Key_read_requests 大比小好,但是对于系统调优而言,更有意义的应该是单位时间内的 Key_reads,通常可以通过 Key_reads / Uptime 计算;该参数可以通过如下命令得到:
其中第一行表示的是系统启动后的总请求,在此可以忽略,下面的每行数值都表示 10 秒内的数据变化,这样就可以大致评估每秒有多少的磁盘请求,而且可以根据你的磁盘性能进行评估是否合理。
NOTE: 命令里的 mysqladmin ext 其实就是 mysqladmin extended-status,你甚至可以简写成 mysqladmin e 。
结论
通过 Key_reads / Uptime 替换 Key_reads / Key_read_requests 。
参考
可以参考官方文档 Reference Manual - Server Status Variables,主要介绍各个监控项的含义。
Monitoring MySQL performance metrics,一篇很不错的介绍 MySQL 监控项文章,包括上述的吞吐量、执行性能、链接情况、缓冲池使用情况等。
Why you should ignore MySQL’s key cache hit ratio 这篇文章介绍了 MyISAM 缓存的调优,其中的思想其它参数也可以考虑,也可以参考 本地文档 。