MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选
1 、MySQL数据库的性能监控
1.1、如何查看MySQL数据库的连接数
连接数是指用户已经创建多少个连接,也就是MySQL中通过执行 SHOW PROCESSLIST命令输出结果中运行着的线程个数的详情,如图所示。
SHOW PROCESSLIST默认情况下只显示前100条记录的详情,如果超过100条后需要显示所有,可以通过执行SHOW FULL PROCESSLIST命令,如图所示。
show variables like 'max_connections'可以查询数据库中可以支持的最大连接数,如图所示。
本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
show global status like 'max_used_connections'可以查询当前已经使用过的最大连接数,如图所示。
1.2、如何查看MySQL数据库当前运行的事务与锁
事务是对数据库执行一种带有原子性、一致性、隔离性、持久性的数据操作,在MySQL中如果需要使用事务,那么数据存储时必须选用MySQL的innodb引擎,使用innodb引擎后,在MySQL系统数据库information_schema的innodb_trx表中记录了数据库当前正在运行的事务。
innodb_trx表中包含的常用字段说明如表所示。
表 innodb_trx表中包含的常用字段说明
字段 |
描述 |
trx_id |
事务ID |
trx_state |
事务的状态,一般包括RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING着几种不同的状态 |
trx_started |
事务开始运行的时间 |
trx_requested_lock_id |
事务需要等待的但已经被别的程序锁定的资源id,一般可以和INNODB_LOCKS表关联在一起获取更多的被锁定的资源的详细信息 |
trx_wait_started |
事务开始等待时间 |
trx_mysql_thread_id |
事务对应的MySQL线程id |
trx_query |
事务正在执行的SQL语句 |
trx_operation_state |
事务操作的状态 |
trx_tables_in_use |
事务使用到的数据库表的数量 |
trx_tables_locked |
事务锁定的数据库表的数量 |
trx_rows_locked |
事务锁定的数据记录行数 |
trx_rows_modified |
事务更改的数据记录行数 |
trx_unique_checks |
事务是否打开唯一性检查的标识 |
trx_foreign_key_checks |
事务是否打开外键检查的标识 |
trx_isolation_level |
事务隔离级别,一般分为Read Uncommitted(未提交读取)、Read Committed(已提交读取)、Repeatable Read(可重复读取)、Serializable(序列化)四种不同的级别 |
trx_weight |
事务的权重 |
trx_lock_memory_bytes |
事务锁住的内存大小,单位为 字节 |
trx_concurrency_tickets |
事务并发票数 |
trx_last_foreign_key_error |
事务最后一次的外键检查的错误信息 |
MySQL系统数据库information_schema的 innodb_locks表中记录了innodb数据库引擎当前产生的锁的情况, innodb_locks表中包含的常用字段说明如表所示。
字段 |
描述(本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》) |
lock_id |
锁的id |
lock_trx_id |
拥有锁的事务 ID。可以和 INNODB_TRX 表关联查询得到事务的详细信息 |
lock_mode |
锁的模式,锁的模式一般包含: 行级锁:包括S(共享锁)、X(排它锁)、IS(意向共享锁)、IX(意向排它锁)。 表级锁:包括S_GAP(共享间隙锁)、X_GAP(排它间隙锁)、IS_GAP(意向共享间隙锁)、IX_GAP(意向排它间隙锁) 和 AUTO_INC(自动递增锁) |
lock_type |
锁的类型。包括RECORD(行级锁)和TABLE(表级锁) |
lock_table |
当前被锁定的或者包含锁定记录的表的名称 |
lock_index |
当 LOCK_TYPE为RECORD 时,表示锁定的索引的名称,否则直接返回NULL |
lock_space |
当 LOCK_TYPE为RECORD 时,表示锁定行的表空间 ID,否则直接返回NULL |
lock_page |
当 LOCK_TYPE为RECORD时,表示锁定记录行的页数,否则直接返回NULL |
lock_rec |
当 LOCK_TYPE为RECORD时,表示锁定的数据行的数量 |
lock_data |
当 LOCK_TYPE为RECORD时,表示锁定记录行的主键 |
MySQL系统数据库information_schema的innodb_lock_waits表中记录了innodb数据库引擎当前运行的数据库事务等待锁的情况,innodb_lock_waits表中包含的常用字段说明如表所示。本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
表innodb_lock_waits表中包含的常用字段说明
字段 |
描述 |
requesting_trx_id |
请求事务的 ID |
Requested_lock_id |
事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表关联查询 |
Blocking_trx_id |
阻塞事务的 ID |
Blocking_lock_id |
阻塞了另一事务的运行的事务的锁的 ID |
在数据库中出现死锁时,经常需要通过查询innodb_trx、innodb_locks、innodb_lock_waits这三张表来找出在执行什么事务操作时导致了死锁,例如执行如下SQL可以列出数据库中所有事务的等待和锁定记录。
--本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html
--来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
SELECT
r.trx_isolation_level,/*事务隔离级别*/
r.trx_id AS waiting_trx_id,/*正处于等待中的事务id*/
r.trx_mysql_thread_id AS waiting_trx_thread, /*正处于等待中的数据库线程id*/
r.trx_state AS waiting_trx_state, /*正处于等待中的事务的状态*/
lr.lock_mode AS waiting_trx_lock_mode,/*正处于等待中的事务的锁定模式*/
lr.lock_type AS waiting_trx_lock_type,/*正处于等待中的事务的锁定类型*/
lr.lock_table AS waiting_trx_lock_table,/*正处于等待中的事务将锁定的表*/
lr.lock_index AS waiting_trx_lock_index,/*正处于等待中的事务将锁定的索引*/
r.trx_query AS waiting_trx_SQL,/*正处于等待中的事务将执行的SQL*/
b.trx_id AS blocking_trx_id,/*正处于锁定中的事务id*/
b.trx_mysql_thread_id AS blocking_trx_thread,/*正处于锁定中的线程id*/
b.trx_state AS blocking_trx_state,/*正处于锁定中的事务的状态*/
lb.lock_mode AS blocking_trx_lock_mode,/*正处于锁定中的事务的锁定模式*/
lb.lock_type AS blocking_trx_lock_type,/*正处于锁定中的事务的锁定类型*/
lb.lock_table AS blocking_trx_lock_table,/*正处于锁定中的事务已经锁定的表*/
lb.lock_index AS blocking_trx_lock_index,/*正处于锁定中的事务已经锁定的索引*/
b.trx_query AS blocking_sql /*正处于锁定中的事务在执行的SQL*/
FROM
information_schema.innodb_lock_waits wt
INNER JOIN information_schema.innodb_trx b
ON b.trx_id = wt.blocking_trx_id
INNER JOIN information_schema.innodb_trx r
ON r.trx_id = wt.requesting_trx_id
INNER JOIN information_schema.innodb_locks lb
ON lb.lock_trx_id = wt.blocking_trx_id
INNER JOIN information_schema.innodb_locks lr
ON lr.lock_trx_id = wt.requesting_trx_id;
1.3、MySQL中数据库表的监控
- 1、查看数据库中当前打开了哪些表: show OPEN TABLES ,如图所示。另外还可以通过show OPEN TABLES where In_use > 0过滤出当前已经被锁定的表。
- 2、查看数据库中表的状态:SHOW STATUS LIKE '%table%',如图所示。需要特别注意的是Table_locks_waited 指的是不能立即获取表级锁而需要等待的次数,如果等待的次数非常大则说明可能存在锁争抢的情况,如果是频繁的出现锁争抢则对应用程序的并发性能影响很大。
- 3、查看数据库中锁的信息:SHOW STATUS LIKE '%lock%',如图所示。
- 4、查看数据库中的表被扫描的情况:show global status like 'handler_read%',如图所示,查询的结果数据也可以用来评估数据库中索引的使用情况。查询的结果数据说明如表所示。
查询结果项 |
描述 |
Handler_read_first |
从索引中读取第一项的次数,如果该值非常高,表明服务器正在执行大量的全索引扫描,该值一般不宜太高 |
Handler_read_key |
基于键读取数据行的请求数,该值如果越高则表明大量的查询都走了索引。如果越低,表示索引的利用很低,该值一般越高越好 |
Handler_read_last |
读取索引中最后一个键的请求数 |
Handler_read_next |
按键顺序读取下一行的请求数,如果查询都走了索引,那么该值将不断递增 |
Handler_read_prev |
按键顺序读取前一行的请求数(倒序读取数据),一般用于评估执行ORDER BY … DESC的次数 |
Handler_read_rnd |
基于固定位置读取数据行的请求数,如果正在执行大量的需要对查询结果进行排序的查询,则此值很高。如果该值很高,则可能存在很多查询需要做整表扫描或者查询时一些表的关联连接没有正确使用主键或者索引 |
Handler_read_rnd_deleted |
从数据库数据文件中读取被删除记录行的请求数 |
Handler_read_rnd_next |
从数据库数据文件中读取下一行的请求数,如果SQL语句执行大量表扫描,则此值很高。如果该值很高,一般说明表没有正确添加索引或者SQL语句没有走索引来查询 |
1.4、性能测试时MySQL中其他常用监控
- 1、查看每秒事务的提交数:show global status like 'com_commit',如图所示
- 2、查看每秒事务的回滚数:show global status like 'com_rollback',如图所示
- 3、查看线程的运行情况:show global status like 'threads_%',如图所示。
查询结果描述说明如表所示。
表查询结果描述说明
查询结果项 |
描述 |
Threads_cached |
线程缓存中的线程数 |
Threads_connected |
已经建立连接的线程数 |
Threads_created |
已经创建的线程数 |
Threads_running |
正在运行中的线程数 |
- 4、查看数据库建立过的连接总数(包括连接中以及已经断开的连接):show global status like 'Connections',如图所示。
- 5、查看innodb引擎缓存命中情况:show global status like 'innodb_buffer_pool_read%',如图所示。
- 6、 查看join操作时全表扫描的次数:show global status like 'select_full_join',如图所示,该值一般可以表示SQL语句中的join操作没有走索引的次数,如果值非常大,那可能是SQL语句中的join操作存在性能问题。
- 7、 查看SQL中排序使用情况:show global status like 'sort%',如图所示
- 8、 查看SQL查询缓存的命中情况:show global status like 'qcache%',如图所示。
如果需要查询数据库查询缓存的设置,可以通过show variables like 'query_cache%'进行查看,如图所示。
备注:MySQL数据库中大部分的运行状态都可以通过show status和show global status来查看,二者的区别在于前者是查询当前的运行状态,后者是查询全局的运行状态,也就是数据库开始启动运行到现在为止的状态。
2、MySQL数据库的性能定位
2.1、慢SQL
慢SQL 一般指查询很慢的SQL语句,在MySQL数据库中,可以通过慢查询来查看所有执行超时的SQL语句,在默认情况下,一般慢SQL 是关闭的,可以通过执行show variables like 'slow_query%'来查看数据库是否开启了慢查询,如图所示。
从图中看到slow_query_log的值为OFF表示未开启,可以通过执行 set global slow_query_log=1; 或者 set global slow_query_log=ON;来临时开启慢查询,如图所示。
如果需要永久开启,需要修改/etc/my.cnf配置文件,在[mysqld]处加入如下配置,然后重启数据库即可生效,如图所示。
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/localhost-slow.log
修改完成重启数据库后,再次执行show variables like 'slow_query%',发现慢查询已经被开启,如图所示。
通过执行show variables like 'long_query%';可以查询慢查询的记录时间,如图所示,默认是10秒,可以通过执行set long_query_time=需要修改的时长;来修改慢查询的记录时间。
通过执行show status like 'slow_queries';可以查看慢查询发生的次数,如图所示。
从慢查询日志中,我们也可以看到慢查询发生的详细信息,如图所示,慢查询日志中会记录每次慢查询发生的时间、执行查询时的数据库用户、线程id、查询执行的SQL语句等信息。
本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
在获取到慢查询的SQL语句后,就可以借助数据库的执行计划来对慢查询的SQL语句做进一步分析了。
2.2、执行计划
在MySQL中使用explain关键字可以模拟查看数据库是如何来执行SQL查询语句,也就是常说的查看一条SQL语句在数据库中的执行计划,如图6-2-8所示就是执行EXPLAIN
本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
SELECT * FROM test.test 后返回的SELECT * FROM test.test查询的执行计划。
查询结果返回的字段说明如表所示
表查询结果返回的字段说明
字段 |
说明 |
id |
查询的顺序编号,表示查询中执行的顺序,id的值越大执行的优先级越高,如果id相同,则从上往下执行 |
select_type |
查询类型,常见查询类型如下: SIMPLE:表示简单查询方式,SQL语句中一般不会不使用UNION和子查询等 PRIMARY:表示当查询中包含子查询时,最外层的查询语句则被标记为primary 。 UNION:查询语句中如果在UNION关键字之后出现了第二个SELECT,则被标记为UNION。 UNION RESULT:表示查询中有多个查询结果集做UNION操作。 DEPENDENT UNION:表示子查询中存在UNION操作时,从UNION之后的第二个及之后的SELECT语句都是DEPENDENT UNION。 DEPENDENT SUBQUERY:子查询中UNION 中第一个SELECT查询为DEPENDENT SUBQUERY。 SUBQUERY:子查询内层查询的第一个SELECT。 DERIVED:查询语句中如果from子句的子查询中出现了union关键字则外层select查询将被标记为DERIVED。 MATERIALIZED:表示子查询被物化。 UNCACHEABLE SUBQUERY:表示查询结果集无法缓存的子查询,需要逐次查询。 UNCACHEABLE UNION:表示子查询不可被物化,需要逐次运行 |
Table |
查询涉及的表名或者表的别名 本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》 |
Type |
表示表连接的类型,包括的类型如下所示,如下的这些类型的性能从高到低的顺序是:null→system→const→eq-ref→ref→fulltext→ref_or_null→index_merge→unique_subquery→index_subquery→range→index→ALL null:表示不访问任何的表 system:表示表中只有一条记录,相当于系统表,一般可以认为是const类型的特例。 const:表示主键或者唯一索引的常量查询,表中最多只有1行记录符合查询要求,通常const使用到主键或者唯一索引进行定值查询、常量查询,查询的速度非常快。 eq_ref:表示join 查询过程中,关联条件字段走主键或者唯一索引,出来的行数不止一行。eq_ref是一种查询性能很高的 join 操作。 ref:表示非聚集索引的常量查询 fulltext:表示查询的过程中,使用到了 fulltext 索引。 ref_or_null:跟ref查询类似,在ref的查询基础上会多家一个null值的条件查询 index merg:表示索引联合查询, unique subquery:表示查询走主键的子查询 index subquery:表示查询走非聚集索引的子查询 range:表示查询走索引范围的查询,一般包括:=、<>、>、>=、<、<=、IS NULL、BETWEEN、IN、<=> 等范围。 index:表示通过索引做扫描查询。 All:表示全表扫描,性能最差 |
possible_keys |
查询时预计可能会使用的索引,这里说的索引只是可能会用到,实际查询不一定会用到。 |
Key |
实际查询时真实使用的索引 |
key_len |
使用的索引长度 |
Ref |
关联信息 |
Rows |
查询时扫描的数据记录行数 |
Extra |
表示查询特性的使用情况,常用的查询特性如下所示。 Using index:表示使用了索引 Using index conditio:表示使用了索引做过滤 Using MRR:表示使用了索引做内部排序 Using where:表示使用了where条件 Using temporary:表示使用了临时表。 Using filesort:表示使用文件排序,一般指无法利用索引来完成的排序 |
本文作者:张永清, 转载请注明: https://www.cnblogs.com/laoqing/p/16880718.html 来源于博客园 ,本文摘选自《软件性能测试分析与调优实践之路》
MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选的更多相关文章
- 软件性能测试分析与调优实践之路-JMeter对RPC服务的性能压测分析与调优-手稿节选
一.JMeter 如何通过自定义Sample来压测RPC服务 RPC(Remote Procedure Call)俗称远程过程调用,是常用的一种高效的服务调用方式,也是性能压测时经常遇到的一种服务调用 ...
- 软件性能测试分析与调优实践之路-Web中间件的性能分析与调优总结
本文主要阐述软件性能测试中的一些调优思想和技术,节选自作者新书<软件性能测试分析与调优实践之路>部分章节归纳. 在国内互联网公司中,Web中间件用的最多的就是Apache和Nginx这两款 ...
- 软件性能测试分析与调优实践之路-Java应用程序的性能分析与调优-手稿节选
Java编程语言自从诞生起,就成为了一门非常流行的编程语言,覆盖了互联网.安卓应用.后端应用.大数据等很多技术领域,因此Java应用程序的性能分析和调优也是一门非常重要的课题.Java应用程序的性能直 ...
- 一:MySQL数据库的性能的影响分析及其优化
MySQL数据库的性能的影响分析及其优化 MySQL数据库的性能的影响 一. 服务器的硬件的限制 二. 服务器所使用的操作系统 三. 服务器的所配置的参数设置不同 四. 数据库存储引擎的选择 五. 数 ...
- [转载]Java 应用性能调优实践
Java 应用性能调优实践 Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具 ...
- JVM性能调优实践——JVM篇
前言 在遇到实际性能问题时,除了关注系统性能指标.还要结合应用程序的系统的日志.堆栈信息.GClog.threaddump等数据进行问题分析和定位.关于性能指标分析可以参考前一篇JVM性能调优实践-- ...
- elasticsearch5.3.0 bulk index 性能调优实践
elasticsearch5.3.0 bulk index 性能调优实践 通俗易懂
- jmeter连接Mysql数据库测试性能初探
Jmeter mysql性能测试演示 1. Jmeter是java开发的,jmeter连接mysql数据库当然需要jdbc驱动,这个可以在网上下载mysql-connector-java包,然后解压 ...
- Java 应用性能调优实践
Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具和思路,给出搜狗商业平台的性 ...
随机推荐
- 总在用户态调试 C# 程序,终还是搭了一个内核态环境
一:背景 一直在用 WinDbg 调试用户态程序,并没有用它调试过 内核态,毕竟不是做驱动开发,也没有在分析 dump 中需要接触用内核态的需求,但未知的事情总觉得很酷,加上最近在看 <深入解析 ...
- 线程池:ThreadPoolExecutor源码解读
目录 1 带着问题去阅读 1.1 线程池的线程复用原理 1.2 线程池如何管理线程 1.3 线程池配置的重要参数 1.4 shutdown()和shutdownNow()区别 1.5 线程池中的两个锁 ...
- CentOS7_K8S安装指南
https://www.cnblogs.com/liu-shuai/articles/12177298.html 不能完全按照他来装,因为他装的是15.5的,15.5 有部分组件在阿里云镜像上没有,导 ...
- 一个包搞定中文数据集: datasetstore
工作中,总是要使用各种中文数据集,每次使用数据集都要花费不少的时间进行寻找,写预处理代码,结合不同的模型和框架做出相应的处理.有的时候好不容易找到合适的数据集,但是却因为网络问题,无法下载,下载了很长 ...
- vue简单的请求api并渲染到表格
环境 vue3.11 组件库 https://element-plus.gitee.io/#/zh-CN 开始 初始化一个项目 App.vue <template> <div> ...
- HCIA-STP原理与配置
STP协议生成树协议: 为了保证网络可靠,所以在组网时需要设置冗余链路和设备,从而在物理结构上形成结构,又因为交换机的工作特点导致二层网络中产生广播风暴和MAC地址表震荡现象,影响用户体验. 广播风暴 ...
- Markdowm基础语法的使用(typora)
Mackdown学习 一级标题:一个#加空格 回车 二级标题:两个#加空格 回车 以此类推... 一级标题(Ctrl+1) 二级标题(Ctrl+2) 三级标题(Ctrl+3) 四级标题(Ctrl+4) ...
- traefik的80和443端口占用进一步分析
上一篇文章地址:https://www.cnblogs.com/sanduzxcvbnm/p/14990065.html 建议先看上一篇文章,才更容易理解这篇 1.traefik的deployment ...
- NetworkPolicy网络策略以及举例说明
网络策略(NetworkPolicy)是一种关于pod间及pod与其他网络端点间所允许的通信规则的规范.NetworkPolicy 资源使用标签选择pod,并定义选定pod所允许的通信规则. 前提 网 ...
- 在 Linux 上安装服务器管理软件 Cockpit
Cockpit 是一个自由开源的服务器管理软件,它使得我们可以通过它好看的 web 前端界面轻松地管理我们的 GNU/Linux 服务器.Cockpit 使得 linux 系统管理员.系统维护员和开发 ...