01-monitor
frame 英 /freɪm, 框架;
schema 英 [ˈskiːmə] n. (计划或理论的)提要,纲要
- 99_install_binary.md
- 97_install_rpm.md
- 98_uninstall_rpm.md
- mysql_官网
- Chapter 27 MySQL Performance Schema
- 各种连接池性能对比测试
- druid_常见问题
1. 基础
- 结合公司之前的应用场景来阐述有关调优的问题
1. Server架构,三层
- Client
- Server
- 连接器
- 采用数据库连接池,减少频繁的开关连接
- 分析器(开发能操作)
- 词法分析,语法分析
- 优化器。自带一定优化(开发能操作)
- RBO:基于规则优化
- CBO:基于成本(代价)优化
- 执行器。
select *
是有大问题(IO) - 缓存器。mysql8.0后废除
- 连接器
- Engine存储引擎
- InnoDB:磁盘
- MyISAM:磁盘
- Memory:内存
2. 文件存放
# mac_mysql_data目录
sudo chmod -R a+rwx /usr/local/mysql/data
- InnoDB
- 默认情况下所有数据文件放到表空间中,不会为每个表保存一份数据文件。
set global innodb_file_per_table=on
开启为每个表单独文件保存
.frm
:表结构.ibd
:data和index(聚簇索引)数据文件和索引文件存放在一起
- 默认情况下所有数据文件放到表空间中,不会为每个表保存一份数据文件。
- MyISAM
.frm
:表结构.MYI
:index文件.MYD
:data文件
3. 优化目标(IO)
- 减少IO量
- 减少IO次数
2. profile
- 客户端不能profile,客户端一个查询执行了太多其他sql了
- Mysql8.0取消了
- sql的duration精确到小数点后8位
# 调用mac本地mysql
/usr/local/mysql/bin/mysql -u root -p
# 查看所有db
show databases;
# 切换db
use mca;
# 查询profiling
show variables like 'profiling%';
# 配置耗时,开启profiling功能
set profiling = 1;
# 可以查询到具体sql详细时间
show profiles;
# sql每个阶段具体耗时(默认最近一条sql)
show profile;
# 指定sql,执行具体耗时
show profile for query 2;
-- -----------------------------------------------
# all:显示所有性能信息
show profile all for query 1;
# block io:显示块io操作的次数
show profile block io for query 1;
# context switches:显示上下文切换次数,被动和主动
show profile context switches for query 1;
# cpu:显示用户cpu时间、系统cpu时间
show profile cpu for query 1;
# IPC:显示发送和接受的消息数量
show profile ipc for query 1;
# page faults:显示页错误数量
show profile page faults for query 1;
# source:显示源码中的函数名称与位置
show profile source for query 1;
# swaps:显示swap的次数
show profile swaps for query 1;
starting, Sending data
耗时多,是正常的sql
3. performance_schema
- Chapter 27 MySQL Performance Schema
- 20个小章节来指导你如何用
performance_schema
1. 特点
performance_schema用于监控MySQL_Server在一个较低级别的运行过程中的资源消耗、资源等待等情况
- 实时检查mysql_server的内部执行情况
performance_schema
:使用performance_schema存储引擎。该数据库主要关注数据库运行过程中的性能数据information_schema
:Server运行过程中的元数据信息
- 通过监视Server的事件来监视Server内部运行情况
- ”事件“就是Server内部活动中所做的任何事情以及对应的时间消耗,利用这些信息来判断Server中的相关资源消耗在了哪里
- 一般来说,事件可以是函数调用、OS等待、SQL执行的阶段(parsing或sorting阶段)或者整个SQL语句与SQL语句集合。事件的采集可以方便的提供Server中的相关存储引擎对磁盘文件、表I/O、表锁等资源的同步调用信息
performance_schema
存储引擎使用Server源代码中的检测点来实现事件数据的收集。实现机制本身的代码没有相关的单独线程来检测,这与其他功能(如复制或事件计划程序)不同- 事件与写入二进制日志中的事件(描述数据修改的events)、事件计划调度程序(这是一种存储程序)的事件不同
- 记录Server执行某些活动对某些资源的消耗、耗时、这些活动执行的次数等情况
- 事件只记录在本地Server的
performance_schema
中,其下的这些表中数据发生变化时不会被写入binlog
中,也不会通过复制机制被复制到其他Server中 - 当前活跃事件、历史事件、事件摘要相关的表中记录的信息。能提供某个事件的执行次数、使用时长。进而可用于分析某个特定线程、特定对象(mutex或file)相关联的活动
- 收集的事件数据存储在
performance_schema
数据库的表中。这些表可以使用select语句查询,也可以使用SQL语句更新performance_schema
数据库中的表记录- (动态修改
performance_schema
的setup_*开头的几个配置表,但要注意:配置表的更改会立即生效,这会影响数据收集)
- (动态修改
performance_schema
的表中的数据不会持久化存储在磁盘中,而是保存在内存中,一旦服务器重启,这些数据会丢失(包括配置表在内的整个performance_schema
下的所有数据)- Mysql支持的所有平台中事件监控功能都可用,但不同平台中用于统计事件时间开销的《计时器类型》可能会有所差异
2. 开启
- Mysql的5.7版本,性能模式是默认开启的
- 显式关闭的话需要修改配置文件,不能直接进行修改,报错:
Variable 'performance_schema' is a read only variable
show databases;
# 切换数据库
use performance_schema;
# 87张表
show tables;
# 开关
show variables like 'performance_schema';
# 'performance_schema', 'ON'
# 只读无法设置,配置文件修改
set performance_schema = off;
# [HY000][1238] Variable 'performance_schema' is a read only variable
# 查看表结构
show create table setup_consumers;
-- ---------------------------------------------------------------
create table setup_consumers
(
NAME varchar(64) not null,
ENABLED enum ('YES', 'NO') not null
)
engine = PERFORMANCE_SCHEMA;
# 修改配置文件
cd /etc/
vi my.cnf
# performance_schema,ON开启,OFF关闭
[mysqld]
performance_schema=ON
理解两个基本概念:
- instruments生产者:采集Mysql中各种各样event_info,对应配置表中的配置项称为《event_info采集配置项》
- 采集项的配置表中每一项都有一个开关字段(YES,NO)
- consumers消费者:存储Mysql中各种各样event_info,对应配置表中的配置项称为《event_info存储配置项》
- 存储项的配置表中每一项都有一个开关字段(YES,NO)
3. 表的分类(87张)
# 监视不同的纬度进行分组
use performance_schema;
# 聚合后的摘要表summary
# summary表还可以根据帐号(account)、主机(host)、程序(program)、线程(thread)、用户(user)和全局(global)再进行细分
# 《语句事件记录表》这些表记录了语句事件信息
# 《当前语句事件表》events_statements_current
# 《历史语句事件表》events_statements_history
# 《长语句历史事件表》events_statements_history_long
show tables like '%statement%';
# 《等待事件记录表》与语句事件类型的相关记录表类似
show tables like '%wait%';
# 《阶段事件记录表》记录语句执行的阶段事件的表
show tables like '%stage%';
# 《事务事件记录表》记录事务相关的事件的表
show tables like '%transaction%';
# 监控文件系统层调用的表
show tables like '%file%';
# 监控内存使用的表
show tables like '%memory%';
# 动态对performance_schema进行配置的配置表
show tables like '%setup%';
4. 简单配置与使用
- DB刚刚初始化并启动时,并非所有
instruments
和consumers
都启用了,所以默认不会收集所有的事件(因MySQL版本而异)
use performance_schema;
# 查看所有配置开关
select * from setup_instruments;
select * from setup_consumers;
# 打开《等待event_info采集配置项》开关
update setup_instruments set enabled = 'YES', timed = 'YES' where name like 'wait%';
# 打开《等待event_info存储配置项》开关
update setup_consumers set enabled = 'YES' where name like '%wait%';
# _current表中每个线程只保留一条记录,一旦线程完成工作,该表中不会再记录该线程的事件信息
# events_waits_current,该表中每个线程只包含一行数据,用于显示每个线程的最新监视事件
select * from events_waits_current;
*************************** 1. row ***************************
THREAD_ID: 11
EVENT_ID: 570
END_EVENT_ID: 570
EVENT_NAME: wait/synch/mutex/innodb/buf_dblwr_mutex
SOURCE:
TIMER_START: 4508505105239280
TIMER_END: 4508505105270160
TIMER_WAIT: 30880
SPINS: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
INDEX_NAME: NULL
OBJECT_TYPE: NULL
OBJECT_INSTANCE_BEGIN: 67918392
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
OPERATION: lock
NUMBER_OF_BYTES: NULL
FLAGS: NULL
# 该信息表示线程id为11的线程正在等待buf_dblwr_mutex锁,等待事件为30880
# 属性说明:
# id: 事件来自哪个线程,事件编号是多少
# event_name: 检测到的具体的内容
# source: 这个检测代码在哪个源文件中以及行号
# timer_start: 该事件的开始时间
# timer_end: 该事件的结束时间
# timer_wait: 该事件总的花费时间
# _history表:记录每个线程应该执行完成的事件信息,但每个线程的事件信息只会记录10条,再多就会被覆盖
# _history_long表:记录所有线程的事件信息,但总记录数量是10000,超过就会被覆盖掉
select thread_id, event_id, event_name, timer_wait from events_waits_history order by thread_id limit 21;
# _summary_表:提供所有事件的汇总信息,该组中的表以不同的方式汇总事件数据(如:按用户、主机、线程等等)
# eg:要查看哪些instruments占用最多的时间,可以通过对events_waits_summary_global_by_event_name表的COUNT_STAR或SUM_TIMER_WAIT列进行查询
# (这两列是对事件的记录数执行COUNT(*)、事件记录的TIMER_WAIT列执行SUM(TIMER_WAIT)统计而来)
SELECT EVENT_NAME, COUNT_STAR FROM events_waits_summary_global_by_event_name ORDER BY COUNT_STAR DESC LIMIT 10;
# _instance表:记录了哪些类型的对象会被检测。这些对象在被server使用时,在该表中将会产生一条事件记录
# eg:file_instances表列出了文件I/O操作及其关联文件名
select * from file_instances limit 20;
5. 常用配置项说明
1. 启动选项
# 启动之后也可以在setup_consumers表中使用UPDATE语句进行动态更新配置项
# 开机启动events_statements_current表的记录功能(该表记录当前的语句事件信息),默认值为TRUE
performance_schema_consumer_events_statements_current=TRUE
# 类似上,配置是否记录语句事件短历史信息,默认为TRUE
performance_schema_consumer_events_statements_history=TRUE
# 类似上,配置是否记录语句事件长历史信息,默认为FALSE
performance_schema_consumer_events_stages_history_long=FALSE
# 除了statement(语句)事件之外,还支持:wait(等待)事件、state(阶段)事件、transaction(事务)事件,他们与statement事件一样都有三个启动项分别进行配置,
# 但这些等待事件默认未启用,如果需要在MySQL_Server启动时一同启动,则通常需要写进my.cnf配置文件中
# 开机启动全局表(eg:mutex_instances、rwlock_instances、cond_instances、file_instances、users、hostsaccounts、
# socket_summary_by_event_name、file_summary_by_instance等大部分的全局对象计数统计和事件汇总统计信息表)的记录功能,默认值为TRUE
performance_schema_consumer_global_instrumentation=TRUE
# 开机启动events_statements_summary_by_digest表的记录功能,,默认值为TRUE
performance_schema_consumer_statements_digest=TRUE
# 开机启动
performance_schema_consumer_thread_instrumentation=TRUE
# events_xxx_summary_by_yyy_by_event_name表的记录功能,默认值为TRUE
performance_schema_instrument[=name]
# 开机启动某些采集器,由于instruments配置项多达数千个,所以该配置项支持key-value模式,还支持%号进行通配等,如下:
# [=name]可以指定为具体的Instruments名称(但是这样如果有多个需要指定的时候,就需要使用该选项多次),
# 也可以使用通配符,可以指定instruments相同的前缀+通配符,也可以使用%代表所有的instruments
# 指定开启单个instruments
--performance-schema-instrument= 'instrument_name=value'
# 使用通配符指定开启多个instruments
--performance-schema-instrument= 'wait/synch/cond/%=COUNTED'
# 开关所有的instruments
--performance-schema-instrument= '%=ON'
--performance-schema-instrument= '%=OFF'
# 注意,这些启动选项要生效的前提是,需要设置performance_schema=ON。
# 另外,这些启动选项虽然无法使用`show variables`语句查看,但可以通过setup_instruments和setup_consumers表查询这些选项指定的值
2. 系统变量
show variables like '%performance_schema%';
# performance_schema功能的开关
# 5.7.x版本之前默认关闭,5.7.x版本开始默认开启
# 注意:如果mysqld在初始化performance_schema时发现无法分配任何相关的内部缓冲区,则performance_schema将自动禁用,并将performance_schema设置为OFF
performance_schema=ON
# 控制events_statements_summary_by_digest表中的最大行数
# 如果产生的语句摘要信息超过此最大值,便无法继续存入该表,此时performance_schema会增加状态变量
performance_schema_digests_size=10000
# 控制events_statements_history_long表中的最大行数
# 该参数控制所有会话在events_statements_history_long表中能够存放的总事件记录数,超过这个限制之后,最早的记录将被覆盖
# 全局变量,只读变量,整型值,5.6.3版本引入
# 5.6.x版本中,5.6.5及其之前的版本默认为10000,5.6.6及其之后的版本默认值为-1,通常情况下,自动计算的值都是10000
# 5.7.x版本中,默认值为-1,通常情况下,自动计算的值都是10000
performance_schema_events_statements_history_long_size=10000
# events_statements_history表中单个线程(会话)的最大行数
# 控制单个会话在events_statements_history表中能够存放的事件记录数,超过这个限制之后,单个会话最早的记录将被覆盖
# 全局变量,只读变量,整型值,5.6.3版本引入
# 5.6.x版本中,5.6.5及其之前的版本默认为10,5.6.6及其之后的版本默认值为-1,通常情况下,自动计算的值都是10
# 5.7.x版本中,默认值为-1,通常情况下,自动计算的值都是10
# 除了statement(语句)事件之外,wait(等待)事件、state(阶段)事件、transaction(事务)事件,与statement事件一样都有三个参数分别进行存储限制配置
performance_schema_events_statements_history_size=10
# 用于控制标准化形式的SQL在存入performance_schema的限制长度,该变量与max_digest_length变量相关(max_digest_length变量含义请自行查阅相关资料)
# 全局变量,只读变量,默认值1024字节,整型值,取值范围0~1048576
performance_schema_max_digest_length=1024
# 控制存入events_statements_current、events_statements_history和events_statements_history_long语句事件表中的SQL_TEXT列的最大SQL长度字节数。
# 超出系统变量performance_schema_max_sql_text_length的部分将被丢弃,不会记录,一般情况下不需要调整该参数,除非被截断的部分与其他SQL比起来有很大差异
# 全局变量,只读变量,整型值,默认值为1024字节,取值范围为0~1048576,5.7.6版本引入
# 降低该值可以减少内存使用,但如果汇总的SQL中,被截断部分有较大差异,会导致没有办法再对这些有较大差异的SQL进行区分。
# 增加该值会增加内存使用,但对于汇总SQL来讲可以更精准地区分不同的部分。
performance_schema_max_sql_text_length=1024
6. 配置表相互关系
- 在
performance_schema
库中还包含了很多其他的库、表,对DB的性能做完整监控,参考官网详细了解 - 配置表之间相互关联关系,按照配置影响的先后顺序,可添加为
# 记录了server中有哪些可用的事件计时器
# 字段解释:
# timer_name:表示可用计时器名称,CYCLE是基于CPU周期计数器的定时器
# timer_frequency:表示每秒钟对应的计时器单位的数量,CYCLE计时器的换算值与CPU的频率相关、
# timer_resolution:计时器精度值,表示在每个计时器被调用时额外增加的值
# timer_overhead:表示在使用定时器获取事件时开销的最小周期值
select * from performance_timers;
# 记录当前使用的事件计时器信息
# 字段解释:
# name:计时器类型,对应某个事件类别
# timer_name:计时器类型名称
select * from setup_timers;
# 列出了consumers可配置项
# 字段解释:
# NAME:consumers配置名称
# ENABLED:consumers是否启用,有效值为YES或NO,此列可以使用UPDATE语句修改
select * from setup_consumers;
# 列出了instruments可配置项,即代表了哪些事件支持被收集
# 字段解释:
# NAME:instruments名称,可能具有多个部分并形成层次结构
# ENABLED:instrumetns是否启用,有效值为YES或NO,此列可以使用UPDATE语句修改。如果设置为NO,则这个instruments不会被执行,不会产生任何的事件信息
# TIMED:instruments是否收集时间信息,有效值为YES或NO,此列可以使用UPDATE语句修改,如果设置为NO,则这个instruments不会收集时间信息
SELECT * FROM setup_instruments;
# setup_actors表的初始内容是匹配任何用户和主机,因此对于所有前台线程,默认情况下启用监视和历史事件收集功能
# 字段解释:
# HOST:与grant语句类似的主机名,一个具体的字符串名字,或使用“%”表示“任何主机”
# USER:一个具体的字符串名称,或使用“%”表示“任何用户”
# ROLE:当前未使用,MySQL 8.0中才启用角色功能
# ENABLED:是否启用与HOST,USER,ROLE匹配的前台线程的监控功能,有效值为:YES或NO
# HISTORY:是否启用与HOST, USER,ROLE匹配的前台线程的历史事件记录功能,有效值为:YES或NO
SELECT * FROM setup_actors;
# 控制performance_schema是否监视特定对象。默认情况下,此表的最大行数为100行
# 字段解释:
# OBJECT_TYPE:
# instruments类型,有效值为:“EVENT”(事件调度器事件)、“FUNCTION”(存储函数)、“PROCEDURE”(存储过程)、“TABLE”(基表)、“TRIGGER”(触发器),
# TABLE对象类型的配置会影响表I/O事件(wait/io/table/sql/handler instrument)和表锁事件(wait/lock/table/sql/handler instrument)的收集
# OBJECT_SCHEMA:某个监视类型对象涵盖的数据库名称,一个字符串名称,或“%”(表示“任何数据库”)
# OBJECT_NAME:某个监视类型对象涵盖的表名,一个字符串名称,或“%”(表示“任何数据库内的对象”)
# ENABLED:是否开启对某个类型对象的监视功能,有效值为:YES或NO。此列可以修改
# TIMED:是否开启对某个类型对象的时间收集功能,有效值为:YES或NO,此列可以修改
SELECT * FROM setup_objects;
# 对于每个server线程生成一行包含线程相关的信息,
# 字段解释:
# THREAD_ID:线程的唯一标识符(ID)
# NAME:与server中的线程检测代码相关联的名称(注意,这里不是instruments名称)
# TYPE:线程类型,有效值为:FOREGROUND、BACKGROUND。分别表示前台线程和后台线程
# PROCESSLIST_ID:对应INFORMATION_SCHEMA.PROCESSLIST表中的ID列
# PROCESSLIST_USER:与前台线程相关联的用户名,对于后台线程为NULL
# PROCESSLIST_HOST:与前台线程关联的客户端的主机名,对于后台线程为NULL
# PROCESSLIST_DB:线程的默认数据库,如果没有,则为NULL
# PROCESSLIST_COMMAND:对于前台线程,该值代表着当前客户端正在执行的command类型,如果是sleep则表示当前会话处于空闲状态
# PROCESSLIST_TIME:当前线程已处于当前线程状态的持续时间(秒)
# PROCESSLIST_STATE:表示线程正在做什么事情
# PROCESSLIST_INFO:线程正在执行的语句,如果没有执行任何语句,则为NULL
# PARENT_THREAD_ID:如果这个线程是一个子线程(由另一个线程生成),那么该字段显示其父线程ID
# ROLE:暂未使用
# INSTRUMENTED:线程执行的事件是否被检测。有效值:YES、NO
# HISTORY:是否记录线程的历史事件。有效值:YES、NO *
# THREAD_OS_ID:由操作系统层定义的线程或任务标识符(ID)
select * from threads;
7. 实践
# 1. 哪类的sql执行最多?
select digest_text, count_star, first_seen, last_seen
from events_statements_summary_by_digest
order by count_star desc;
# 2. 哪类sql的平均响应时间最多?
select digest_text, avg_timer_wait
from events_statements_summary_by_digest
order by count_star desc;
# 3. 哪类sql排序记录数最多?
select digest_text, sum_sort_rows
from events_statements_summary_by_digest
order by count_star desc;
# 4. 哪类sql扫描记录数最多?
select digest_text, sum_rows_examined
from events_statements_summary_by_digest
order by count_star desc;
# 5. 哪类sql使用临时表最多?
select digest_text, sum_created_tmp_tables, sum_created_tmp_disk_tables
from events_statements_summary_by_digest
order by count_star desc;
# 6. 哪类sql返回结果集最多?
select digest_text, sum_rows_sent
from events_statements_summary_by_digest
order by count_star desc;
# 7. 哪个表物理IO最多?
select file_name, event_name, sum_number_of_bytes_read, sum_number_of_bytes_write
from file_summary_by_instance
order by sum_number_of_bytes_read + sum_number_of_bytes_write desc;
# 8. 哪个表逻辑IO最多?
select object_name, count_read, count_write, count_fetch, sum_timer_wait
from table_io_waits_summary_by_table
order by sum_timer_wait desc;
# 9. 哪个索引访问最多?
select object_name, index_name, count_fetch, count_insert, count_update, count_delete
from table_io_waits_summary_by_index_usage
order by sum_timer_wait desc;
# 10. 哪个索引从来没有用过?
select object_schema, object_name, index_name
from table_io_waits_summary_by_index_usage
where index_name is not null
and count_star = 0
and object_schema <> 'mysql'
order by object_schema, object_name;
# 11. 哪个等待事件消耗时间最多?
select event_name, count_star, sum_timer_wait, avg_timer_wait
from events_waits_summary_global_by_event_name
where event_name != 'idle'
order by sum_timer_wait desc;
# 12-1. 剖析某条sql的执行情况,包括statement信息、stege信息、wait信息
select event_id, sql_text
from events_statements_history
where sql_text like '%count(*)%';
# 12-2. 查看每个阶段的时间消耗
select event_id, event_name, source, timer_end - timer_start
from events_stages_history_long
where nesting_event_id = 1553;
# 12-3. 查看每个阶段的锁等待情况
select event_id,
event_name,
source,
timer_wait,
object_name,
index_name,
operation,
nesting_event_id
from events_waits_history_long
where nesting_event_id = 1553;
4. processlist
# 查看mysql数据库连接。id即为thread_id,kill该id即断开连接
show processlist;
# 写代码一定要关闭数据库连接
5. 连接池
- dbcp,没人用了
- c3p0
- durid
- HikariCP,号称“性能杀手”,只是查询快,PSCache不支持,ExceptionSorter不支持