MySQL之性能剖析(四)

性能剖析

使用慢查询

Percona Server对慢查询日志做了哪些改进?比如"使用SHOW PROFILE"执行相同查询后可以抓取到的结果

c 复制代码
# Time:110905 17:03:18
# User@Host:root[root] @localhost[127.0.01]
# Thread_id:7 Schema:saklia Last_errono:0 Killed:0
# Query_time:0.166872 Lock_time:0.000552 Rows_sent:997 Rows_examined:24861
  Rows_affected:0 Rows_read:997
# Bytes_sent:216528 Tmp_tables:3 Tmp_disk_tables:2 Tmp_table_sizes:11627188
# InnoDB_trx_id:191E
# QC_Hit:NO Full_scan:Yes Full_jooin:No Tmp_table:Yes Tmp_table_on_disk:Yes
# Filesort:yes Filesort_on_disk:No Merge_passes:0
# InnoDB_IO_r_ops:0 InnoDB_IO_r_bytes:0 InnoDB_IO_r_wait:0.000000
# InnoDB_rec_lock_wait:0.000000 InnoDB_queue_wait:0.000000
# InnoDB_pages_distinct:20
# PROFILE_VALUES ...Copying to tmp table:0.090623...
SET timestamp=1315256598
SELECT * FROM sakila.nice_but_slower_film_list;

从这里可以看到查询确实以供创建了三个临时表,其中两个是磁盘临时表。而SHOW PROFILE看起来则隐藏了信息(可能由于服务i去执行查询的方式有不一样地方造成的)。最后对该查询执行SHOW PROFILE的数据也会写入到日志中,所以在Percona Server中甚至可以记录SHOW PROFILE的细节信息。

另外可以看到,慢查询日志中详细记录的条目包含了SHOW PROFILE和SHOW STATUS所有的输出,并且还有更多的信息。所以通过pt-query-digest发现"坏"查询后,在慢查询日志中可以获得足够有用的信息。查看pt-query-digest的报告时其标题部分一般会有如下输出:

c 复制代码
# Query 1:0 OPS, 0x concurrency, ID0xEE758C5E0D7EADEE at byte 3214------

可以通过这里的字节偏移值(3214)直接跳转到日志的对应部分,例如用下面这样的命令即可:

c 复制代码
tail -c +3214 /path/to/query.log | head -n100

这样就可以直接跳转到细节部分了,另外pt-query-digest能够处理Percona Server在慢查询日志中增加的所有键值对,并且会自动在报告中打印更多的细节信息

使用Performance Schema

在MySQL5.5中新增的Performance Schema表还不支持查询级别的剖析信息。Performance Schema还是非常新的特性,并且还在快速开发中,未来的版本中将会包含更多的功能。尽管如此,MySQL 5.5的初始版本已经包含了狠毒偶有去的信息。例如,下面的查询显示了系统中等待的主要原因:

sql 复制代码
mysql> SELECT event_name, count_star, sum_timer_wait FROM `performance_schema`.`events_waits_summary_global_by_event_name` ORDER BY sum_timer_wait DESC LIMIT 5;

目前还有一些限制,使得Performance Schema还无法被当作一个通用的剖析工具,首先它还无法提供查询执行阶段的细节信息和计时信息,而前面提供的很多现有的工具都已经能做到这些了。其次,还没有经过长事件、大规模使用的验证,并且自身的开销也还比较大,多数比较保守的用户还对此有疑问。

最后,对大多数用户来说,直接通过Performance Schema的裸数据获得有用的结果相对来说过于复杂和底层。到目前为止实现的这个特性,主要是为了测量当为提升服务器性能而修改MySQL源代码时使用,包括等待和互斥锁。MySQL5.5中的特性读与高级用户也很有价值,而不仅仅为开发者使用。在MySQL5.6或者以后的版本中,Performance Schema将会包含更多的功能,再加上一些方便使用的工具。而且Oracle将其实现成表的形式,可以通过SQL访问,这样用户可以方便地访问有用的数据.但其目前还无法立即取代慢查询日志等其他工具用于服务器和查询的性能优化。

使用性能剖析

当获得服务器或者查询的剖析报告后,怎么使用?好的剖析报告能够将潜在的问题显示出来,但最终的解决方案还需要用户来决定(尽管报告可能会给出建议)。优化查询时,用户需要对服务器如何执行查询有较深的了解。剖析报告能够尽可能多地收集需要的信息、给出诊断问题的正确方向,以及为其他诸如EXPLAIN等工具提供基础信息。

尽管一个拥有完美测量信息的剖析报告可以i让事情变得简单,但现有系统通常都没有完美的测量支持。例如,我们虽然推断出是临时表和没有索引的读导致查询的响应事件过长,但却没有明确的证据。因为无法测量所有需要的信息,或者测量的范围不正确,有些问题就很难解决。例如,可能没有集中在需要优化的地方测量,而是测量了服务器层面的活动,或者测量的是查询开始之前的计数器,而不是查询开始后的数据。

也有其他的可能性。设想一下正在分析慢查询日志,发现了一个很简单的查询正常情况下都非常快,却有几次非常不合理地执行了很长事件。手工重新执行一遍,发现也非常快,然后使用EXPLAIN 查询其执行计划,也正确地使用了索引。然后尝试修改WHERE条件中使用不同的值,以排除缓存命中的可能,也没有发现什么问题,这可能是什么原因呢?

如果使用官方版本的MySQL,慢查询日志中没有执行计划或者详细的时间信息,对于偶尔记录到的这几次查询异常慢的问题,很难知道其原因在哪里,因为信息优先,可能是系统中有其他东西消耗了资源,比如正在备份,也可能是某种类型的所或者争用阻塞了查询的进度。

其他剖析工具

  • 1.使用USER_STATISTICS表。
    Percona Server和MariaDB都引入了一些额外的对象级别使用统计的INFORMATION_SCHEMA表,这些最初是由Google开发的。这些表对于查询服务器各部分的实际使用情况非常有帮助。在一个大型企业中,DBA负责管理数据库,但其对开发缺少话语权,那么通过这些表就可以对数据库活动那个进行测量和审计,并且强制执行使用策略。对于像共享主机环境这样的多租户环境也同样有用。另外,在查找性能问题时,这些表也可以帮助找出数据库中什么地方花费了最多的时间,或者什么表或索引表使用得最皮肤那你,抑或最不频繁,下面就是这些表:
sql 复制代码
mysql> SHOW TABLES FROM information_schema LIKE '%_STATISTICS';
+---------------------------------------------+
| Tables_in_information_schema (%_STATISTICS) |
+---------------------------------------------+
| TABLE_STATISTICS                            |
| INDEX_STATISTICS                            |
| IO_STATISTICS                               |
| PERF_STATISTICS                             |
+---------------------------------------------+
4 rows in set (0.15 sec)

有几个要点要说明一下:

1.可以查找使用得最多或者使用得最少的表和索引,通过读取次数或者更新次数,或者两者一起排序

2.可以查找出从未使用的索引,可以考虑删除之

3.可以看看复制用户的CONNECTED_TIME和BUSY_TIME,以确认复制是否会很难跟上主库的进度

  • 2.使用strace
    strace工具可以调查系统调用的情况,有好几种可以使用的方法,其中一种是计算系统调用的时间并打印出来:
c 复制代码
strace -cfp $(pidof mysqld)
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.012014           6        202        12 read
  00.00    0.000000           0          2          0 write
  00.00    0.000000           0          4          0 ioctl
  00.00    0.000000           0          1          0 mmap
------ ----------- ----------- --------- --------- ----------------
100.00    0.012014                   209        12 total

read 系统调用被调用了 202 次,总共耗时大约 0.012 秒,每次调用平均用时 6 微秒,并且有 12 次错误。

write 系统调用被调用了 2 次,没有错误发生。

ioctl 系统调用被调用了 4 次,没有错误发生。

mmap 系统调用被调用了 1 次,没有错误发生。

这种用法和oprofile有点像。但是oprofile还可以剖析程序的内部符号,而不仅仅是系统调用。另外,strace拦截系统调用使用的是不同oprofile的技术,这会有一些不可预期性,开销也更大些。strace度量时使用的实际时间,而oprofile使用的是花费CPU周期。

举个例子,当IO等待出现问题的时候,strace能将它们希纳是出来,因为它诸如read或者pread64这样的系统调用开始计时,直到调用结束。但opfile不会这样,因为IO系统调用并不会真正地消耗CPU周期,而只是等待IO完成而已。

strace对像mysqld这样有大量线程的场景会产生一些副作用。当strace附加上去后,mysqld的运行会变得很慢,因此不适合在产品环境中使用。但在某些场景下还是相当有用的,Percona Toolkit中有一个叫作pt-ioprofile的工具就是使用strace来生成IO活动的剖析报告的。

相关推荐
wqq_99225027724 分钟前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
爱上口袋的天空26 分钟前
09 - Clickhouse的SQL操作
数据库·sql·clickhouse
转世成为计算机大神30 分钟前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342731 小时前
Java实现离线身份证号码OCR识别
java·开发语言
Oak Zhang1 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
聂 可 以2 小时前
Windows环境安装MongoDB
数据库·mongodb
web前端神器2 小时前
mongodb多表查询,五个表查询
数据库·mongodb
门牙咬脆骨2 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨2 小时前
【Redis】GEO数据结构
数据库·redis·缓存
阿龟在奔跑2 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list