23 MySQL Performance Schema
23.9.4.1 events_waits_current表
23.9.4.2 Events_waits_history表
23.9.4.3 events_waits_history_long 表
23.9.5.1 events_stages_current表
23.9.5.2 events_stage_history表
23.9.5.3 events_stage_history_long表
23.9.11.1 replication_connection_configure表
23.9.11.2 replication_connection_status
23.9.11.3 replication_applier_configure
23.9.11.4 replication_applier_status
23.9.11.5 replication_applier_status_by_coordinator
23.9.11.6 replication_applier_statys_by_worker
23.9.11.7 replication_group_members
23.9.11.8 replication_group_member_status
MySQL Performance Schema用来监控MySQL Server的运行运行在底层。性能框架有这些特性:
· 性能框架提供了一种方法检查内部的服务运行。通过PERFORMANCE_SCHEMA存储引擎和performance_schema实现。性能框架主要关注于数据性能。和INFORMANCE_SCHEMA不同,INFORMACE_SCHEMA主要检查元数据。
· 性能框架监控服务事件,事件是服务需要花时间的任何东西,并且已经被记录这样时间信息可以被收集。通常一个事件可以是一个函数调用,一个操作系统等待,SQL语句执行的阶段比如解析或者排序,或者整个语句或者一组语句。时间收集提供。时间收集提供了同步调用文件和表IO,表锁等信息。
· 性能框架事件的事件和binlog的事件,事件调度的事件不同。
· 性能框架事件被指定到某个MySQL服务。性能框架表别人我是本地服务,他们的修改不会被写入到binary log,也不会被复制。
· 当前事件,历史事件和事件总结是可用的,那么就可以确定记录被启动了多少次,用了多少时间。事件信息可以查看指定线程的活动或者指定对象的活动,比如文件和信号量。
· PERFORMANCE_SCHEMA存储引擎使用代码中的记录点来收集信息。
· 收集的信息被保存在performance_schema数据库中。可以用select查询。
· 性能框架配置可以动态的被修改,通过修改performance_schema数据库配置数据收集。
· Performance_schema上的表是视图或者临时表,不会保存到磁盘中。
· MySQL支持所有平台的监控。
· 通过在源代码中加入记录点实现数据收集。没有特定线程使用相关的性能框架。
23.1 性能框架快速启动
对于性能框架要启用,必须要在MySQL编译的时候配置好。可以通过mysqld的帮助验证。如果性能框架可用输出就会带—performance_schema参数。
如果这些参数没有出现,那么代码在编译时就不支持性能框架。
假设性能框架可用,默认是可用的。可以通过配置文件配置:
[mysqld]
performance_schema=ON
当服务启动,发现performance_schema就会试图初始化性能框架,可以查看performance_schema变量检查初始化是否成功。
mysql> SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| performance_schema | ON |
+--------------------+-------+
这个值表示,性能框架已经可用,如果为off表示发生错误,检查错误日志。
性能框架实现和存储引擎类似。如果引擎可用可以在show engine查看是否支持PERFORMANCE_SCHEMA存储引擎。
Performance_schema中的数据库可以被划分为几块,当前时间,历史事件,总结,对象实例和安装信息。
原本,其实并不是所有的记录点和收集器都是可用。所以性能框架不会收集所有的数据。可以通过以下语句打开所有的积累点和收集器:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES';
Query OK, 560 rows affected (0.04 sec)
mysql> UPDATE setup_consumers SET ENABLED = 'YES';
Query OK, 10 rows affected (0.00 sec)
当前事件表,可以通过events_waits_current查看当前服务在做什么。每个线程都有一行。
历史表,表结构和当前事件一样,event_waits_history和event_waits_history_long表包含了每个线程最近10个event和每个线程最近10000个events。
一个新的事件被加入,老的事件就会删除。
总结表提供了所有事件的聚合的信息。这个表通过分组一不同方式计算事件数据。为了查看那个记录点呗执行的次数最多或者等待事件最长,通过对表上的count_star或者sum_timer_wait列进行排序:
mysql> SELECT EVENT_NAME, COUNT_STAR
-> FROM events_waits_summary_global_by_event_name
-> ORDER BY COUNT_STAR DESC LIMIT 10;
+---------------------------------------------------+------------+
| EVENT_NAME | COUNT_STAR |
+---------------------------------------------------+------------+
| wait/synch/mutex/mysys/THR_LOCK_malloc | 6419 |
| wait/io/file/sql/FRM | 452 |
| wait/synch/mutex/sql/LOCK_plugin | 337 |
| wait/synch/mutex/mysys/THR_LOCK_open | 187 |
| wait/synch/mutex/mysys/LOCK_alarm | 147 |
| wait/synch/mutex/sql/THD::LOCK_thd_data | 115 |
| wait/io/file/myisam/kfile | 102 |
| wait/synch/mutex/sql/LOCK_global_system_variables | 89 |
| wait/synch/mutex/mysys/THR_LOCK::mutex | 89 |
| wait/synch/mutex/sql/LOCK_open | 88 |
+---------------------------------------------------+------------+
mysql> SELECT EVENT_NAME, SUM_TIMER_WAIT
-> FROM events_waits_summary_global_by_event_name
-> ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
+----------------------------------------+----------------+
| EVENT_NAME | SUM_TIMER_WAIT |
+----------------------------------------+----------------+
| wait/io/file/sql/MYSQL_LOG | 1599816582 |
| wait/synch/mutex/mysys/THR_LOCK_malloc | 1530083250 |
| wait/io/file/sql/binlog_index | 1385291934 |
| wait/io/file/sql/FRM | 1292823243 |
| wait/io/file/myisam/kfile | 411193611 |
| wait/io/file/myisam/dfile | 322401645 |
| wait/synch/mutex/mysys/LOCK_alarm | 145126935 |
| wait/io/file/sql/casetest | 104324715 |
| wait/synch/mutex/sql/LOCK_plugin | 86027823 |
| wait/io/file/sql/pid | 72591750 |
+----------------------------------------+----------------+
如,上面结果THR_LOCK信号量是热点,2个语句分别表示执行的热度和等待事件长度。
实例表,记录了对象类型被记录了。当服务使用了一个记录对象,那么会产生一个事件。这些表提供了事件名,解释性的注释或者状态。比如file_instances表,记录了文件io操作和他们对应的文件。
mysql> SELECT * FROM file_instances\G
*************************** 1. row ***************************
FILE_NAME: /opt/mysql-log/60500/binlog.000007
EVENT_NAME: wait/io/file/sql/binlog
OPEN_COUNT: 0
*************************** 2. row ***************************
FILE_NAME: /opt/mysql/60500/data/mysql/tables_priv.MYI
EVENT_NAME: wait/io/file/myisam/kfile
OPEN_COUNT: 1
*************************** 3. row ***************************
FILE_NAME: /opt/mysql/60500/data/mysql/columns_priv.MYI
EVENT_NAME: wait/io/file/myisam/kfile
OPEN_COUNT: 1
...
Setup表用来配置和监控特点的,比如setup_timers表:
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
Setup_instruments列了哪些可以被记录的事件。然后通过修改这个表开控制是否启动这个记录。
mysql> UPDATE setup_instruments SET ENABLED = 'NO'
-> WHERE NAME = 'wait/synch/mutex/sql/LOCK_mysql_create_db';
性能框架使用,收集来的事件来更新到performance_schema数据库,数据库作为事件信息的消费者。Setup_consumers表列出了可用的消费者。
控制是否性能框架维护一个消费者作为事件信息的目标。可以设置为enabled值。
23.2 性能框架配置
23.2.1 性能框架编译时配置
为了让性能框架启用必须在编译时被配置,由官方提供的MySQL是支持性能框架的,如果是其他发布方发布的,那么要先检查是否支持。
如果是从源代码发布的,那么在发布的时候要先设置:
shell> cmake . -DWITH_PERFSCHEMA_STORAGE_ENGINE=1
在MySQL 5.7.3之后,也可以支持启动性能框架,但是不包含所有的记录点,比如:
shell> cmake . -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DDISABLE_PSI_STAGE=1 \
-DDISABLE_PSI_STATEMENT=1
如果你安装MySQL到一个老的安装上,并且没有配置过性能框架,当确保performance_schema数据库包含了所有的当前表后,可以使用mysql_upgrade启动服务。然后重启,有个迹象要特别留意:
[ERROR] Native table 'performance_schema'.'events_waits_history' has the wrong structure
[ERROR] Native table 'performance_schema'.'events_waits_history_long'has the wrong structure
...
通过以下查看mysql是否支持性能框架:
shell> mysqld --verbose --help
...
--performance_schema
Enable the performance schema.
--performance_schema_events_waits_history_long_size=#
Number of rows in events_waits_history_long.
...
也可以通过连接到服务之后使用show engine查看是否存在PERFORMANCE_SCHEMA存储引擎。如果在build的时候没有被配置那么show engines不会显示PERFORMANCE_SCHEMA存储引擎。
23.2.2 性能框架启动配置
假设性能框架是可用的,那么默认是启动的也可以在配置文件中配置:
[mysqld]
performance_schema=ON
如果服务不能在初始化性能框架的时候分配内部缓存,那么性能框架自己关闭并且设置performance_schema为off,服务在没有记录点状况下运行。
性能框架可以以命令行参数方式配置。
--performance-schema-instrument='instrument_name=value'
关闭所有记录点:
--performance-schema-instrument='%=OFF'
比较长的记录点名会比短的积累点名要优先于短的模式名,不管顺序。
具体可以看后面章节:23.2.3.4命名记录点或者消费者的过滤
一个无法别识别的记录点名会被忽略。为了控制消费者,可以使用以下选项:
--performance-schema-consumer-consumer_name=value
consumer_name
是一个消费者名比如events_waits_history,value是以下一个值:
l OFF,False或者0:不收集这个消费者的事件
l ON,True或者1:收集消费者的事件
比如消费者名是events_waits_history:
--performance-schema-consumer-events-waits-history=ON
被允许的消费者名可以在setup_consumers表上找到。在表中消费者名字都是下划线,在选项配置的时候,下划线和减号没有区别。
性能框架提供了很多系统变量可以用来配置:
mysql> SHOW VARIABLES LIKE 'perf%';
+--------------------------------------------------------+---------+
| Variable_name | Value |
+--------------------------------------------------------+---------+
| performance_schema | ON |
| performance_schema_accounts_size | 100 |
| performance_schema_digests_size | 200 |
| performance_schema_events_stages_history_long_size | 10000 |
| performance_schema_events_stages_history_size | 10 |
| performance_schema_events_statements_history_long_size | 10000 |
| performance_schema_events_statements_history_size | 10 |
| performance_schema_events_waits_history_long_size | 10000 |
| performance_schema_events_waits_history_size | 10 |
| performance_schema_hosts_size | 100 |
| performance_schema_max_cond_classes | 80 |
| performance_schema_max_cond_instances | 1000 |
...
Performance_Schema表示了性能框架是否启动,别的参数表示表的大小伙子内存分配的值。
可以使用配置文件开设置这些变量:
[mysqld]
performance_schema
performance_schema_events_waits_history_size=20
performance_schema_events_waits_history_long_size=15000
如果没有指定值,那么默认这些变量会有一个默认值。在MySQL 5.7.6,性能框架分配内存会根据服务符合增加伙子减少,而不是在服务启动的时候一次性分配完成。所以很多参数并不需要在启动的时候都分配好,更多内容可以看23.12 性能框架系统变量。
每个自动分配的参数不是在启动时设置或者设置为-1,性能框架决定如何根据以下的参数来设置这些值:
max_connections
open_files_limit
table_definition_cache
table_open_cache
如果要覆盖自动设置的值或者自动范围的值,就在启动的时候设置一个给定的值而不是给-1这样性能框架就会设置一个给定的值。
在运行时,show variables会显示自动设置的值,自动范围设置的会给-1.如果性能框架被禁用,自动设置和自动范围参数都会被设置为-1,并且显示为-1.
23.2.3 启动时性能框架配置
23.2.3.1 性能架构事件定时
事件被收集也就是说记录点被加到了服务源代码中。记录点时间事件,是性能框架如何提供一个事件持续多久的方案。也可以配置记录点收集定时信息。
性能框架定时器
2个性能框架表提供了定时器信息:
l Performance_timers,保存了可用的timers和它们的特点。
l Setup_timers,表明了哪些记录点使用了哪个timers。
每个setup_timers使用的计时器躲在performance_timers表中。
mysql> SELECT * FROM performance_timers;
+-------------+-----------------+------------------+----------------+
| TIMER_NAME | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD |
+-------------+-----------------+------------------+----------------+
| CYCLE | 2389029850 | 1 | 72 |
| NANOSECOND | 1000000000 | 1 | 112 |
| MICROSECOND | 1000000 | 1 | 136 |
| MILLISECOND | 1036 | 1 | 168 |
| TICK | 105 | 1 | 2416 |
+-------------+-----------------+------------------+----------------+
TIMER_NAME:表示可用timer的名字,CYCLE表示给予cpu计数器
TIMER_FREQUENCY:表示每秒的timer个数。对于cycle timer,频率和cpu事件相关,其他timer是秒的若干分。
TIMER_RESOLUTION:表示每次增加的单位
TIMER_OVERHEAD:指定周期获取一个定时需要的最小cycles个数。每个事件都会在开始和结束的时候调用timer,因此是显示的负荷的2倍。
修改setup_timer表的timer_name:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'idle';
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
默认性能框架会为每个记录点类型设置timer,也可以修改。
对于记录等待事件的时间,最重要的是在时间精度上减少负荷,所以使用cycle timer最合适。
对于语句或者stage的执行比执行一个简单的等待要大的多,并且需要一个精确的量,并且和处理器无关,所以最好不要使用cycle。默认使用NANOSECOND。尽管负荷比cycle要大,但是不重要,因为调用2次计数器的数量级远远比执行语句本身的cpu时间要小。
Cycle提供的精度和cpu有关,如果处理器是1Gh或者更高,cycle可以提供比纳秒还小的进度。使用cycle计数器比获取一个一天的实际事件开销小。
Cycle的缺点:
l 从cycles转化为时间单位是比较费事的。为了更快,这个转化操作知识很粗糙的乘法计算。
l 处理器cycle,可能会遍,比如笔记本进入省电模式,那么cpu cycle会下降如果cpu cycle有波动,那么转化就会出错。
l Cycle 计数器可能是不靠谱的或者不可用的,和处理器或者操作系统有关。
l 一些处理器,乱序执行或者多处理器同步,可能会导致计数器忽高忽低。
性能框架计数器在事件中的表现
存储在性能框架表的当前事件,有3个列表示事件,TIMER_START,TIMER_END表示事件启动和结束,TIMER_WAIT表示事件的时间。
Set_instruments表有ENABLED字段来表示,事件是否要收集。TIMED字段表示记录点是否被时间标记。如果记录点没有启动,那么就不会生成事件。如果不是timed,那么生成的事件,中TIMER_START,TIME_END,TIMER_WAIT是null。那么在统计表计算最大时间,最小时间的时候会被忽略。
内部,事件启动的时候,timer以给定的单位保存在事件里面,当要显示的时候,timers被显示为标准的事件单位,不管选了什么timer都会显示为,皮秒。
Setup_timers的修改会马上生效。已经在处理的会使用老的timer。为了不导致无法预期的结果出现,最好先把统计表使用truncate table进行重置。
Timer的基线,在服务启动的时候被初始化。TIMER_START,TIMER_END表示从基线以来的皮秒数。TIMER_WAIT表示占用的皮秒。
23.2.3.2 性能框架事件过滤
事件是以生产者消费者模式处理的:
l 记录点代码是事件的源,产生事件被用来收集,setup_instruments表列出了可以被收集的记录点。Setup_instruments表提供了很多event的产生。
l 性能框架表示事件的目的地。Setup_consumers,列出了所有消费者类型。
l 预过滤,通过修改性能框架配置完成,可以通过启用或者禁用记录点和消费者完成。使用预过滤的目的:
n 减少负荷。性能框架运行需要消耗资源,虽然很少。
n 不关心的事件可以不写入消费者中。
n 避免维护多个类型的事件表。
· 事后过滤,可以使用where语句在查询性能框架的时候过滤。
23.2.3.3 事件预过滤
预过滤有性能框架完成并且会全局的影响所有用户。预过滤可以在生产者或者消费者的处理阶段上:
· 几个表可以用来配置生产者的预过滤:
§ Setup_instruments说明哪个记录点是可用的,如果这个表上一个记录点被禁用,不管其他表怎么配置,都不会再产生事件。
§ Setup_objects控制了性能框架特定表和存储过程对象。
§ Threads表示是不是每个服务线程都有监控
§ Setup_actors新的后台进程的初始监控状态
· 要配置预过滤在消费者阶段,那么要修改setup_comsumers表。setup_comsumers也会影响事件的产生。如果指定的事件不会发送给任何地方,那么性能框架不会产生
修改任意表都会马上影响监控,但是有些例外:
· 修改某些setup_instruments表只有的服务启动的时候生效。在运行时修改不会生效。
· 修改setup_actors表,只会影响后台线程。
当修改监控配置,性能框架不会刷新历史表。历史表和当前表的事件不会被替换,除非又新的事件。如果禁用一个记录点的时候,需要等待一段时间,来替换老的事件。也可以用truncate table清空。
在修改完记录点之后,可能下那个药伤处summary表清理统计信息对于events_statements_summary_by_digest或者内存统计表。Truncate table只会重置值为0,并不会删除行。
23.2.3.3.1 记录点预过滤
控制记录点的过滤,是过滤setup_instruments表设置enables字段。修改setup_instruments大多数会马上生效。对于某些记录点,修改只会在服务器启动才会生效。setup_instruments提供了最基本的记录点控制。
23.2.3.3.2 对象预过滤
Setup_objects表控制了性能框架部分表和存储过程。修改Setup_objects会马上相应。
mysql> SELECT * FROM setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
OBJECT_TYPE:表示对象类型,比如表或者事件,存储过程等。
OBJECT_SCHEMA和OBJECT_NAME包含了schema或者对象名的字符串,也可以是通配符
ENABLED列表示对象是否被监控,TIMED列表示是否收集timing信息。
默认会收集除了mysql,information_schema,performance_schema外所有的的数据库对象。
23.2.3.3.3 线程预过滤
threads表为每个线程保存了一行数据。每行数据都包含了线程的信息并且表明是否被监控。对于性能框架监控一个线程必须满足一下他条件:
· 表sestup_consumers表中的thread_instrumentation必须为yes
· Threads.instrumented列必须为yes
· 只监控setup_instruments表中的记录点
threads表也说明了每个服务线程是否执行历史事件记录。如果要记录历史事件以下条件都必须为真:
· 对应的消费者配置,setup_consumers表必须为yes。
· Threads.HISTORY列必须为yes。
· 只监控setup_instruments表中的记录点
对于后台线程,instrumented和history的初始数据,取决于setup_action中的配置。
mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
thread表的instrumented和history的规则如下:
· 如果最佳匹配,enabled=yes,那么instrumented=yes,最佳匹配history=yes,那么threads表的history=yes
· 如果最佳匹配,enabled=no,那么instrumented=no,最佳匹配history=no,那么threads表的history=no
· 如果无法匹配,那么instrumented,history都为no
在mysql 5.7.6 之前,没有enabled字段,只要有匹配,那么instrumented=yes
在mysql5.7.8,之前,没有history字段,线程要不全部可以进入history要不都不能,取决于setup_consumer的配置。
默认,后台的所有线程都是会被记录的,因为setup_actors有一行都是‘%’。
23.2.3.3.4 消费者预过滤
Setup_cunsumers表包含了所有的消费者。修改这个表来过滤那些event会被发送。
Setup_consumers表中设置消费者,从高级到低级。主要的原则如下:
· 除非性能框架检查消费者,并且消费者是可用的,不然不会受到消息。
· 只有当消费者依赖的所有的消费者都可用了,才会被检查
· 被依赖的消费者,有自己的依赖消费者。
· 如果一个事件没有目的,那么性能框架不会被产生。
全局和线程消费者
· Global_instrumentation是高级消费者,如果global_instrumentation为no,那么所有的的全局记录点都被禁用。所有其他低级的都不会被检查。当global_instrumentation启动了,才会去检查thread_instrumentation
· Thread_instrumentation,如果是no,那么这个级别下面的级别都不会被检查,如果是yes,性能框架就会维护线程指定信息,并且检查events_xxx_current消费者。
Wait Event消费者
这些消费者,需要global_instrumentation,thread_instrumention为yes。如果被检查行为如下:
· Events_waits_current,如果为no,禁用对各个wait event收集。如果为yes检查history消费者和history_long消费者。
· Events_waits_history,如果上级为no不检查,为yes,收集各个等待事件。
· Events_waits_history_long,和上面类似
Stage event,statement event和上面类似。
23.2.3.4命名记录点或者消费者的过滤
可以对指定记录名或者消费者进行过滤:
mysql> UPDATE setup_instruments
-> SET ENABLED = 'NO'
-> WHERE NAME = 'wait/synch/mutex/myisammrg/MYRG_INFO::mutex';
mysql> UPDATE setup_consumers
-> SET ENABLED = 'NO' WHERE NAME = 'events_waits_current';
指定一组记录点或者消费者:
mysql> UPDATE setup_instruments
-> SET ENABLED = 'NO'
-> WHERE NAME LIKE 'wait/synch/mutex/%';
mysql> UPDATE setup_consumers
-> SET ENABLED = 'NO' WHERE NAME LIKE '%history%';
23.2.3.5 识别哪些已经被记录
通过检查setup_instruments表,你可以得知包含了哪些记录点被记录:
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE 'wait/io/file/innodb/%';
+--------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+--------------------------------------+---------+-------+
| wait/io/file/innodb/innodb_data_file | YES | YES |
| wait/io/file/innodb/innodb_log_file | YES | YES |
| wait/io/file/innodb/innodb_temp_file | YES | YES |
+--------------------------------------+---------+-------+
23.3 性能框架查询
预过滤限制了哪些事件信息被收集,很多用户都不同。可以通过select过滤event。
mysql> SELECT THREAD_ID, NUMBER_OF_BYTES
-> FROM events_waits_history
-> WHERE EVENT_NAME LIKE 'wait/io/file/%'
-> AND NUMBER_OF_BYTES IS NOT NULL;
+-----------+-----------------+
| THREAD_ID | NUMBER_OF_BYTES |
+-----------+-----------------+
| 11 | 66 |
| 11 | 47 |
| 11 | 139 |
| 5 | 24 |
| 5 | 834 |
+-----------+-----------------+
23.4 性能框架记录点命名约定
记录点命名是一串组件然后用‘/’分割:
wait/io/file/myisam/log
wait/io/file/mysys/charset
wait/lock/table/sql/handler
wait/synch/cond/mysys/COND_alarm
wait/synch/cond/sql/BINLOG::update_cond
wait/synch/mutex/mysys/BITMAP_mutex
wait/synch/mutex/sql/LOCK_delete
wait/synch/rwlock/sql/Query_cache_query::lock
stage/sql/closing tables
stage/sql/Sorting result
statement/com/Execute
statement/com/Query
statement/sql/create_table
statement/sql/lock_tables
记录点命名类似于树形结构。从左到右越来越详细,组件的名称以来与计数器类型。
名字由2部分组成:
· 组件名,比如mysiam
· 变量名,一种是全局变量,还有一种是class::value。值class类中的变量。
顶级记录点组件
· Idle:表示idle事件的记录点。
· Memory:memory事件记录点
· Stage:阶段事件记录点
· Statement:语句事件记录点
· Transaction:事务事件记录点
· Wait:等待事件记录点
Idle记录点用于idle事件,具体看:23.9.3.5 socket_instance表
内存记录点组件
很多内存记录点默认是不可用的,可以手动启动,修改setup_instruments表。记录点前缀,memory/performance_schema/表示有多少性能框架内部的内存分配。memory/performance_schema/总是启用的,并且不能被禁用。这件记录点被收集在 memory_summary_global_by_event_name
表。
Stage记录点组件
Stage表示语句阶段性处理的比如sorting result或者sending data。
语句记录点组件
· Statement/abstract/*: 抽象语句操作记录点。抽象记录点在语句早期使用。
· Statement/com :是记录点命令操作。并且有名字对应到com_xxx操作,比如statement/com/Connect 和 statement/com/Init DB对应到COM_CONNECT和COM_INIT_DB命令。
· Statement/scheduler/event:单个记录点用来跟踪所有事件调度生成的事件。
· Statement/sp :存储过程执行内部的记录点,比如statement/sp/cfetch 和statement/sp/freturn,用来游标获取和函数返回。
· Statement/sql:sql操作的记录点,比如statement/sql/create_db和statement/sql/select,用于创建数据库和select语句。
等待记录点指令
· Wait/io,io操作记录点
§ Wait/io/file:文件io操作记录点,对于文件,等待是等待文件操作文件完成。因为缓存的关系,物理文件io可能在这个操作上不会执行
§ Wait/io/socket:socket操作记录点,socket记录点有以下命名格式:wait/io/socket/sql/socket_type。服务有一个监听socket用来支持每个网络协议。这个记录点支持监听socket是tcpip或者unix socket文件。socket_type的值为server_tcpip_socket或者server_unix_socket。当监听socket发现一个连接,服务把这个连接转换到独立的线程。那么新的连接线程的socket_type为client_connection。
§ Wait/io/table: 表io操作记录点。包含持久性表或者临时表的行级别访问。对行的影响就是fetch,insert,update,delete。对于视图,是被视图引用的基表。和其他等待不同,表的io等待报货其他等待。比如表io可能包含,文件io或者内存操作。因此events_waits_current中对于行的等待可能有2行。
· Wait/lock ,锁操作的记录点
§ Wait/lock/table,表锁记录点操作
§ Wait/lock/metadata/sql/mdl,元数据所操作
· Wait/synch,同步对象记录点
§ Wait/synch/cond,条件被用来一个线程通知另外一个线程,某些它们等待的东西已经完成。如果一个线程等待一个条件,那么会醒来并且处理。如果多个线程等待那么会都新来并且完成它们等待的资源。
§ Wait/synch/mutex,多排他对象用来访问一个资源,防止其他线程访问资源。
§ Wait/synch/rwlock,一个读写锁对象用来锁定特定的变量,防止其他线程使用。一个共享读所可以多个线程同时获取。一个排他写锁只能由一个线程获取。
§ Wait/synch/sxlock,共享排他锁是读写锁的rwlock的一种,提供当一个线程写时,其他线程可以非一致性读。Sxlock在mysql 5.7中使用为了优化rwlock的或展现。
23.5 性能框架和状态监控
可以使用show status like ‘%perf%’查看性能框架的状态。
性能框架状态变量提供了关于记录点因为内存的原因没有被创建或者加载的信息。根据状态命名有几类:
· Performance_Schema_xxx_class_lost,表示有多少xxx类型的记录点不能被加载。
· Performance_schema_xxx_instance_lost,表示有多少xxx类型的记录点不能被创建。
· Performance_schema_xxx_handlees_lost,表示有多少xxx类型的记录点不能被打开。
· Performance_schema_locker_lost,表示有多少时间都是或者没有被记录。
比如,一个信号量是记录点,但是服务不能为记录点分配内存。那么会增加performnace_schema_mutex_classes_lost。但是信号量还是以用于对象同步。但是性能数据就无法被收集,如果记录点被分配,用来初始化记录点信号量实体。对于单独的信号量比如全局信号量,只有一个实例。有些信号量的实例个数会变化,比如每个连接的信号量。如果服务不能创建一个指定记录点信号量实体,就会增加,performance_schema_mutex_instance_lost。
假设有以下条件:
· 服务启动参数,--performance_schema_max_mutex_classes=200,因此有200个信号量空间。
· 150信号量已经被加载
· 插件plugin_a有40个信号量
· 插件plugin_b有20个信号量
服务为插件,分配信号量记录点依赖于已经分配了多少,比如以下语句:
INSTALL PLUGIN plugin_a
那么服务已经有了150+40个信号量。
UNINSTALL PLUGIN plugin_a;
虽然插件已经卸载,但是还是有190个信号量。所有插件代码生成的历史数据还是有效。但是新的记录点事件不会被分配。
INSTALL PLUGIN plugin_a;
服务发现40个记录点已经被分配,因此新的记录点不会被创建,并且之前分配的内部buffer会被重新使用,信号量还是190个。
INSTALL PLUGIN plugin_b;
这个使用可用信号量已经只有10个了,新的插件要20个记录点。10个已经被加载,10个会被取消或者丢失。Performance_schema_mutex_classes_lost会标记这些丢失的记录点。
mysql> SHOW STATUS LIKE "perf%mutex_classes_lost";
+---------------------------------------+-------+
| Variable_name | Value |
+---------------------------------------+-------+
| Performance_schema_mutex_classes_lost | 10 |
+---------------------------------------+-------+
1 row in set (0.10 sec)
Plugin_b任然会收集执行部分记录点。
当服务不能创建一个信号量记录点,那么会发生以下情况:
· 不会有新行被插入到setup_instruments表
· Performance_Schema_mutex_classes_lost增加1
· Performance_schema_mutex_instance_lost,不会改变。
上面描述的适用于所有记录点,不单单是信号量。
当Performance_Schema_mutex_classes_lost大于0那么有2种情况:
· 为了保存一些内存,你可以启动,Performance_Schema_mutex_classes=N,N小于默认值。默认值是满足加载所有插件的mysql发布。但是一些插件如果不加载可能会少一点。比如你可以不加载默写存储引擎。
· 你加载一个第三方插件,是性能框架的记录点,但是在服务启动的时候,不允许插件记录点内存获取。因为来自第三方,这个引擎的记录点内存并不会被记录在performance_schema_max_mutex_classes.
如果服务不能满足插件记录点的资源,没有显示的分配更多的 performance_schema_max_mutex_classes,那么久会出现记录点的饥饿。
如果performance_schema_max_mutex_classes.太小,没有错误会被写入到错误日志,并且在运行时没有错误。然而performance_schema上的表会丢失事件。performance_schema_max_mutex_classes_lost状态变量只是标记一些事件因为创建记录点失败被删除。
如果记录点没有丢失,那么就会通知性能框架,当在代码中(THD::LOCK_delete)创建了信号量,单个记录点就会被使用。那么就需要很多信号量实体。这个时候,每个线程都有lock_delete,比如有1000个线程,1000个lock_delete信号量记录点实例。
如果服务没有空间存放所有1000个信号量记录点实体,一些信号量会被创建记录点,一些就不会被创建。如果服务职能创建800个,那么另外200个会丢失,Performance_schema_mutex_instances_lost会增加200个。
Performance_schema_mutex_instances_lost,可能在要初始化的信号量记录点大于配置的Performance_schema_mutex_instances=N那么久会发生。
如果SHOW STATUS LIKE 'perf%'没有丢失任何东西,那么新能框架数据是可以被依赖的。如果有一些都是了,那么数据是不完整的,并且性能框架不会记录所有。这样Performance_schema_xxx_lost就说明了问题范围。
有些时候饥饿时可以均衡的,比如你可能不需要文件io的数据,那么可以把所有性能框架参数,和文件io相关的都设置为0,那么久不会把内存分配到和文件相关的类,对象实例或者句柄中。
23.6 性能框架和分子原子性事件
对于一个表的io事件,通常有2行在events_waits_current,不是一个如:
Row# EVENT_NAME TIMER_START TIMER_END
---- ---------- ----------- ---------
1 wait/io/file/myisam/dfile 10001 10002
2 wait/io/table/sql/handler 10000 NULL
行获取会导致文件读取。比如,表io获取事件在文件io事件之前,但是还没有完成。那么文件io嵌入在表io事件。
和其他原子性等待事件不同,表io事件是分子,包含其他事件。Events_waits_current中,表io事件通常有2行:
· 一行是当前表io等待事件
· 一行是其他任何类型的等待事件。
通常,其他类型的等待事件不是表io事件。当副事件完成,会从events_waits_current中消失。
23.7 性能框架statement digests
MySQL服务有能力维护statement digest信息。Digest进程把一个sql语句转化为标准的格式并且计算一个hash结果。标准化允许相似的语句分组并且总结暴露一些语句的类型和发生的频率。
在性能框架,语句digest涉及这些组件:
· Setup_comsumers的statement_digset控制了,性能框架如何维护digest信息。
· 语句事件表有列包含digest和相关的值的列:
§ DIGEST_TEXT,标准化的语句。
§ DIGEST,是digest MD5 hash值。
Digest计算,最大的可用空间1024B。MySQL 5.7.8后这个值可以通过参数,performance_schema_max_digest_length修改。之前使用max_digest_length。
· 语句事件表也有sql_text列包含了原始的sql语句。语句显示的最大为1024B,可以通过performance_schema_max_sql_text_length字段修改。
· events_statements_summary_by_digest,提供综合的语句digset信息。
标准化一个语句转化,会保留语句结构,删除不必要的信息:
· 对象标识符,比如表或者数据库名会被保留。
· 文本值会被替换成变量。
· 注释会被删除,空格会被调整。
比如如下2个语句:
SELECT * FROM orders WHERE customer_id=10 AND quantity>20
SELECT * FROM orders WHERE customer_id = 20 AND quantity > 100
替换后会变成:
SELECT * FROM orders WHERE customer_id = ? AND quantity > ?
对于每个标准化的语句提供一个DIGEST_TEXT和DIGEST一个hash值。语句Digest总结表,提供了语句的profile信息,显示语句运行频率运行次数等。
events_statements_summary_by_digest大小固定的,所以如果满了,如果在表上没有匹配的,那么所有的语句都会被计算在schema_name和digest为null的记录里面,当然可以增加digest大小,performance_schema_digests_size,如果没有指定,那么性能框架会自己评估一个值。
performance_schema_max_digest_length系统变量决定digest buffer最大可用字节。但是现实的语句digest的长度往往比buffer长,那是因为关键字和文本值的关系。也就是说digest_text的长度可能超过performance_schema_max_digest_length。
对于应用程序生成了很长的语句,只有结尾不同,增加performance_schema_max_digest_length可以让digest得以计算,识别语句。反过来减少performance_schema_max_digest_length会导致服务牺牲很少的内存来保存语句的digest,但是增加了语句的相似度,被当成同一个digest。如果长度要求长,那么保存的也要更多。
可以通过show engine performance_schema status语句,或者监控以下语句查看sql语句保存使用的内存量。
mysql> SELECT NAME FROM setup_instruments
-> WHERE NAME LIKE '%.sqltext';
+------------------------------------------------------------------+
| NAME |
+------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.sqltext |
| memory/performance_schema/events_statements_current.sqltext |
| memory/performance_schema/events_statements_history_long.sqltext |
+------------------------------------------------------------------+
mysql> SELECT NAME FROM setup_instruments
-> WHERE NAME LIKE 'memory/performance_schema/%.tokens';
+----------------------------------------------------------------------+
| NAME |
+----------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.tokens |
| memory/performance_schema/events_statements_current.tokens |
| memory/performance_schema/events_statements_summary_by_digest.tokens |
| memory/performance_schema/events_statements_history_long.tokens |
+----------------------------------------------------------------------+
23.8 性能框架常用表特性
Performance_schema数据库是小写的,数据库里面的表名也是小写的。查询要使用小写。
很多表在performance_schema数据库是只读的不能被修改。一些setup表的某些列可以被修改。一些也可以被插入和删除。事务可以被允许清理收集的事件,所以truncate table可以用来清理信息。
Truncate table可以在总结表上使用,但是不能再events_statements_summary_by_digest和内存总结表上使用,效果只是把总计列清理为0.
23.9 性能框架表描述
23.9.1 性能框架表索引
具体看:http://dev.mysql.com/doc/refman/5.7/en/performance-schema-table-index.html
23.9.2 性能框架setup表
Setup表提供关于当前收集点启用信息。使用表而不是全局变量提供了更高级别的性能框架配置。比如你可以使用一个sql语句配置多个记录点。
这些setup表示可用的:
· Setup_actors:如何初始化后台线程
· Setup_consumers:决定哪些信息会被发送和存储。
· Setup_instruments:记录点对象,哪些事件要被收集。
· Setup_objects:哪些对象要被监控
· Setup_timers:当前事件定时器。
23.9.2.1 setup_actors表
setup_actors表包含了信息决定是否监控或者对新的后台线程进行历史数据记录。这个表默认最多100行,可以通过修改参数performance_schema_setup_actors_size修改大小。
对于新的后台线程,在setup_actors中,性能框架满足的用户和host。如果一个行负荷enabled,histroy列,对应到threads表上的instrumented和history列。如果找不到匹配那么instrumented和history列就为no。
对于后台线程, Instrumented和history默认都是yes,setup_actors默认没有限制。
Setup_actors初始化内容,不过滤任何数据:
mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
修改setup_actors表只会影响后台线程,不会影响已经存在的线程。为了影响已经存在的threads表,修改instrumented和history列。
23.9.2.2 setup_consumers表
Setup_consumers表列了各个类型的消费者:
mysql> SELECT * FROM setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
Setup_consumers设置形成从高到低的级别。形成依赖,如果高级别的设置了低级别才会有机会被检查。
23.9.2.3 setup_instruments表
Setup_consumers表列了所有记录点对象:
mysql> SELECT * FROM setup_instruments;
每个记录点被增加到源代码中,都会在这个表上有一行,即使记录点代码没有被指定。当一个记录点启动了或者执行了,记录点实例就会被创建会显示在*_instrances表。
修改setup_instruments行会马上影响监控。对于一些记录点,修改只会在下次启动才会生效。在指定时修改并不会生效。
23.9.2.4 setup_objects表
Setup_objects表控制了哪些对象的性能框架会被监控。这个对象默认为100行可以通过修改变量来控制,performance_schema_setup_objects_size。
初始化的setup_objects如下:
mysql> SELECT * FROM setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
| EVENT | mysql | % | NO | NO |
| EVENT | performance_schema | % | NO | NO |
| EVENT | information_schema | % | NO | NO |
| EVENT | % | % | YES | YES |
| FUNCTION | mysql | % | NO | NO |
| FUNCTION | performance_schema | % | NO | NO |
| FUNCTION | information_schema | % | NO | NO |
| FUNCTION | % | % | YES | YES |
| PROCEDURE | mysql | % | NO | NO |
| PROCEDURE | performance_schema | % | NO | NO |
| PROCEDURE | information_schema | % | NO | NO |
| PROCEDURE | % | % | YES | YES |
| TABLE | mysql | % | NO | NO |
| TABLE | performance_schema | % | NO | NO |
| TABLE | information_schema | % | NO | NO |
| TABLE | % | % | YES | YES |
| TRIGGER | mysql | % | NO | NO |
| TRIGGER | performance_schema | % | NO | NO |
| TRIGGER | information_schema | % | NO | NO |
| TRIGGER | % | % | YES | YES |
+-------------+--------------------+-------------+---------+-------+
修改setup_objects表会马上影响监控。
对于setup_objects,object_type表示监控了哪些对象类型。如果没有匹配的object_schema,object_name。那么就不会有对象没监控。
23.9.2.5 setup_timers表
Setup_times表如下:
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
Timer_name是,performance_timers中的一行。表示某个事件类型使用了什么计时器
23.9.3 性能框架实例表
23.9.3.1 cond_instances表
Cond_instance表列出了所有性能框架可以查看的条件。条件是同步机制,用来通知一个指定的事件已经产生完毕。所以一个线程等待这个条件的会马上恢复工作。
当一个线程等待的东西已经变化,条件名值说明线程在等待条件名。
23.9.3.2 file_instances表
当指定文件io记录点的时候,File_instances表列出了所有性能框架能看到的所有文件。如果文件在disk但是没有被打开不会出现在file_instrances中。当文件在次磁盘中被删除,那么file_instances中也会删除。
23.9.3.3 mutex_instances表
Mutex_instances显示了所有可以被性能框架查看到的信号量。信号量是同步机制用来保护资源。当2个线程运行需要放问相同的资源,2个线程会互相争用,一个线程获取了mutex上的锁,那么另外一个只能等待上一个完成。
当任务执行获取信号量,称为临界区域,区域内执行都是顺序的,可能有潜在瓶颈问题。
表中有3个字段:
Name:记录点的名字
OBJECT_INSTANCE_BEGIN:被记录的信号量在内存中的地址。
LOCKED_BY_THREAD_ID:拥有mutex的线程id,否则为null。
对于每个记录的信号量,性能框架提供一下信息:
· Setup_instruments表列出了记录点名,以wait/synch/mutex/为前缀。
· 当有代码创建了信号量,那么就有一行被加入到mutex_instrances表中,OBJECT_INSTANCE_BEGIN列是mutex的唯一列。
· 当一个线程视图锁定信号量,events_waits_current表为线程显示一行,说明在等待信号量,通过object_instance_begin。
· 当线程成功锁定了一个信号量:
§ Events_waits_current,显示等待信号量就会完成
§ 完成的事件会被添加到历史表中
§ Mutex_instances显示信号量现在属于一个thread
· 当thread unlock一个信号量,mutex_instances显示信号量现在没有owner,thread_id为null。
· 当信号量对象被销毁,对应的行也会被删除。
查以下2个表,可以诊断瓶颈或者死锁:
§ Events_waits_current,查看线程等待的信号量。
§ Mutex_instrances,查看其它线程的所有的信号量。
23.9.3.4 Rwlock_instances表
Rwlock_instances表列出了所有rwlock的实例。Rwlock是同步机制用来强制在一定规则下,在给定的事件里面能访问一些资源。这些资源被rwlock保护。访问要不是共享方式要不是排他方式,如果允许非一致性访问,还可以共享排他方式访问。Sxlock只有在,mysql 5.7之后才能被使用,用来优化并发性。
根据访问的需求,所的请求要不是,共享,排他,共享排他或者不授权,等待其他线程完成。
表列如下:
· NAME:记录点名相关的lock
· OBJECT_INSTANCE_BEGIN:被记录的锁在内存中的地址。
· WRITE_LOCKED_BY_THREAD_ID:当一个线程有一个rwlock,排他模式,WRITE_LOCKED_BY_THREAD_ID,就是锁定线程的thread_id。
· READ_LOCKED_BY_COUNT:当线程当前有一个rwlock共享模式,那么read_locked_by_count增加1。只是个计数,所以找不到那个线程拥有了读锁,但是可以用来查看是否有读锁,有多少读是活动的。
通过执行查询一下表,何以知道瓶颈和死锁:
· Events_waits_current,查看等待哪些rwlock
· Rwlock_instrances,查看其它线程是否拥有这个锁。
只能知道那个线程有了write lock但是不知道哪个线程有read lock。
23.9.3.5 socket_instance表
Socket_instancees表提供了一个实时的连接活动快照。每个tcp/ip连接有一行,或者每个unix socket file连接有一行。
mysql> SELECT * FROM socket_instances\G
*************************** 1. row ***************************
EVENT_NAME: wait/io/socket/sql/server_unix_socket
OBJECT_INSTANCE_BEGIN: 4316619408
THREAD_ID: 1
SOCKET_ID: 16
IP:
PORT: 0
STATE: ACTIVE
*************************** 2. row ***************************
EVENT_NAME: wait/io/socket/sql/client_connection
OBJECT_INSTANCE_BEGIN: 4316644608
THREAD_ID: 21
SOCKET_ID: 39
IP: 127.0.0.1
PORT: 55233
STATE: ACTIVE
*************************** 3. row ***************************
EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
OBJECT_INSTANCE_BEGIN: 4316699040
THREAD_ID: 1
SOCKET_ID: 14
IP: 0.0.0.0
PORT: 50603
STATE: ACTIVE
socket记录点名字格式,wait/io/socket/sql/socket_type:
1.
服务有一个监听socket,记录点那么socket_type的值为server_tcpip_socket
或者server_unix_socket
。
2. 当有一个监听socket发现一个连接,那么服务会转化到一个新的socket来管理,server_type类型为client_connection。
3. 当一个连接中断,那么行会在socket_instances中删除。
Socket_instances表类如下:
· EVENT_NAME: wait/io/socket/*,具体的名字来至于setup_instruments表
· OBJECT_INSTANCE_BEGIN:socket的唯一标记,值为对象在内存中的值。
· THREAD_ID:内部线程表示。每个socket由线程管理,所以每个socket被映射到一个线程。
· SOCKET_ID:socket内部的分配的文件句柄
· IP:客户端ip地址
· PORT:客户端端口地址
· STATE:socket状态要不是idle要不是active。如果线程等待client的请求,那么状态就是idle。当socket变成idle,表中的STATE也会变成IDLE,socket的记录点中断。当请求出现idle中断,变成ACTIVE。Socket的记录点timing恢复。
IP:PORT组合来表示一个有效的连接。组合值被用于events_waits_xxx表的object_name,来标记连接来至于哪里:
· 来至于unix域监听socket,端口是0,ip为‘’
· 对于通过unix域监听的socket,端口是0,ip为‘’
· 对于tcp/ip的监听,端口是服务的端口,默认为3306,ip为0.0.0.0
· 对于通过tcp/ip连接的客户端接口,端口不为0,ip是客户端的ip。
23.9.4 性能框架事件等待表
事件等待表有3个:
· Events_waits_current:当前事件等待表
· Events_waits_history:历史等待历史表,最近的等待事件表
· Events_waits_history_long:很多事件等待历史的表。
等待历史配置
为了收集等待事件,启动相应的记录点和消费者。
mysql> SELECT * FROM setup_instruments
-> WHERE NAME LIKE 'wait/io/file/innodb%';
+--------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+--------------------------------------+---------+-------+
| wait/io/file/innodb/innodb_data_file | YES | YES |
| wait/io/file/innodb/innodb_log_file | YES | YES |
| wait/io/file/innodb/innodb_temp_file | YES | YES |
+--------------------------------------+---------+-------+
mysql> SELECT * FROM setup_instruments WHERE
-> NAME LIKE 'wait/io/socket/%';
+----------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+----------------------------------------+---------+-------+
| wait/io/socket/sql/server_tcpip_socket | NO | NO |
| wait/io/socket/sql/server_unix_socket | NO | NO |
| wait/io/socket/sql/client_connection | NO | NO |
+----------------------------------------+---------+-------+
修改enabled和timing列:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME LIKE 'wait/io/socket/sql/%';
Setup_consumers包含消费者对应到刚刚的事件表。这些消费者用来过滤等待事件的收集,默认被禁用:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%waits%';
+---------------------------+---------+
| NAME | ENABLED |
+---------------------------+---------+
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
+---------------------------+---------+
启动所有的等待事件:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%waits%';
Setup_timers表包含了一行name为wait,表示等待事件的定时的单位,默认是cycle:
mysql> SELECT * FROM setup_timers WHERE NAME = 'wait';
+------+------------+
| NAME | TIMER_NAME |
+------+------------+
| wait | CYCLE |
+------+------------+
修改定时单位时间:
mysql> UPDATE setup_timers SET TIMER_NAME = 'NANOSECOND'
-> WHERE NAME = 'wait';
23.9.4.1 events_waits_current表
Events_waits_current表包含了当前的等待时间,每个thread都有一行显示当前thread的等待时间。Events_waits_current表可以使用truncate table。
Events_waits_current表列:
· THREAD_ID,EVENT_ID
线程相关的事件和线程当前事件号。这2个字段形成主键来标示一行。
· END_EVENT_ID
当事件启动,这个列为null,如果时间结束分配一个事件号。
· EVENT_NAME
生成事件的记录点名。
· SOURCE
源代码文件名包含产生事件的记录点代码位置。可以帮助用来检查源代码。
· TIMER_START,TIMER_END,TIMER_WAIT
事件的timing信息。时间单位为皮秒。TIMER_START,TIMER_END表示事件的开始和结束。TIMER_WAIT是事件的持续时间。如果事件没有完成TIMER_END,TIMER_WAIT为null。如果记录点的timed=no那么这3个列都是null。
· SPINS
对于信号量,是只自旋次数。如果为null,表示代码不使用自旋或者自旋没有被记录。
· OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE_OBJECT_INSTANCE_BEGIN
这些列表示对象被启动的位置,根据对象类型不同意义不同:
对于同步对象:(cond,mutex,rwlock)
§ OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE为null
§ OBJECT_INSTANCE_BEGIN为同步对象在内存中的地址。
对于文件io对象
§ OBJECT_SCHEMA为null
§ OBJECT_NAME为文件名
§ OBJECT_TYPE为file
§ OBJECT_INSTANCE_BEGIN为内存地址
对于socket对象
§ OBJECT_NAME为IP:PORT
§ OBJECT_INSTANCE_BEGIN为内存地址
对于表io对象
§ OBJECT_SCHEMA是表所在schema的名字
§ OBJECT_NAME表名
§ OBJECT_TYPE为table或者temporary table
§ OBJECT_INSTANCE_BEGIN是内存地址
OBJECT_INSTANCE_BEGIN本身是没有意义的,除非不同的值表示不同的对象。OBJECT_INSTANCE_BEGIN可以用来调试。比如group by这个字段查看是否有1000个信号量,造成一点瓶颈。
· INDEX_NAME
使用的index名字,primary表示表的主键索引,null表示没有索引
· NESTING_EVENT_ID
event_id表示那个event被嵌套
· NESTING_EVENT_TYPE
嵌套的事件培训,可能是以下一种,TRANSACTION,STATEMENT,STAGE,WAIT
· OPERATION
执行操作的类型,lock,read,write中一个。
· NUMBER_OF_BYTES
读写操作的字节个数。对于表io等待,MySQL 5.7.5之前值为null,之后为行数。如果值大于1,是批量io操作。MySQL执行join是nested-loop机制。性能框架可以提供行数和每个表执行join准确的时间。假设一个join查询,执行如下:
SELECT ... FROM t1 JOIN t2 ON ... JOIN t3 ON ...
在join操作的时候表的表行的增加减少(扇出)。如果t3的扇出大于1,那么大多数行获取操作就来自于这个表。假设t1 10行,t2 20行对应到t1一行,t3 30行对应t2 1行。那么一共会有被记录的操作是:
10 + (10 * 20) + (10 * 20 * 30) = 6210
为了减少被记录操作,可以通过每次扫描实现聚合的方式(聚合t1,t2的唯一值)。记录点计数减少为:
10 + (10 * 20) + (10 * 20) = 410
对于上面的情况使用环境:
§ 查询访问的表基本上都是inner join的
§ 查询执行不需要表内的单个记录
§ 查询执行不需要评估子查询访问了表。
· FLAGS
保留
23.9.4.2 Events_waits_history表
Events_waits_history表每个线程包含了最近N条数据。表结构和events_waits_current一行,也可以被truncate table,N是服务启动自动设置的,也可以从参数设置: performance_schema_events_waits_history_size。
23.9.4.3 events_waits_history_long 表
Events_waits_history_long表每个线程包含了最近N条数据。表结构和events_waits_current一行,也可以被truncate table,N是服务启动自动设置的,也可以从参数设置: performance_schema_events_waits_history_long_size。
23.9.5 性能框架Stage事件表
性能框架stage记录,是语句执行的阶段,比如解析语句,打开表或者执行filesort操作。Stage关联到的了show processlist中的线程状态。
因为事件等级,等待事件穿插在stage事件,stage事件穿插在语句事件,事务事件。
Stage事件配置
启动stage事件的收集,启动相应的记录点和消费者。
Setup_instruments表包含以stage开头的记录点名。这些记录点除了语句处理的信息,默认是禁用的:
mysql> SELECT * FROM setup_instruments WHERE NAME RLIKE 'stage/sql/[a-c]';
+----------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+----------------------------------------------------+---------+-------+
| stage/sql/After create | NO | NO |
| stage/sql/allocating local table | NO | NO |
| stage/sql/altering table | NO | NO |
| stage/sql/committing alter table to storage engine | NO | NO |
| stage/sql/Changing master | NO | NO |
| stage/sql/Checking master version | NO | NO |
| stage/sql/checking permissions | NO | NO |
| stage/sql/checking privileges on cached query | NO | NO |
| stage/sql/checking query cache for query | NO | NO |
| stage/sql/cleaning up | NO | NO |
| stage/sql/closing tables | NO | NO |
| stage/sql/Connecting to master | NO | NO |
| stage/sql/converting HEAP to MyISAM | NO | NO |
| stage/sql/Copying to group table | NO | NO |
| stage/sql/Copying to tmp table | NO | NO |
| stage/sql/copy to tmp table | NO | NO |
| stage/sql/Creating sort index | NO | NO |
| stage/sql/creating table | NO | NO |
| stage/sql/Creating tmp table | NO | NO |
+----------------------------------------------------+---------+-------+
修改stage事件,修改enabled和timing列:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME = 'stage/sql/altering table';
Setup_consumers表包含消费者只关联的事件表名。消费者可能用来过滤收集器stage事件。Stage消费者默认禁用:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%stages%';
+----------------------------+---------+
| NAME | ENABLED |
+----------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
+----------------------------+---------+
启动所有的stage事件:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%stages%';
Setup_timers包含name=‘stage’,说明stage事件timing:
mysql> SELECT * FROM setup_timers WHERE NAME = 'stage';
+-------+------------+
| NAME | TIMER_NAME |
+-------+------------+
| stage | NANOSECOND |
+-------+------------+
修改timing值:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'stage';
Stage事件进程信息
MySQL 5.7.5,性能架构stage事件表包含2列,每行提供stage进程标示:
· WORK_COMPLETED:stage工作单元完成个数。
· WORK_ESTIMATED:预期的stage工作单元完成个数。
如果没有进度信息,每列都是null。性能框架提供一个容器来存放这些进度数据:
· 工作单元,是一个量,随着执行时间的增加变大。
· WORK_COMPLETED,一个或者多个单元增加一次,依赖于被记录代码
· WORK_ESTIMATED,可以在stage司改,根据,被记录代码。
对于stage事件的进度的记录可以实现以下任何行为:
· 没有进度记录点
这个是最常出现的,因为没有进度数据被提供,WORK_COMPLETED和WORKESTIMATED都为bull
· 没有被绑定记录点
只有WORK_COMPLETED列有意义,WORK_ESTIMATED列没有值,显示为0。
打开events_stages_current表监控回话,监控程序可以报告有多少work已经被执行,但是不知道什么时候可以结束,因为记录点没有提供。
· 绑定进度记录点
WORK_COMPLETED和WORK_ESTIMATED列都是有意义的。
进度标识符的类型适合于已经定义了完成临界的操作,比如表复制记录点。通过查询events_stages_current表来监控会话,监控程序可以监控所有完成比例的stage,通过计算WORK_COMPLETED / WORK_ESTIMATED的比率。
stage/sql/copy to tmp table演示,进度标识符如何工作。在执行alter table语句,这个记录点就很有用,并且会执行很长一段时间。
23.9.5.1 events_stages_current表
Events_stages_current表包含当前stage事件,每行一个线程线程当前状态监控到的stage事件。
Events_stages_current表可以truncate table。
表events_stages_current是events_stages_history和events_stages_history_long的基础。
Events_Stages_current列:
· THREAD_ID,EVENT_ID
线程相关的事件和线程当前事件号。这2个字段形成主键来标示一行。
· END_EVENT_ID
当事件启动,这个列为null,如果时间结束分配一个事件号。
· EVENT_NAME
生成事件的记录点名。
· SOURCE
源代码文件名包含产生事件的记录点代码位置。可以帮助用来检查源代码。
· TIMER_START,TIMER_END,TIMER_WAIT
事件的timing信息。时间单位为皮秒。TIMER_START,TIMER_END表示事件的开始和结束。TIMER_WAIT是事件的持续时间。如果事件没有完成TIMER_END,TIMER_WAIT为null。如果记录点的timed=no那么这3个列都是null。
· WORK_COMPLETED,WORK_ESTIMATED
这些列提供了stage进度信息,对于记录点已经用来生成这些信息。WORK_COMPLETED表示有多少工作单元已经被完成,WORK_ESTIMATED表示有多少工作单元预计的stage。
· NESTING_EVENT_ID
EVENT_ID nested生成的事件。嵌套的event的stage事件通常是语句事件。
· NESTING_EVENT_TYPE
嵌套事件类型,TRANSACTION,STATEMENT,STAGE,WAIT其中一个。
23.9.5.2 events_stage_history表
Events_stages_history为每个线程保留了N个记录,具体可以通过配置参数修改:
performance_schema_events_stages_history_size
23.9.5.3 events_stage_history_long表
Events_stages_history_long为每个线程保留了N个记录,具体可以通过配置参数修改:
performance_schema_events_stages_history_long_size
23.9.6 性能框架语句事件表
性能框架记录点语句执行。语句事件发生在高级别的事件,等待事件嵌套在stage事件中,stage事件嵌套在语句事件中,语句事件嵌套在事务事件中。
语句事件配置
Setup_instruments表包含记录点,以statement前缀的记录点。这些记录点的默认值可以使用语句:
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE 'statement/%';
可以通过以下语句修改:
mysql> UPDATE setup_instruments SET ENABLED = 'NO'
-> WHERE NAME LIKE 'statement/com/%';
查看和修改timer:
mysql> SELECT * FROM setup_timers WHERE NAME = 'statement';
+-----------+------------+
| NAME | TIMER_NAME |
+-----------+------------+
| statement | NANOSECOND |
+-----------+------------+
修改timer:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'statement';
语句监视
语句监视开始于被请求的活动到所有活动停止。也就是服务受到客户端的第一个包,到完成返回响应。在MySQL 5.7.2之前,语句只会是高级别的,比如在存储过程或者子查询不会被分离出来。
最终记录点名和服务命令和sql语句有关:
· 关联到COM_xxx定义在mysql_com.h头文件和在sql/sql_parse.cc中处理,比如COM_PING和COM_QUIT,那么记录点名以statement/com开头,比如statement/com/ping和statement/com/ping。
· SQL语句是用文本表示的。那么相关的命令行以statement/sql开头,比如statement/sql/delete和statement/sql/select。
一些记录点名表示特殊的错误处理:
· Statement/com/error,记录了服务收集到的未绑定的信息。无法判断从客户端发送到服务端的命令。
· Statement/sql/error,记录了sql语句分析错误。用来诊断查询发送到客户端的异常。一个查询分析错误和查询执行错误不同
请求可以通过以下渠道获得:
· 一个命令或者语句从客户端获取并发送
· 在replication slave,语句字符串从relay log读取。
· 从event scheduler获取事件。
请求的详细原来是不知道的,并且性能框架从请求的顺序获取特定的记录点名。
从客户端收集的请求:
1. 当服务发现一个新的包在socket级别,一个新的的语句以抽象的记录点名statement/abstract/new_packet开始。
2. 当服务读取包序号,获取接受的请求类型,性能框架获取记录点名。比如,请求是COM_PING包,那么记录点名会变成statement/com/ping。如果请求是COM_QUERY包,知道是一个sql语句,但是不知道具体的类型。这个时候会给一个抽象的记录点名statement/abstract/query。
3. 如果请求的语句,文本已经读入到分析器。分析之后,那么准确的语句类型已经知道了,如果请求是一个插入语句,性能框架会重新定位记录点名statement/abstract/Query to statement/sql/insert。
对于从复制的relay log上读取语句:
1. 语句在relay log中是以文本存储的。没有网络协议,所以statement/abstract /new_packet不会被使用,而是使用statement/abstract/realy_log。
2. 当语句被解析,准确的语句类型被得知。比如insert语句,那么性能框架会重新查找记录点名,statement/abstract/Query to statement/sql/insert。
上面介绍的,只是基于语句的复制,对于基于行的复制,订阅表行处理可以被记录,但是relay log中的行事件描述语句的并不会出现。
对于从事件调度器来的请求:
事件执行的记录点名为statement/scheduler/event。
事件体重的事件执行记录点名使用statement/sql/*,不适用其他抽象记录点名。事件是一个存储过程,并且存储过程是预编译在内存中的。那么在执行时就不会有解析,但是类型在执行时就知道了。
在事件体内的语句都是子句。比如一个事件执行了一个insert语句,执行的事件是上级。记录点使用statement/scheduler/event,并且insert是下级,使用statement/sql/insert记录点。
这样不单单是要启动statement/sql/*记录点,还要启动statement/abstract/*记录点。
在之前的5.7版本的,抽象记录点名用其他记录点代替的:
· Statement/abstract/new_packet之前为statement/com/
· Statement/abstract/query之前为statement/com/Query
· Statement/abstract/relay_log之前为statement/rpl/relay_log
23.9.7 性能框架事务表
性能框架事务记录点。在事件级别,等待事件嵌套stage事件,stage事件嵌套语句事件,语句事件嵌套事务事件。
事务事件配置
Setup_instruments包含的transaction的记录点:
mysql> SELECT * FROM setup_instruments WHERE NAME = 'transaction';
+-------------+---------+-------+
| NAME | ENABLED | TIMED |
+-------------+---------+-------+
| transaction | NO | NO |
+-------------+---------+-------+
启动收集事务事件:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME = 'transaction';
Setup_consumers表包含transaction的消费者:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%transactions%';
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
+----------------------------------+---------+
启动消费者:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%transactions%';
设置相关记录点:
mysql> SELECT * FROM setup_timers WHERE NAME = 'transaction';
+-------------+------------+
| NAME | TIMER_NAME |
+-------------+------------+
| transaction | NANOSECOND |
+-------------+------------+
修改timer_name的值:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'transaction';
事务绑定
在MySQL Server,使用以下语句显示启动事务:
START TRANSACTION | BEGIN | XA START | XA BEGIN
事务也可以隐式启动,当autocommit系统变量启动。当autocommit禁用,在启动新事务钱要显示的结束上面一个事务。
COMMIT | ROLLBACK | XA COMMIT | XA ROLLBACK
执行DDL语句,事务会隐式提交
性能框架定义的事务绑定和服务的很相似。事务的启动和解释也和服务的事务状态匹配:
· 对于显示启动的事务,事务events在start transaction后启动。
· 对于隐式启动的事务,事务事件在第一个语句执行的时候启动。
· 对于任何事务,当执行commit,rollback事务结束。
微妙的不同点:
· 性能框架中的事务事件,没有完全包含语句事件比如START TRANSACTION,COMMIT,ROLLBACK语句。
· 语句如果运行在非实物引擎,那么连接的事务状态不会影响。
事务记录点
3个定义的事务属性:
· 访问模式(read only,read write)
· 隔离级别
· 隐式或者显示
为了减少事务记录点并且保证收集事务数据是完成的,有意义的结果,所有事务都有访问模式,隔离级别,自动提交模式。
事务事件表使用3列来ACCESS_MODE,ISOLATION_LEVEL,AUTOCOMMIT记录。
事务记录点消费可以有很多种方式减少,比如根据用户,账号,host,thread启动或者禁用事务减了点。
线程和嵌套事件
事务事件的上级事件是初始化事务的事件。对于显示事务启动,包含START_TRANSACTION和commit and china,如果是隐式事务,第一个语句启动事务。
显示的结束事务,COMMIT,ROLLBACK,或者DDL语句,隐式的提交事务。
事务和存储过程
事务和存储过程事件关联如下:
· 存储过程
存储过程操作独立的事务,一个存储过程可以启动一个事务,并且一个事务可以在存储过程中启动和结束。如果在一个事务中调用,一个存储过程可以语句强制提交事务并且启动一个新的事务。
· 存储函数
存储函数可以限制显示或者隐式的事务提交和回滚。
· 触发器
触发器活动是语句的活动访问相关的表,所以触发器事件的上级事件激活它。
· 调度事件
事件体的语句调度事件发生一个新连接。
事务和savepoint
Savepoint语句以独立的语句事件被记录。语句事件包括SAVEPOINT,ROLLBACK TO SAVEPOINT和RELEASE SAVEPOINT语句。
事务和错误
事务中的错误和警告被记录在语句事件中,但是不在相关的事务事件。
23.9.8 性能框架连接表
性能框架提供了连接的统计信息。当客户端连接,在一个特定的用户名和host下。性能框架为每个账号跟踪连接。
· Accounts:每个客户端账号的连接统计信息。
· Hosts:每个客户端hostname 的连接统计信息。
· Users:每个客户端用户名的连接统计信息。
账号这里的意思是用户加上host。连接表有CURRENT_CONNECTIONS和TOTAL_CONNECTIONS列跟踪所有的连接。Accounts表有USER和HOST列跟踪用户和host。Users和hosts表有USER和HOST列,跟踪用户或者host。
假设客户端名user1,user2从hosta,hostb连接过来。性能框架跟踪连接入选:
· Accounts会有4条记录,user1/hosta,user1/hostb,user2/hosta,user2/host2.
· Users表有2条记录,user1,user2
· Host表有2条记录,hosta,hostb
当客户端连接,连接表中如果不存在这样的用户或者host,那么就增加一行否则就修改CURRENT_CONNECTIONS和TOTAL_CONNECTIONS列。
当客户端断开连接,性能框架减少current_connecitons列。
性能框架也计数内部线程和用户会话线程验证错误。对应的user和host为null。
每个连接表都可以truncate:
· 行如果是CURRENT_CONNECTIONS=0的就删除
· 如果>0,TOTAL_CONNECTIONS设置为CURRENT_CONNECTIONS。
· 连接合计表依赖于连接表的值会被设为0.
23.9.9 性能框架连接属性表
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-connection-attribute-tables.html
23.9.10 性能框架用户变量表
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-user-variable-tables.html
23.9.11 性能框架复制表
MySQL 5.7.2,性能框架提供了关于复制信息的表。和show slave status的信息类似:
· Show slave status输出可以阅读进行检查,但是不能用来编程使用。
· 查询结果可以保存到表中,用于分析,设置变量,或者在存储过程上使用。
· 复制表提供了更好的诊断信息,对于多线程slave操作,show slave status使用last_SQL_Errorno和last_sql_error字段报告所有的协调器和工作线程的错误。所以只有最近的错误才能可见。复制表会为每个线程上的错误保存信息不会丢失。
· 每个工作线程的最新的事务在在复制表是可见的。但是show_slave_status。不可见。
· 开发熟悉的性能框架接口可以扩展复制表提供更多的信息。
复制表描述
性能框架提供一下和复制有关的表:
· 关于Slave连接到master的连接信息表:
§ Replication_connection_configuration:配置连接到master的参数。
§ Replication_connection_status:当前连接到master的状态。
· 关于slave事务应用的表
§ replication_applier_configuration:slave中事务应用的配置信息。
§ replication_applier_status:当前事务应用的状态。
· 关于指定线程应用从master获取事务并执行的信息:
§ Replication_applier_status_by_coordinator:applier线程状态,之前叫replication_execute_status_by_coordinator。对于有多个work thread的复制有多个work thread和一个协调线程,对于单线程的这个表为空。
§ Replication_applier_status_by_worker:工作线程应用状态。同上单线程复制表为空。
· 包含复制组成员信息的表:
§ Replication_group_members:提供网络和组成员状态。
§ Replication_group_member_status:提供组成员的统计信息和参与的事务。
复制表生命周期
性能框架在以下状态下写入复制表:
· 在执行change master to之前表为空。
· 在执行change master to之后。配置阐述可以在表上发现。如果这个时候没有活动的slave 线程,那么thread_id列为null,serivce_state的状态为off。
· Start slave之后,没有thread_id字段不为空。线程为空闲或者活动service_status状态为on。线程连接到master server,如果连接建立有个connecting值。
· Stop slave之后,thread_id为null,并且service_State列值为off。
· Stop slave或者thread碰到错误,表信息会被保留。
· Replication_applier_Status_by_worker表只有当slave操作在多线程模式下为非空。如果slave_parallel_workers变量大于0,那么start slave之后,行数和线程个数一样多。
SHOW SLAVE STATUS不再复制表中的信息
Show slave status的信息和复制表中的信息不同,因为这些表主要是面向GTID的复制。不是基于文件名和位置:
· 以下字段关于文件名和位置的没有保存:
Master_Log_File
Read_Master_Log_Pos
Relay_Log_File
Relay_Log_Pos
Relay_Master_Log_File
Exec_Master_Log_Pos
Until_Condition
Until_Log_File
Until_Log_Pos
· Master_info_file字段没有保存。参照master.info文件。
· 以下字段基于server_id,不是server_uuid,没有被保存:
Master_Server_Id
Replicate_Ignore_Server_Ids
· Skip_counter列基于事件个数,不是gtid没有被保存。
· 错误列是last_sql_errno,last_sql_error的别名,因此不被保存
Last_Errno
Last_Error
在性能框架中,replication_applier_status_by_coodinator和表replication _applier_status_by_worker中的last_error_number和last_error_message列保存了错误信息。
· 命令行过滤操作的信息不被保存:
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
· Slave_io_State和slave_sql_running_state列没有保存。如果需要可以通过thread_id关联上perocesslist表获取表中的status值。
· Executed_gtid_set字段可以显示大量的文字。和性能框架表中显示已经被slave应用的事务的GTID。已经被执行的GTID可以通过gtid_executed系统变量获取。
· Seconds_behind_master和relay_log_spae用来将要被决定的状态不保留。
状态变量移动到了复制表
从mysql 5.7.5,以下状态被移动到了性能框架复制表:
Slave_retried_transactions
Slave_last_heartbeat
Slave_received_heartbeats
Slave_heartbeat_period
Slave_running
这些变量用于单源复制,因为只能汇报默认源复制。当有多个复制源,可以使用性能复制表,汇报每个复制渠道的状态。
多源复制
性能框架表的第一列是channel_name.可以看到每个复制源。
23.9.11.1 replication_connection_configure表
表显示了连接到slave服务的连接配置。参数被保存在表中,在change master执行的时候会被修改。
replication_connection_configuration表包含以下列:
· CHANNEL_NAME:复制源名。
· HOST:master的host名。
· PORT:master的端口
· USER:连接用户
· NETWORK_INTERFACE:slave绑定的network接口。
· AUTO_POSITION:如果自定定位被使用了就是1,否则是0
· SSL_ALLOWED, SSL_CA_FILE, SSL_CA_PATH, SSL_CERTIFICATE, SSL_CIPHER, SSL_KEY, SSL_VERIFY_SERVER_CERTIFICATE, SSL_CRL_FILE, SSL_CRL_PATH
这些列显示了slave连接到master的SSL的参数SSL_ALLOWED的值如下:
§ Yes,如果SSL连接到master被允许。
§ No,如果SSL连接到master不被允许。
§ Ignored,如果SSL被允许,但是slave不支持SSL。
Change master to选项还有其他ssl选项:MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_CIPHER, MASTER_SSL_CRL, MASTER_SSL_CRLPATH, MASTER_SSL_KEY, MASTER_SSL_VERIFY_SERVER_CERT。
· CONNECTION_RETRY_INTERVAL:重试的秒数。
· CONNECTION_RETRY_COUNT:失误连接之后重试的次数。
· HEARTBEAT_INTERVAL:复制心跳间隔。
23.9.11.2 replication_connection_status
表保存了io线程的状态,io线程连接到master服务获取binary log信息。
Replication_connection_status相关列:
· CHANNEL_NAME:来源名。
· GOURP_NAME:保留
· SOURCE_UUID:master的server_uuid
· THREAD_ID:io 线程id
· SERVICE_STATE:服务状态
· RECEIVED_TRANSACTION_SET:GTID集合反应已经被slave收到的GTID。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:错误好和错误信息。
· LAST_ERROR_TIMESTAMP:错误的事件格式为YYMMDD HH:MM:SS。
· LAST_HEARTBEAT_TIMESTAMP:最近一次心跳事件的事件。
· COUNT_RECEIVED_HEARTBEATS:收到的心跳次数。
23.9.11.3 replication_applier_configure
这个表显示了影响事务应用的配置参数。参数保存在表可以通过change master to修改。
Replication_applier_configure表有以下列:
· CHANNEL_NAME:复制来源名。
· DIESIRED_DELAY:master到slave的延迟。
23.9.11.4 replication_applier_status
表保存了slave通常事务执行的状态。
replication_aplier_status列名:
· CHANNEL_NAME:复制来源名。
· SERVICE_STATE:显示on表示复制渠道活动或者空闲,如果为off表示应用线程没有活动。
· REMAINING_DELAY:如果slave等待DESIRED_DELAY直到master应用事件。列显示剩下的秒数。
· COUNT_TRANSACTIONS_RETRIES:显示了sql thread应用事务错误,导致重试的次数。
23.9.11.5 replication_applier_status_by_coordinator
对于多线程的slave,slave使用多个工作线程和一个协调线程,协调线程用来管理工作线程,表显示了协调线程的状态。如果是单线程slave,表为空。
Replication_applier_status_by_coordinator列:
· CHANNEL_NAME:复制来源名。
· THREAD_ID:SQL/协调线程id。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:最后一次错误号和错误信息。
· LAST_ERROR_TIMESTRAMP:时间戳格式为YYMMDD HH:MM:SS。
23.9.11.6 replication_applier_statys_by_worker
对于多线程的slave,slave使用多个工作线程和一个协调线程,协调线程用来管理工作线程,表显示了协调线程的状态。如果是单线程slave,表为空。
Replication_applier_status_by_worker:
· CHANNEL_NAME:复制来源名。
· WORKER_ID:worker标识符。Stop slave之后线程id会变成null,workerid会保留。
· THREAD_ID:线程id
· SERVICE_STATE:on,表示活动或者空闲,off表示不存在。
· 表示worker发现的最新的事务,如果gtid_mode=off列的值为ANONYMOUS。如果为on:
§ 如果没有事务被执行,那么就是空。
§ 当有一个事务被执行了列设置成gtid_next。
§ GTID会被保留,知道下一个事务运行完成。
§ 当下一个GTID被其他线程获取,从gtid_next上获得。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:最后一次错误号和错误信息。
· LAST_ERROR_TIMESTRAMP:时间戳格式为YYMMDD HH:MM:SS。
23.9.11.7 replication_group_members
表保存了网络和复制成员组的状态信息。Replication_group_members列:
· CHANNEL_NAME:复制来源名。
· MEMBER_ID:member标示,和uuid一样。
· MEMBER_HOST:host地址或者主机名。
· MEMBER_PORT:端口。
· MEMBER_STATE:
§ OFFLINE:group replication插件已经安装但是没有启动。
§ RECOVERING:服务已经加入到一个group,正在获取数据。
§ ONLINE:成员在全功能状态。
23.9.11.8 replication_group_member_status
表保存了replication group成员的状态,replication_group_member_status:
· CHANNEL_NAME:复制来源名。
· VIEW_ID:该group的当前的view标示符。
· MEMBER_ID:member标示,和uuid一样。
· COUNT_TRANSACTIONS_IN_QUEUE:pending事务的个数。
· COUNT_TRANSACTIONS_CHECKED:已经被成员认证的事务个数。
· COUNT_CONFLICTS_DETECTED:冲突发现个数。
· COUNT_TRANSACTIONS_VALIDATING:事务可以执行检查,但是没有被回收的个数。
· TRANSACTIONS_COMMITTED_ALL_MEMBERS:固化的group事务集合。
· LAST_CONFLICT_FREE_TRANSACTION:最后一个没有冲突的被认证的事务。
23.9.12 性能框架锁相关表
23.9.12.1 metadata_locks
性能框架把元数据锁通过metadata_locks显示。显示一下信息:
· 锁已经被分配
· 锁被请求但是没有被分配。
· 锁请求但是被死锁kill或者锁等待超时而被取消。
这些信息可以了解元数据锁和会话之间的关系。可以查看等待的锁,也可以查看已经获取的锁。
Metadata_locks表只读,不能写入。默认是自动大小的,也可以通过启动参数配置大小:performance_schema_max_metadata_locks。
表默认是被禁用的,拖过设置setup_instruments的/locl/metadata/sql/mdl来启动。
性能框架维护内容,使用lock_status表示锁的状态:
· 当元数据锁被请求并且马上获取,行的状态的是GRANTED。
· 当元数据锁被请求但是没有马上获得,行的状态为pending。
· 当之前请求的元数据锁获取了,行的状态改为granted。
· 当元数据锁被释放,行被删除。
· 当pending的锁请求被死锁发现器取消,状态改为victim。
· 当pending的锁超时,状态变为pending to timeout。
· 当分配的锁或者pending的锁被kill,状态变为killed。
· 当VICTIM,TIMEOUT,KILLED被通知之后行会被删除。
· PRE_ACQUIRE_NOTIFY,POST_RELEASE_NOTIFY状态,当获取锁或者释放锁时,lock子系统通知所在的存储引擎的状态。
Metadata_locks列:
· OBJECT_TYPE:可以是这些值的其中一个. GLOBAL, SCHEMA, TABLE, FUNCTION, PROCEDURE, TRIGGER (currently unused), EVENT, COMMIT, USER LEVEL LOCK, TABLESPACE, LOCKING SERVICE。
如果值为USER LEVEL LOCK表示从get_lock()获取锁,如果是LOCKING SERVICE表示使用lock service获取说。
· OBJECT_SCHEMA:对象所在的schema
· OBJECT_NAME:对象名
· OBJECT_INSTANCE_BEGIN:记录点对象在内存中的地址。
· LOCK_TYPE:锁的类型,INTENTION_EXCLUSIVE, SHARED, SHARED_HIGH_PRIO, SHARED_READ, SHARED_WRITE, SHARED_UPGRADABLE, SHARED_NO_WRITE, SHARED_NO_READ_WRITE, or EXCLUSIVE.
· LOCK_DURATION:lock持续的期限。可以是这些值STATEMENT, TRANSACTION, EXPLICIT. STATEMENT 和TRANSACTION从语句或者事务的开始直到语句或者事务的结束。
· LOCK_STATUS:锁的状态,PENDING, GRANTED, VICTIM, TIMEOUT, KILLED, PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY.
· SOUCE:源代码文件中的文件名和位置。
· OWNER_THREAD_ID:请求元数据的线程。
· OWNER_EVENT_ID:请求锁的事件id。
23.9.12.2 table_handles
通过表table_handles返回表锁信息。Table_handle显示了每个打开表的handle的锁信息。那个表被打开了,如何被锁定的,是哪个线程锁的。
Table_handles是只读表,不能修改,表列如下:
· OBJECT_TYPE:被table handle打开的表。
· OBJECT_SCHEMA:表所在的schema。
· OBJECT_NAME:记录点对象名。
· OBJECT_INSTANCE_BEGIN:记录点对象在内存中的地址。
· OWNER_THREAD_ID:请求元数据的线程。
· OWNER_EVENT_ID:请求锁的事件id。
· INTERNAL_LOCK:SQL级别使用的表锁。值如下: READ, READ WITH SHARED LOCKS, READ HIGH PRIORITY, READ NO INSERT, WRITE ALLOW WRITE, WRITE CONCURRENT INSERT, WRITE LOW PRIORITY, WRITE。
· EXTERNAL_LOCK:存储引擎级别使用的表锁,READ EXTERNAL ,WRITE EXTERNAL
23.9.13 性能框架系统变量表
MySQL维护了很多系统变量,系统变量在这些表是可用的:
· Global_variables:全局系统变量。如果应用程序只要全局值可以使用这个表。
· Session_variables:当前会话的系统变量。还有没有session变量部分的global变量
· Variables_by_thread:每个会话的系统变量。
这些会话级别的变量只包含了活动会话的变量。这些表不支持truncate table。
Global_variablees和session_variables表有这些列:
· VARIABLES_NAME:变量名
· VARIABLES_VALUE:变量的值。
Variables_by_thread的列:
· Thread_id:线程id
· VARIABLES_NAME:变量名
· VARIABLES_VALUE:变量的值。
Variables_by_thread表包含了后台线程的系统变量信息。如果不是所有的线程记录,那么表内有些行会小时。这个时候Performance_schema_thread_instance_lost状态变量大于0 。
23.9.14 性能框架系统状态变量表
和系统变量表类似,具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-status-variable-tables.html
23.9.15 性能框架统计表
等待事件统计表:
· Events_waits_summary_global_by_event_name:等待事件根据每个事件进行合计。
· Events_waits_summary_by_instance:等待事件根据每个instance进行统计。
· Events_waits_summary_by_thread_by_event_name:根据线程和事件名合计的表。
Stage统计表:
· Events_stages_summary_by_thread_by_event_name:stage等待和线程id统计的表。
· Events_stages_summary_global_by_eevnt_name:stage等待中每个事件名的统计表。
语句统计表:
· Events_statements_summary_by_digest:每个schema和digest后的统计表。
· Events_statements_summary_by_thread_by_event_name:语句事件名和线程的统计表。
· Events_statements_summary_global_by_event_name:每个语句事件名的统计表。
· Events_statements_summary_by_program:每个存储程序的统计(存储过程和存储函数)。
· Prepared_statements_instances:预备的语句实例和统计信息。
事务统计表:
· Events_transactions_summary_by_account_by_event_name:每个账号发起的事件统计。
· Events_transactions_summary_by_host_by_event_name:每个host发起的事务事件统计。
· Events_transactions_summary_by_thread_by_event_name:每个线程发起的事务事件统计。
· Events_transactions_summary_by_user_by_event_name:每个用户发起的事务事件统计。
· Events_transactions_summary_global_by_event_name:事务事件名统计。
对象等待统计:
· Objects_summary_global_by_type:对象合计。
文件IO统计:
· File_summary_by_event_name:合计所有文件io事件名。
· File_summary_by_instance:每个文件实例的合计。
表IO和锁等待统计:
· Table_io_waits_summary_by_index_usage:每个所有的表io等待。
· Table_io_waits_summary_by_table:每个表的io等待。
· Table_io_waits_summary_by_table:每个表的锁等待。
连接统计:
· Events_waits_summary_by_account_by_event_name:每个账号发起的等待事件统计。
· Events_waits_summary_by_user_by_event_name:每个用户发起的等待事件统计。
· Events_waits_summary_by_host_by_event_name:每个host发起的等待事件合计。
· Events_stages_summary_by_account_by_event_name:每个账号stage事件统计。
· Events_stages_summary_by_user_by_event_nam:每个用户发起的stage事件统计。
· Events_stages_summary_by_ host_by_event_name:每个host发起的stage事件合计。
· Events_statements_summary_by_digest:每个schema下的所有digest。
· Events_statements_summary_account_by_event_name:每个账号发起的语句事件。
· Events_statements_summary_by_user_by_event_name:每个用户发起的语句事件。
· Events_statements_summary_host_by_event_name:每个host发起的语句事件。
Socket统计:
· Socket_summary_by_instance:每个实例的socket等待和io合计。
· Socket_summary_by_event_name:socket等待和io合计。
内存统计:
· Memory_summary_global_by_event_name:内存操作事件合计。
· Memory_summary_by_thead_by_event_name:每个线程内存操作合计。
· Memory_summary_by_account_by_event_name:每个账号内存操作合计。
· Memory_summary_by_user_by_event_name:每个用户内存操作合计。
· Memory_summary_by_host_by_event_name:每个host内存操作合计。
状态变量统计:
· Status_by_account:状态变量账号合计。
· Status_by_host:状态变量host合计
· Status_by_user:状态变量用户合计
23.9.16 性能框架其他表
除了上面你的表还有3个表:
· Host_cache:内部host cache信息。
· Performance_timers:事件可用定时器。
· Threads:服务的线程表。
23.10 性能框架选项和变量
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-option-variable-reference.html
23.11 性能框架命令选项
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-options.html
23.12 性能框架系统变量
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-system-variables.html
23.13 性能框架状态变量
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-status-variables.html
23.14 性能框架内存分配模型
在mysql 5.7.6之前,性能框架使用以下内存分配模型:
· 所有的内存在启动时分配。
· 服务操作的时候不分配内存。
· 服务操作的时候不释放内存。
· 在服务关闭的时候释放内存。
使用这个模型,性能框架会分配大量的内存,除非显示的配置。Mysql 5.7.6之后的分配模型:
· 可以在服务启动的时候分配。
· 可以在服务操作的时候额外分配。
· 在服务操作的时候不释放。
· 在服务关闭的时候释放内存。
这样可以根据负荷来调整内存使用,不是现实配置。
有一些性能框架配置参数是自动分配,也可以手动分配:
performance_schema_accounts_size
performance_schema_hosts_size
performance_schema_max_cond_instances
performance_schema_max_file_instances
performance_schema_max_index_stat
performance_schema_max_metadata_locks
performance_schema_max_mutex_instances
performance_schema_max_prepared_statements_instances
performance_schema_max_program_instances
performance_schema_max_rwlock_instances
performance_schema_max_socket_instances
performance_schema_max_table_handles
performance_schema_max_table_instances
performance_schema_max_table_lock_stat
performance_schema_max_thread_instances
performance_schema_users_size
对于自动配置的参数,配置基本如下:
· 如果为-1,默认,参数是自动配置的。
§ 初始对应的内部buffer为空,没有内存。
§ 当性能框架开始收集数据,没存被分配到想要的buffer。buffer大小没有上限,随着负荷上升上涨。
· 如果设置为0:
§ 初始内部buffer为空,也不会分配内存。
· 如果设置的N>0:
§ 对象的内部buffer为空,并且不分配内存。
§ 当数据开始收集,内存开始分配,直到设置的大小。
§ 一旦buffer大小到达N,内存就不再分配。性能框架收集的数据会丢失,对应的状态变量的lost instance会增加。
为了查看性能框架使用了多少内存,检查记录点。性能框架收集了每个buffer的内存使用信息。这样可以跟踪每个buffer的内存使用情况。记录点,memory/performance _schema/。因为这些buffer是全局的,所以只在memory_summary_global_by_event_ name上显示。查询如下:
SELECT * FROM memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/performance_schema/%';
23.15 性能框架和
具体看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-and-plugins.html
23.16 使用性能框架诊断
性能框架可以让dba来做一些性能调整,比如一个重复出现的性能问题:
1.运行用例
2.使用性能框架表,分析根本的性能问题。分析严重依赖于post过滤。
3.问题区域已经划出,禁用对应的记录点。比如如果分析出和文件io不相关,禁用io的记录点。
4.重复 步骤1-3,这样可以减少干扰找出真正的问题。
5.明确了性能瓶颈的原因:
§ 调整服务参数
§ 调整查询。
§ 调整数据库结构
§ 调整代码。
6.重复步骤1,查看对性能的影响。
在性能调优的时候,mutex_instances.locked_by_thread_id,rwlock_instances. write_locked_by_thread_id列十分重要。比如:
1.线程1,在等待一个信号量。
2.可以使用以下语句查看等待的信号量:
SELECT * FROM events_waits_current WHERE THREAD_ID = thread_1;
3.然后查看那个线程持有着这个信号量:
SELECT * FROM mutex_instances WHERE OBJECT_INSTANCE_BEGIN = mutex_A;
4.查看线程2在做什么:
SELECT * FROM events_waits_current WHERE THREAD_ID = thread_2;
23.17 迁移到性能框架系统和状态变量表
Information_schema有表包含了系统和状态变量信息,MySQL 5.7.6之后,性能框架也包含了系统变量和状态变量信息。性能框架的表会取代information_schema上的表。
在mysql 5.6查看状态变量和系统变量来自于:
SHOW VARIABLES
SHOW STATUS
INFORMATION_SCHEMA.GLOBAL_VARIABLES
INFORMATION_SCHEMA.SESSION_VARIABLES
INFORMATION_SCHEMA.GLOBAL_STATUS
INFORMATION_SCHEMA.SESSION_STATUS
Mysql 5.7.6,性能框架也包含了系统变量和状态变量:
performance_schema.global_variables
performance_schema.session_variables
performance_schema.variables_by_thread
performance_schema.global_status
performance_schema.session_status
performance_schema.status_by_thread
performance_schema.status_by_account
performance_schema.status_by_host
performance_schema.status_by_user
MySQL 5.7.6增加了show_compatibility_56系统变量,如果为on:
· 当从information_schema中输出,会出现警告。
· 在mysql 5.7.6,使用show的where语句就会警告。MySQL 5.7.8之后就不会。
当变量为off,不启动兼容模式:
· 搜索information_schema表会报错。
· Show语句输出的数据来至于性能框架表。
· 这些slave_XXX的状态变量不可用:
Slave_heartbeat_period
Slave_last_heartbeat
Slave_received_heartbeats
Slave_retried_transactions
Slave_running
应该从性能框架的复制相关的表中获取数据。
迁移和权限
访问性能框架中的系统变量和状态变量需要select权限。如果show_compatibility_56为off,那么show variables和show status也需要select权限,如果兼容性关闭,这些语句输出来至于性能框架的global_variables,session_variables,global_status, session_status表。
在mysql 5.7.9,这些表在性能矿建中访问不需要select权限。对应的show variables和show status也不需要权限。
之后的发布,information_schema变量表和show_compatibility_56会被删除,show输出基于性能框架表。