MySQL 服务器性能剖析
这是《高性能 MySQL(第三版)》第三章的读书笔记。
关于服务,常见的问题有:
- 如何确认服务器是否发挥了最大性能
- 找出执行慢的语句,为何执行慢
- 为何在用户端发生间歇性的停顿、卡死
通过性能剖析(profiling)分析服务器的性能并找出花费时间最多的地方,有助于解决上述问题。
1. 性能优化简介
性能通常可以认为就是响应时间(Latency,延迟),而性能优化就是减少响应时间。
要想优化性能,首先需要知道性能的瓶颈在哪里。这就需要用到测试了。
2. 性能测试
2.1 对应用程序进行性能测试
每种语言都有专门的测试程序,对于 PHP,可以使用的有:
2.2 对数据库进行性能测试
2.2.1 分析服务器负载
通过分析服务器负载,定位需要优化的单条查询。
捕获 MySQL 的查询到日志文件
MySQL 中,慢查询日志是开销最低、精度最高的测量查询时间的工具。运行时间超过 long_query_time 值语句会被记录到慢查询日志中。long_query_time 单位是秒,默认值为 10,可以设置为 0 来捕获所有的查询。慢查询日志需要手动开启,开启后会略微影响性能。慢查询日志可以写入文件或数据库,但写入到数据库时会影响性能且时间粒度退化为秒级。
MySQL 中还有另外一种查询日志,叫通用日志,但可用信息太少且资源消耗大,基本不用。
慢查询日志相关参数如下,使用可以参考 这里:
- slow_query_log:是否开启慢查询日志,1 开启,0 关闭。
- log-slow-queries:旧版(5.6以下版本)MySQL数据库慢查询日志存储路径。默认给一个缺省的文件 host_name-slow.log
- slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。默认给一个缺省的文件 host_name-slow.log
- long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。
- log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
- log_output:日志存储方式。log_output=’FILE’表示将日志存入文件,默认值是’FILE’。log_output=’TABLE’表示将日志存入数据库,这样日志信息就会被写入到 mysql.slow_log 表中。MySQL 数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output=’FILE,TABLE’。日志记录到系统的专用日志表中比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,建议优先记录到文件。
分析查询日志
分析慢查询日志可以使用 MySQL 自带的 mysqldumpslow 工具。要用慢查询日志生成分析报告可以使用 pt-query-digest 工具。
2.2.2 分析单条查询
定位到需要优化的单条查询后,开始优化。
SHOW PROFILE(以被 performance_schema 替代)
都废弃了,别研究了。
–使用前先通过 have_profiling 参数查看当前 MySQL是否支持 profile:–
mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES |
+------------------+
1 row in set, 1 warning (0.01 sec)
mysql> show warnings;
+---------+------+---------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1287 | '@@have_profiling' is deprecated and will be removed in a future release. |
+---------+------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
–默认禁用,可以通过服务器变量在会话级别启用:–
mysql> SET profiling = 1;
Performace Schema
Performace Schema 是目前 MySQL(5.7 及以上版本)主推的性能测试工具,默认开启。首次安装 MySQL 后,你会发现其默认安装了几个数据库,其中的 performace_schema 就是用于配置 Performace Schema 的。
SHOW STATUS
SHOW STATUS 命令返回一些服务器级别的全局计数器或某个会话级别的计数器。可以显示活动频繁程度,但是无法给出消耗的时间。
mysql> show global status;
+-----------------------------------------------+--------------------------------------------------+
| Variable_name | Value |
+-----------------------------------------------+--------------------------------------------------+
| Aborted_clients | 275 |
| Aborted_connects | 80872 |
| Binlog_cache_disk_use | 0 |
...
| Threads_running | 1 |
| Uptime | 6661773 |
| Uptime_since_flush_status | 6661773 |
| validate_password_dictionary_file_last_parsed | 2018-01-31 15:35:09 |
| validate_password_dictionary_file_words_count | 0 |
+-----------------------------------------------+--------------------------------------------------+
355 rows in set (0.03 sec)
2.3 诊断间歇问题
应用偶尔停顿、数据库间歇性的慢查询的可能原因有:
- 应用通过接口从运行很慢的外部服务获取数据
- memcached 中的重要缓存条目过期,导致大量请求落到 MySQL 以重新生成缓存条目
- DNS 查询偶尔超时
- 互斥锁争用或内部删除查询缓存的算法效率太低,MySQL 的查询缓存导致服务短暂停顿
- 并发度超过阈值时,InnoDB 的扩展性限制导致查询计划的优化需要很长时间
解决间歇性问题有常见的套路和工具,定位好问题才能进行之后的操作。
2.3.1 单条查询问题还是服务器问题
SHOW GLOBAL STATUS
SHOW STATUS 或 SHOW SESSION STATUS 显示当前会话级别的信息,SHOW GLOBAL STATUS 显示服务器级别的信息。完整差异可以参考 SHOW GLOBAL STATUS vs SHOW STATUS。
以较高的频率执行 SHOW GLOBAL STATUS 命令捕获数据,问题出现时可以通过某些计数器(Threads_running、Threads_connected、Questions、Queries)的“尖刺”和“凹陷”来发现问题。SHOW GLOBAL STATUS 命令的用法简单且执行时不需要特殊权限(登录数据库的用户都可以使用)、对服务器影响小。
下面示例通过 -i1
选项每秒捕捉一次数据,输出给 awk 计算并输出每秒的查询数、Threads_connected、Threads_running:
[root@VM_120_242_centos ~]# mysqladmin -uroot -p ext -i1 | awk '/Queries/{q=$4-qp;qp=$4} /Threads_connected/{tc=$4} /Threads_running/{printf "%d %d %d\n", q, tc, $4}'
Enter password:
1554866 1 1
1 1 1
1 1 1
下面示例通过 -i1
选项每秒捕捉一次数据,通过 -r
选项展示差值,输出给 awk 计算并输出每秒的查询数:
# mysqladmin -uroot -p ext -i1 -r | awk '/Queries/{q=$4} /Threads_connected/{tc=$4} /Threads_running/{printf "%d %d %d\n", q, tc, $4}'
Enter password:
1554856 1 1
1 0 0
1 0 0
1 0 0
SHOW PROCESSLIST
不停的捕获 SHOW PROCESSLIST 的输出,可以观察是否有大量线程处于不正常状态或有不正常特征。例如查询很少会长时间处于“statictics”状态。
示例,通过命令尾部使用 \G 替换分号可以垂直输出结果,通过 sort|uniq|sort
命令可以计算某个列值出现的次数:
[root@VM_120_242_centos ~]# mysql -uroot -p -e 'SHOW PROCESSLIST\G' | grep State: | sort | uniq -c | sort -rn
Enter password:
2 State:
1 State: starting
除了通过命令行外,也可以直接查询 INFORMATION_SCHEMA 数据库中的 PROCESSLIST 表。
使用查询日志
需要开启慢查询日志,并在全局级别设置 long_query_time 为 0,然后重置所有连接以使新的全局设置生效。
好的工具可以帮助诊断问题,否则就要去几百 GB 的日志文件中查找问题。下面示例的一行代码可以根据 MySQL 每秒将当前时间写入日志中的模式统计每秒的查询数量:
awk '/^# Time:/{print $3, $4, c; c=0}/^# User/{c++}' slow-query.log
理解发现的问题
建议刚开始诊断问题时,先使用 SHOW STATUS 和 SHOW PROCESSLIST。这两种方法开销低,且可以通过 shell 或反复查询来收集数据。分析慢查询日志则比较困难。
2.3.2 捕获诊断数据
诊断间歇性问题,需要收集尽可能多的数据。需要两个工具:
- 触发器,即区分问题的方法
- 收集诊断数据的工具
诊断触发器
触发器需要避免“误报”和“漏检”。
通常将触发器阈值调整为正常情况的一倍左右。比如 Threads_running 在正常情况下是 10,则触发器的阈值可以设置为 20。对于 Threads_connected 如果正常值为 150,则阈值可以是 300。
另外,还需要设置持续时间。比如 Threads_running 连续 3 秒钟超过 20,则认为是异常情况。可以使用“pt-stalk”工具。
需要收集的数据类型
确定诊断触发器后,可以开启进程收集数据。数据应该尽可能多,包括系统状态、CPU 利用率、磁盘使用率和可用空间、内存利用率、ps 命令的输出采样,以及从 MySQL 获得的信息,包括 SHOW STATUS、SHOW INNODB STATUS、SHOW PROCESSLIST。
Linux 上可用的服务器内部诊断工具有 oprofile、strace(生产环境中使用有风险)。要剖析查询可用 tcpdump。
可以通过 GDB 堆栈跟踪分析等待原因。跟踪时先启动 GDB,然后附加(attach)到 mysqld 进程,将所有线程的堆栈都存储起来。然后利用脚本汇总类似的堆栈信息,再利用 sort|uniq|sort 排序。
解释结果数据
2.3.3 案例
2.4 其他分析工具
2.4.1 USER_STATISTICS 表
INFORMATION_SCHEMA 库中的表,存储了各个数据库的信息及所有活动的统计信息,可以得知哪个数据库的哪个表、哪个索引使用的最频繁。
表索引的信息。SHOW INDEX FROM schemaname.tablename; 命令从这个表获取结果。
mysql> SHOW INDEX FROM szhuizhong.users;
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| users | 0 | PRIMARY | 1 | UserID | A | 1460 | NULL | NULL | | BTREE | | |
| users | 0 | Account_index | 1 | Account | A | 1460 | NULL | NULL | | BTREE | | |
| users | 1 | CorpID | 1 | FromID | A | 2 | NULL | NULL | YES | BTREE | | |
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
5. 总结
要解决问题,首先要搞清楚问题。所有的查询记录都要记录到日志中,然后用 pt-query-digest 工具生成系统级别的剖析报告。
MySQL 服务器性能剖析的更多相关文章
- 提升mysql服务器性能(复制原理与拓扑优化)
原文:提升mysql服务器性能(复制原理与拓扑优化) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/details/9008171 ...
- 提升mysql服务器性能(HA MMM MHA MaxScale)
原文:提升mysql服务器性能(HA MMM MHA MaxScale) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/detai ...
- 提升mysql服务器性能(索引与查询优化)
原文:提升mysql服务器性能(索引与查询优化) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/details/90138407 ...
- 提升mysql服务器性能(分库、分片与监控)
原文:提升mysql服务器性能(分库.分片与监控) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/details/90145515 ...
- 高性能MySQL(三):服务器性能剖析
select * from c LEFT JOIN c100w on c.id=c100w.id; -- 联合查询 show PROFILES; -- 查看查询耗时 select * from c; ...
- MySQL服务器基准测试
一.基准测试简介 1.什么是基准测试 数据库的基准测试是对数据库的性能指标进行定量的.可复现的.可对比的测试. 基准测试与压力测试 基准测试可以理解为针对系统的一种压力测试.但基准测试不关心业务逻辑, ...
- 11 MySQL之性能优化
01-优化简介 MySQL数据库优化是多方面的,原则是减少系统瓶颈,减少资源的占用,增加系统的反应速度. 1.通过优化文件系统,提高磁盘I\O的速写速度: 2.通过优化操作系统的调度策略,提高MySQ ...
- MySQL 高级性能优化架构 千万级高并发交易一致性系统基础
一.MySQL体系架构 由图,可以看出MySQL最上层是连接组件.下面服务器是由连接池.管理服务和工具组件.SQL接口.查询解析器.查询优化器.缓存.存储引擎.文件系统组成. 1.连接池 管理.缓冲用 ...
- MySQL性能剖析工具(pt-query-digest)【转】
这个工具同样来自percona-toolkit 该工具集合的其他工具 MySQL Slave异常关机的处理 (pt-slave-restart) 验证MySQL主从一致性(pt-table-chec ...
随机推荐
- 剑指Offer编程题(Java实现)——替换空格
题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 解题思路1 在字符串尾部填充任 ...
- SQL的“增删改”
结构语言分类 DDL(数据定义语言) create drop alter 创建删除以及修改数据库,表,存储过程,触发器,索引.... DML(数据操作语言) insert delete ...
- POJ-1502 MPI Maelstrom 迪杰斯特拉+题解
POJ-1502 MPI Maelstrom 迪杰斯特拉+题解 题意 题意:信息传输,总共有n个传输机,先要从1号传输机向其余n-1个传输机传输数据,传输需要时间,给出一个严格的下三角(其实就是对角线 ...
- CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158
CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158 //mediatek/ke ...
- [书接上一回]在Oracle Enterprise Linux (v5.7) 中安装DB - (1/4)
在上一回中,我们安装了OEL了,现在就要安装Oracle数据. 首先登录root用户,输入账号密码或,输入命令行:startx,启动图形界面. 先将虚拟机中插入光碟(Enterprise-R5-U7- ...
- Centos7 配置rsyslog客户端接收远程日志
rsyslog 因为路由器我设定每天重启,但是日志一重启就会清除,并且路由器最多只能保存1024条记录,所以我想把路由器的日志记录到一台服务器上,发现路由器包含远程日志功能 于是我就在我的centos ...
- django:一个RESTfull的接口从wsgi到函数的历程
1.wsgi将web server参数python化,封装为request对象传递给apllication命名的func对象并接受其传出的response参数,这个application在wsgi.p ...
- touch 创建空文件或改变文件的时间戳属性
1.命令功能 touch 改变文件时间属性或创建空文件. 2.语法格式 touch [option] file touch 选项 文件名 3. 选项参数说明 参数 参数说明 -a 仅改变文件的访问 ...
- 锁、volatile、CAS的比较
一.锁 锁是一种悲观的机制.为多线程提供了互斥的访问机制.多个线程同时竞争锁时,没获得锁的线程将会被挂起(智能的JVM会根据之前获取锁操作中对锁的持有时间长短来判断是使线程挂起还是自旋) 锁的劣势:1 ...
- Java实现代理服务器
Web代理(proxy)服务器是网络的中间实体. 代理位于Web客户端和Web服务器之间,扮演"中间人"的角色. HTTP的代理服务器即是Web服务器又是Web客户端. 代理服务器 ...