MySQL锁相关查询实用SQL汇总
转载自文章:https://www.modb.pro/doc/139520
一、查询是否锁表
– 查看哪些表锁到了
show OPEN TABLES where In_use > 0;
– 查看进程号
show processlist;
–删除进程
kill 1085850
查看正在锁的事务:
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
查看等待锁的事务:
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
– 查出死锁进程:SHOW PROCESSLIST
– 杀掉进程 kill id;
其它关于查看死锁的命令:
1:查看当前的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
2:查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3:查看当前等锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4:select * from sys.innodb_lock_waits\G
– 查询死锁详情
SELECT r.trx_id waiting_trx_id,r.trx_mysql_thread_id waiting_thread,
TIMESTAMPADD(SECOND,r.trx_wait_started,CURRENT_TIMESTAMP) wait_time,
r.trx_query waiting_query,
l.lock_table waiting_table_lock,
b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread,
SUBSTRING(p.HOST,1,INSTR(p.HOST,’:’)-1) blocking_host,
SUBSTRING(p.HOST,INSTR(p.HOST,’:’)+1) blocking_port,
IF(p.COMMAND =‘Sleep’,p.TIME,0) idle_in_trx,
b.trx_query blocking_query
from information_schema.INNODB_LOCK_WAITS w
INNER JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_lock_id
INNER JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id
INNER JOIN information_schema.INNODB_LOCKS l ON l.lock_id = w.requested_lock_id
LEFT JOIN information_schema.PROCESSLIST p ON p.id = b.trx_mysql_thread_id
ORDER BY wait_time desc;
show engine innodb status \G
show engine innodb status 是mysql提供的一个用于查看innodb引擎时间信息的工具,就目前来说有两处比较
常用的地方一、死锁分析 二、innodb内存使用情况
二、查看内存使用情况以及死锁分析
2.1、 查看buffer pool 的内存配置
show variables like ‘innodb_buffer_pool_size’;
±------------------------±----------+
| Variable_name | Value |
±------------------------±----------+
| innodb_buffer_pool_size | 268435456 |
±------------------------±----------+
1 row in set (0.01 sec)
mysql> select 268435456/1024/1024 as innodb_buffer_pool_size_in_MB;
±------------------------------+
| innodb_buffer_pool_size_in_MB |
±------------------------------+
| 256.00000000 |
±------------------------------+
1 row in set (0.00 sec)
2.2、通过show engine innodb status 查看内存使用明细
show engine innodb status ;
BUFFER POOL AND MEMORY
Total large memory allocated 274857984
Dictionary memory allocated 116177
Buffer pool size 16382
Free buffers 16002
Database pages 380
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 345, created 35, written 37
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 380, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
2.3、对BUFFER POOL AND MEMORY 各项的说明
1)、Total large memory allocated 分配给innodb 的总内存大小、单位byte
2)、Dictionary memory allocated 分析给innodb 数据字典的内存大小、单位byte
3)、Buffer pool size innodb buffer pool的大小、单位page 如果page的大小设置为16k的话
那么这个值乘以16就是innodb buffer pool 的大小(单位kb)
show global variables like ‘innodb_buffer_pool_size’;
±------------------------±----------+
| Variable_name | Value |
±------------------------±----------+
| innodb_buffer_pool_size | 268435456 |
±------------------------±----------+
1 row in set (0.00 sec)
mysql> select 16384161024 as innodb_buffer_pool_size_in_byte;
±--------------------------------+
| innodb_buffer_pool_size_in_byte |
±--------------------------------+
| 268435456 |
±--------------------------------+
4)、Free buffers innodb buffer pool中空闲页面的数量,单位page
5)、Database pagesinnodb buffer pool中非空闲页面的数量, 单位page
6)、Old database pages old 子列表中的页面数量,单位page
7)、Modified db pages 当前buffer pool中被修改的页面数量,单位page
8)、Pending reads 数据由磁盘读到buffer pool,被挂起的次数
9)、Pending writes: LRUinnodb buffer pool old 子列表的页面被淘汰出内存,要写入到磁盘,但是
这个写入被挂起的次数
10)、flush listcheck point 操作期间页面要被写入到磁盘,但是这个写入被挂起的次数
11)、single page单个页面要被写入到磁盘,但是这个写入过程被挂起的次数
12)、Pages made young页面由old列表移动到new列表的次数
13)、not young 页面由new列表移动表old列表的次数
14)、youngs/s 平均每秒有多少个页面由old移动到new
15)、non-youngs/s 平均每秒有多少个页面由new移动到old
16)、Pages read 从buffer pool中读出页面的总数
17)、created 在innodb buffer pool中创建页面的总数
18)、written innodb buffer pool中被写过的页面总数
19)、reads/s 平均每秒从innodb buffer pool中读多少页
20)、creates/s 平均每秒innodb buffer pool要创建多少页
21)、writes/s平均每少innodb buffer pool有多少页面被写
22)、buffer pool hit rateinnodb buffer pool 命中率
23)、Pages read ahead 平均每秒read ahead的次数
24)、evicted without access平均每秒页面淘汰的次数
25)、Random read ahead 平均每秒random read ahead的次数
三、MYSQL中事务和锁相关的表INNODB_LOCKS, INNODB_LOCK_WAITS,INNODB_TRX
3.1、事务超时或锁相关SQL
通常我们遇到事务超时或锁相关问题时,直接运行下面SQL语句即可进行简单检查:
–查看事务
select * from information_schema.INNODB_TRX;
表字段解释:
事务ID
trx_id varchar(18) NOT NULL DEFAULT ‘’,
事务状态, 允许值是 RUNNING,LOCK WAIT, ROLLING BACK,和 COMMITTING。
trx_state varchar(13) NOT NULL DEFAULT ‘’,
事务开始时间
trx_started datetime NOT NULL DEFAULT ‘0000-00-00 00:00:00’,
事务当前等待的锁的ID,如果TRX_STATE是LOCK WAIT;否则NULL。
trx_requested_lock_id varchar(105) DEFAULT NULL,
事务开始等待锁的时间
trx_wait_started datetime DEFAULT NULL,
事务权重, 反映(但不一定是准确计数)更改的行数和事务锁定的行数。为了解决死锁, InnoDB选择权重最小的事务作为“受害者”进行回滚。无论更改和锁定行的数量如何,更改非事务表的事务都被认为比其他事务更重。
trx_weight bigint(21) unsigned NOT NULL DEFAULT ‘0’,
MySQL 线程 ID。 这个id很重要,如果发现某个事务一直在等待无法结束的话,可以通过这个ID kill掉。
trx_mysql_thread_id bigint(21) unsigned NOT NULL DEFAULT ‘0’,
事务正在执行的 SQL 语句。
trx_query varchar(1024) DEFAULT NULL,
交易的当前操作,如果有的话;否则 NULL。
trx_operation_state varchar(64) DEFAULT NULL,
InnoDB处理此事务的当前 SQL 语句时使用 的表数。
trx_tables_in_use bigint(21) unsigned NOT NULL DEFAULT ‘0’,
InnoDB当前 SQL 语句具有行锁 的表数。(因为这些是行锁,而不是表锁,尽管某些行被锁定,但通常仍可以由多个事务读取和写入表。)
trx_tables_locked bigint(21) unsigned NOT NULL DEFAULT ‘0’,
事务保留的锁数。
trx_lock_structs bigint(21) unsigned NOT NULL DEFAULT ‘0’,
此事务的锁结构在内存中占用的总大小。
trx_lock_memory_bytes bigint(21) unsigned NOT NULL DEFAULT ‘0’,
此事务锁定的大致数量或行数。该值可能包括物理上存在但对事务不可见的删除标记行。
trx_rows_locked bigint(21) unsigned NOT NULL DEFAULT ‘0’,
此事务中修改和插入的行数。
trx_rows_modified bigint(21) unsigned NOT NULL DEFAULT ‘0’,
trx_concurrency_tickets bigint(21) unsigned NOT NULL DEFAULT ‘0’,
–查看锁
select * from information_schema.INNODB_LOCKS;
–查看锁等待
select * from information_schema.INNODB_LOCK_WAITS;
3.2、各个表字段说明
INNODB_TRX:提供有关当前正在内部执行的每个事务的信息 InnoDB,包括事务是否在等待锁定,事务何时启动以及事务正在执行的SQL语句(如果有)。
详见https://dev.mysql.com/doc/refman/5.7/en/innodb-trx-table.html
列名 描述
TRX_ID 事务Id
TRX_WEIGHT 事务的权重,反映(但不一定是确切的计数)更改的行数和事务锁定的行数。要解决死锁,请 InnoDB选择权重最小的事务作为回滚的“ 受害者 ”。无论更改和锁定行的数量如何,已更改非事务表的事务都被认为比其他事务更重。
TRX_STATE 事务执行状态。允许值是 RUNNING,LOCK WAIT, ROLLING BACK,和 COMMITTING。
TRX_STARTED 交易开始时间。
TRX_REQUESTED_LOCK_ID 事务当前正在等待的锁的ID,如果TRX_STATE是LOCK WAIT; 否则NULL。
TRX_WAIT_STARTED 交易开始等待锁定的时间,如果 TRX_STATE是LOCK WAIT; 否则NULL。
TRX_MYSQL_THREAD_ID MySQL线程ID,与show processlist中的ID值相对应
TRX_QUERY 事务正在执行的SQL语句
TRX_OPERATION_STATE 交易的当前操作,如果有的话; 否则 NULL。
TRX_TABLES_IN_USE InnoDB处理此事务的当前SQL语句时使用 的表数。
TRX_TABLES_LOCKED InnoDB当前SQL语句具有行锁定 的表的数量。(因为这些是行锁,而不是表锁,所以通常仍可以通过多个事务读取和写入表,尽管某些行被锁定。)
TRX_LOCK_STRUCTS 事务保留的锁数。
TRX_LOCK_MEMORY_BYTES 内存中此事务的锁结构占用的总大小
TRX_ROWS_LOCKED 此交易锁定的大致数字或行数。该值可能包括实际存在但对事务不可见的删除标记行
TRX_ROWS_MODIFIED 此事务中已修改和插入的行数。
TRX_CONCURRENCY_TICKETS 一个值,指示当前事务在被换出之前可以执行多少工作
TRX_ISOLATION_LEVEL 当前事务的隔离级别。
TRX_UNIQUE_CHECKS 是否为当前事务打开或关闭唯一检查。例如,在批量数据加载期间可能会关闭它们
TRX_FOREIGN_KEY_CHECKS 是否为当前事务打开或关闭外键检查。例如,在批量数据加载期间可能会关闭它们
TRX_LAST_FOREIGN_KEY_ERROR 最后一个外键错误的详细错误消息(如果有); 否则NULL
TRX_ADAPTIVE_HASH_LATCHED 自适应哈希索引是否被当前事务锁定。当自适应哈希索引搜索系统被分区时,单个事务不会锁定整个自适应哈希索引。自适应哈希索引分区由innodb_adaptive_hash_index_parts,默认设置为8。
TRX_ADAPTIVE_HASH_TIMEOUT 是否立即为自适应哈希索引放弃搜索锁存器,或者在MySQL的调用之间保留它。当没有自适应哈希索引争用时,该值保持为零,语句保留锁存器直到它们完成。在争用期间,它倒计时到零,并且语句在每次行查找后立即释放锁存器。当自适应散列索引搜索系统被分区(受控制 innodb_adaptive_hash_index_parts)时,该值保持为0。
TRX_IS_READ_ONLY 值为1表示事务是只读的。
TRX_AUTOCOMMIT_NON_LOCKING 值为1表示事务是 SELECT不使用FOR UPDATEor或 LOCK IN SHARED MODE子句的语句,并且正在执行, autocommit因此事务将仅包含此一个语句。当此列和TRX_IS_READ_ONLY都为1时,InnoDB优化事务以减少与更改表数据的事务关联的开销
INNODB_LOCKS:提供有关InnoDB 事务已请求但尚未获取的每个锁的信息,以及事务持有的阻止另一个事务的每个锁。
详见https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-table.html
列名 描述
LOCK_ID 一个唯一的锁ID号,内部为 InnoDB。
LOCK_TRX_ID 持有锁的交易的ID
LOCK_MODE 如何请求锁定。允许锁定模式描述符 S,X, IS,IX, GAP,AUTO_INC,和 UNKNOWN。锁定模式描述符可以组合使用以识别特定的锁定模式。
LOCK_TYPE 锁的类型
LOCK_TABLE 已锁定或包含锁定记录的表的名称
LOCK_INDEX 索引的名称,如果LOCK_TYPE是 RECORD; 否则NULL
LOCK_SPACE 锁定记录的表空间ID,如果 LOCK_TYPE是RECORD; 否则NULL
LOCK_PAGE 锁定记录的页码,如果 LOCK_TYPE是RECORD; 否则NULL。
LOCK_REC 页面内锁定记录的堆号,如果 LOCK_TYPE是RECORD; 否则NULL。
LOCK_DATA 与锁相关的数据(如果有)。如果 LOCK_TYPE是RECORD,是锁定的记录的主键值,否则NULL。此列包含锁定行中主键列的值,格式为有效的SQL字符串。如果没有主键,LOCK_DATA则是唯一的InnoDB内部行ID号。如果对键值或范围高于索引中的最大值的间隙锁定,则LOCK_DATA 报告supremum pseudo-record。当包含锁定记录的页面不在缓冲池中时(如果在保持锁定时将其分页到磁盘),InnoDB不从磁盘获取页面,以避免不必要的磁盘操作。相反, LOCK_DATA设置为 NULL。
INNODB_LOCK_WAITS:包含每个被阻止InnoDB 事务的一个或多个行,指示它已请求的锁以及阻止该请求的任何锁。
详见https://dev.mysql.com/doc/refman/5.7/en/innodb-lock-waits-table.html
列名 描述
REQUESTING_TRX_ID 请求(阻止)事务的ID。
REQUESTED_LOCK_ID 事务正在等待的锁的ID。
BLOCKING_TRX_ID 阻止事务的ID。
BLOCKING_LOCK_ID 由阻止另一个事务继续进行的事务所持有的锁的ID
3.3、查询sys.innodb_lock_waits表以及元数据锁的超时时间
查询sys.innodb_lock_waits表可以看到更详细的信息,包括等待时间、被锁住的数据库对象名称、被阻塞的SQL语句、阻塞源SQL语句及其trx_id和pid、杀会话语句。
SQL> select * from sys.innodb_lock_waits \G
–查看元数据锁的超时时间(秒),超过该设定时间等待元数据锁的事务会自动回滚。
show global variables like ‘lock_wait_timeout’;
四、performance_schema库查看锁SQL
4.1、查询锁相关SQL
–查看执行完成但是没提交的表:
select d.trx_started ,a.thread_id,b.processlist_id,a.SQL_text from performance_schema.events_statements_current a join performance_schema.threads b on a.thread_id=b.thread_id join information_schema.processlist c on b.processlist_id=c.id join information_schema.innodb_trx d on c.id=d.trx_mysql_thread_id order by d.trx_started;
–查看MDL锁的信息:
select a.thread_id,b.processlist_id,a.SQL_text from performance_schema.events_statements_current a join performance_schema.threads b on a.thread_id=b.thread_id;
select * from performance_schema.metadata_locks where owner_thread_id != sys.ps_thread_id(connection_id());
–等待锁的语句:
SELECT * FROM performance_schema.events_statements_history WHERE thread_id IN(
SELECT b.THREAD_ID FROM sys.innodb_lock_waits AS a , performance_schema.threads AS b
WHERE a.waiting_pid = b.PROCESSLIST_ID)
ORDER BY timer_start ASC;
–看持有锁的语句:
SELECT * FROM performance_schema.events_statements_history WHERE thread_id IN(
SELECT b.THREAD_ID FROM sys.innodb_lock_waits AS a , performance_schema.threads AS b
WHERE a.blocking_pid = b.PROCESSLIST_ID)
ORDER BY timer_start ASC;
–查看当前被锁的语句:
SELECT * FROM performance_schema.events_statements_history WHERE thread_id IN(
SELECT b.THREAD_ID FROM sys.innodb_lock_waits AS a , performance_schema.threads AS b
WHERE a.waiting_pid = b.PROCESSLIST_ID)
ORDER BY timer_start ASC;
–查询当前存在的数据锁:
SELECT * FROM performance_schema.data_locks \G
备注:
其中LOCK_TYPE=TABLE为表锁,LOCK_TYPE=RECORD为行锁。LOCK_MODE包含字母X为独占锁。
–查询数据锁阻塞的线程信息:
SELECT * FROM performance_schema.data_lock_waits \G
备注:
其中BLOCKING_THREAD_ID为阻塞源线程,REQUESTING_THREAD_ID为被阻塞的线程。
–视图table_handles中记录了持有和请求表锁的信息:
select object_type,object_schema,object_name,owner_thread_id
from performance_schema.table_handles where owner_thread_id is not null;
查询当前等待事件主要用到以下三张表:
events_waits_current
events_waits_history
events_waits_history_long
需要更新performance_schema.setup_instruments来启用wait性能事件收集。
配置项修改示例:
打开events_waits_current表当前等待事件记录功能
mysql> UPDATE setup_consumers SET ENABLED =‘NO’ WHERE NAME =‘events_waits_current’;
关闭历史事件记录功能
mysql> UPDATE setup_consumers SET ENABLED =‘NO’ where name like ‘%history%’;
where条件 ENABLED =‘YES’ 即为打开对应的记录表功能
…
五、等待事件表
通常,我们在碰到性能瓶颈时,如果其他的方法难以找出性能瓶颈的时候(例如:硬件负载不高、SQL优化和库表结构优化都难以奏效的时候),我们常常需要借助于等待事件来进行分析,找出在MySQL Server内部,到底数据库响应慢是慢在哪里。
等待事件记录表包含三张表,这些表记录了当前与最近在MySQL实例中发生了哪些等待事件,时间消耗是多少。
events_waits_current表:记录当前正在执行的等待事件的,每个线程只记录1行记录
events_waits_history表:记录已经执行完的最近的等待事件历史,默认每个线程只记录10行记录
events_waits_history_long表:记录已经执行完的最近的等待事件历史,默认所有线程的总记录行数为10000行
要注意:等待事件相关配置中,setup_instruments表中绝大部分的等待事件instruments都没有开启(IO相关的等待事件instruments默认大部分已开启),setup_consumers表中waits相关的consumers配置默认没有开启
5.1、events_waits_current 表
events_waits_current表包含当前的等待事件信息,每个线程只显示一行最近监视的等待事件的当前状态
在所有包含等待事件行的表中,events_waits_current表是最基础的数据来源。其他包含等待事件数据表在逻辑上是来源于events_waits_current表中的当前事件信息(汇总表除外)。例如,events_waits_history和events_waits_history_long表中的数据是events_waits_current表数据的一个小集合汇总(具体存放多少行数据集合有各自的变量控制)
表记录内容示例(这是一个执行select sleep(100);语句的线程等待事件信息)
root@localhost : performance_schema 12:15:03> select * from events_waits_current where EVENT_NAME=‘wait/synch/cond/sql/Item_func_sleep::cond’\G;
*************************** 1. row ***************************
THREAD_ID: 46
EVENT_ID: 140
END_EVENT_ID: NULL
EVENT_NAME: wait/synch/cond/sql/Item_func_sleep::cond
SOURCE: item_func.cc:5261
TIMER_START: 14128809267002592
TIMER_END: 14132636159944419
TIMER_WAIT: 3826892941827
SPINS: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
INDEX_NAME: NULL
OBJECT_TYPE: NULL
OBJECT_INSTANCE_BEGIN: 140568905519072
NESTING_EVENT_ID: 116
NESTING_EVENT_TYPE: STATEMENT
OPERATION: timed_wait
NUMBER_OF_BYTES: NULL
FLAGS: NULL
1 row in set (0.00 sec)
上面的输出结果中,TIMER_WAIT字段即表示该事件的时间开销,单位是皮秒,在实际的应用场景中,我们可以利用该字段信息进行倒序排序,以便找出时间开销最大的等待事件。
5.2、events_waits_current 表完整的字段含义
THREAD_ID,EVENT_ID: 与事件关联的线程ID和当前事件ID。 THREAD_ID 和 EVENT_ID 值构成了该事件信息行的唯一标识(不会有重复的 THREAD_ID+EVENT_ID 值)
END_EVENT_ID :当一个事件正在执行时该列值为NULL,当一个事件执行结束时把该事件的ID更新到该列
EVENT_NAME: 产生事件的 instruments 名称。该名称来自 setup_instruments 表的 NAME 字段值
SOURCE :产生该事件的instruments所在的源文件名称以及检测到该事件发生点的代码行号。您可以查看源代码来确定涉及的代码。例如,如果互斥锁、锁被阻塞,您可以检查发生这种情况的上下文环境
TIMER_START,TIMER_END,TIMER_WAIT :事件的时间信息。单位皮秒(万亿分之一秒)。 TIMER_START和TIMER_END值表示事件开始和结束时间。 TIMER_WAIT是事件经过时间(即事件执行了多长时间)
如果事件未执行完成,则TIMER_END为当前计时器时间值(当前时间),TIMER_WAIT为目前为止所经过的时间(TIMER_END - TIMER_START)
如果采集该事件的instruments配置项TIMED = NO,则不会收集事件的时间信息,TIMER_START,TIMER_END和TIMER_WAIT在这种情况下均记录为NULL
SPINS:对于互斥量和自旋次数。如果该列值为NULL,则表示代码中没有使用自旋或者说自旋没有被监控起来
OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE,OBJECT_INSTANCE_BEGIN: 这些列标识了一个正在被执行的对象,所以这些列记录的信息含义需要看对象是什么类型, 下面按照不同对象类型分别对这些列的含义进行说明:
-
对于同步对象(cond,mutex,rwlock):
-
1)、OBJECT_SCHEMA,OBJECT_NAME和OBJECT_TYPE列值都为NULL
-
2)、 OBJECT_INSTANCE_BEGIN 列是内存中同步对象的地址。 OBJECT_INSTANCE_BEGIN 除了不同的值标记不同的对象之外,其值本身没有意义。但 OBJECT_INSTANCE_BEGIN 值可用于调试。例如,它可以与 GROUP BY OBJECT_INSTANCE_BEGIN 子句一起使用来查看 1,000 个互斥体(例如:保护 1,000 个页或数据块)上的负载是否是均匀分布还是发生了一些瓶颈。如果在日志文件或其他调试、性能工具中看到与该语句查看的结果中有相同的对象地址,那么,在你分析性能问题时,可以把这个语句查看到的信息与其他工具查看到的信息关联起来。
-
对于文件I/O对象:
-
1)、 OBJECT_SCHEMA 列值为 NULL
-
2)、 OBJECT_NAME 列是文件名
-
3)、 OBJECT_TYPE 列为 FILE
-
4)、 OBJECT_INSTANCE_BEGIN 列是内存中的地址,解释同上
-
对于套接字对象:
-
1)、OBJECT_NAME列是套接字的IP:PORT值
-
2)、OBJECT_INSTANCE_BEGIN列是内存中的地址,解释同上
-
对于表I/O对象:
-
1)、OBJECT_SCHEMA列是包含该表的库名称
-
2)、OBJECT_NAME列是表名
-
3)、OBJECT_TYPE列值对于基表或者TEMPORARY TABLE临时表,该值是table,注意:对于在join查询中select_type为DERIVED,subquery等的表可能不记录事件信息也不进行统计
-
4)、OBJECT_INSTANCE_BEGIN列是内存中的地址,解释同上
INDEX_NAME: 表示使用的索引的名称。 PRIMARY 表示使用到了主键。 NULL 表示没有使用索引
NESTING_EVENT_ID :表示该行信息中的 EVENT_ID 事件是嵌套在哪个事件中,即父事件的 EVENT_ID
NESTING_EVENT_TYPE :表示该行信息中的 EVENT_ID 事件嵌套的事件类型。有效值有: TRANSACTION,STATEMENT,STAGE 或 WAIT ,即父事件的事件类型,如果为 TRANSACTION 则需要到事务事件表中找对应 NESTING_EVENT_ID 值的事件,其他类型同理
OPERATION :执行的操作类型,如: lock、read、write、timed_wait
NUMBER_OF_BYTES :操作读取或写入的字节数或行数。对于文件IO等待,该列值表示字节数;对于表 I/O 等待( wait/io/table/sql/handler instruments 的事件),该列值表示行数。如果值大于1,则表示该事件对应一个批量 I/O 操作。 以下分别对单个表 IO 和批量表 IO 的区别进行描述:
MySQL的join查询使用嵌套循环实现。performance_schema instruments的作用是在join查询中提供对每个表的扫描行数和执行时间进行统计。示例:join查询语句:SELECT … FROM t1 JOIN t2 ON … JOIN t3 ON …,假设join顺序是t1,t2,t3
在join查询中,一个表在查询时与其他表展开联结查询之后,该表的扫描行数可能增加也可能减少,例如:如果t3表扇出大于1,则大多数row fetch操作都是针对t3表,假如join查询从t1表访问10行记录,然后使用t1表驱动查询t2表,t1表的每一行都会扫描t2表的20行记录,然后使用t2表驱动查询t3表,t2表的每一行都会扫描t3表的30行记录,那么,在使用单行输出时,instruments统计操作的事件信息总行数为:10 +(10 * 20)+(10 * 20 * 30)= 6210
通过对表中行扫描时的instruments统计操作进行聚合(即,每个t1和t2的扫描行数在instruments统计中可以算作一个批量组合),这样就可以减少instruments统计操作的数量。通过批量I/O输出方式,performance_schema每次对最内层表t3的扫描减少为一个事件统计信息而不是每一行扫描都生成一个事件信息,此时对于instruments统计操作的事件行数量减少到:10 +(10 * 20)+(10 * 20)= 410,这样在该join查询中对于performance_schema中的行统计操作就减少了93%,批量输出策略通过减少输出行数量来显着降低表I/O的performance_schema统计开销。但是相对于每行数据都单独执行统计操作,会损失对时间统计的准确度。在join查询中,批量I/O统计的时间包括用于连接缓冲、聚合和返回行到客户端的操作所花费的时间(即就是整个join语句的执行时间)
FLAGS: 留作将来使用
PS:events_waits_current 表允许使用 TRUNCATE TABLE 语句
5.2、events_waits_history 表
events_waits_history表包含每个线程最近的N个等待事件。 在server启动时,N的值会自动调整。 如果要显式设置这个N大小,可以在server启动之前调整系统参数performance_schema_events_waits_history_size的值。 等待事件需要执行结束时才被添加到events_waits_history表中(没有结束时保存在events_waits_current表)。当添加新事件到events_waits_history表时,如果该表已满,则会丢弃每个线程较旧的事件
events_waits_history 与 events_waits_current 表定义相同
PS:允许执行TRUNCATE TABLE语句
5.3、events_waits_history_long 表
events_waits_history_long表包含最近的N个等待事件(所有线程的事件)。在 server 启动时,N的值会自动调整。 如果要显式设置这个N大小,可以在 server 启动之前调整系统参数
performance_schema_events_waits_history_long_size 的值。等待事件需要执行结束时才会被添加到 events_waits_history_long 表中(没有结束时保存在 events_waits_current 表),当添加新事件到 events_waits_history_long 表时,如果该表已满,则会丢弃该表中较旧的事件。
events_waits_history_long 与 events_waits_current 表结构相同
PS:允许使用TRUNCATE TABLE语句
六、阶段事件表
阶段事件记录表与等待事件记录表一样,也有三张表,这些表记录了当前与最近在MySQL实例中发生了哪些阶段事件,时间消耗是多少。阶段指的是语句执行过程中的步骤,例如:parsing 、opening tables、filesort操作等。
在以往我们查看语句执行的阶段状态,常常使用SHOW PROCESSLIST语句或查询INFORMATION_SCHEMA.PROCESSLIST表来获得,但processlist方式能够查询到的信息比较有限且转瞬即逝,我们常常需要结合profiling功能来进一步统计分析语句执行的各个阶段的开销等,现在,我们不需要这么麻烦,直接使用performance_schema的阶段事件就既可以查询到所有的语句执行阶段,也可以查询到各个阶段对应的开销,因为是记录在表中,所以更可以使用SQL语句对这些数据进行排序、统计等操作
要注意:阶段事件相关配置中, setup_instruments 表中 stage/ 开头的绝大多数 instruments 配置默认没有开启(少数 stage /开头的 instruments 除外,如 DDL 语句执行过程的 stage/innodb/alter* 开头的 instruments 默认开启的), setup_consumers表 中 stages 相关的 consumers 配置默认没有开启
6.1、events_stages_current 表
events_stages_current表包含当前阶段事件的监控信息,每个线程一行记录显示线程正在执行的stage事件的状态
在包含stage事件记录的表中,events_stages_current是基准表,包含stage事件记录的其他表(如:events_stages_history和events_stages_history_long表)的数据在逻辑上都来自events_stages_current表(汇总表除外)
表记录内容示例(以下仍然是一个执行select sleep(100);语句的线程,但这里是阶段事件信息)
root@localhost : performance_schema 12:24:40> select * from events_stages_current where EVENT_NAME=‘stage/sql/User sleep’\G;
*************************** 1. row ***************************
THREAD_ID: 46
EVENT_ID: 280
END_EVENT_ID: NULL
EVENT_NAME: stage/sql/User sleep
SOURCE: item_func.cc:6056
TIMER_START: 14645080545642000
TIMER_END: 14698320697396000
TIMER_WAIT: 53240151754000
WORK_COMPLETED: NULL
WORK_ESTIMATED: NULL
NESTING_EVENT_ID: 266
NESTING_EVENT_TYPE: STATEMENT
1 row in set (0.00 sec)
以上的输出结果与语句的等待事件形式类似,这里不再赘述,
6.2、events_stages_current 表完整的字段含义
THREAD_ID,EVENT_ID :与事件关联的线程ID和当前事件ID,可以使用 THREAD_ID 和 EVENT_ID 列值来唯一标识该行,这两行的值作为组合条件时不会出现相同的数据行
END_EVENT_ID :当一个事件开始执行时,对应行记录的该列值被设置为 NULL ,当一个事件执行结束时,对应的行记录的该列值被更新为该事件的ID
EVENT_NAME :产生事件的 instruments 的名称。该列值来自 setup_instruments 表的 NAME 值。 instruments 名称可能具有多个部分并形成层次结构,如: “stage/sql/Slave has read all relay log; waiting for more updates”, 其中 stage 是顶级名称,sql是二级名称, Slave has read all relay log; waiting for more updates 是第三级名称。详见链接:
https://dev.mysql.com/doc/refman/5.7/en/performance-schema-instrument-naming.html
SOURCE :源文件的名称及其用于检测该事件的代码位于源文件中的行号
TIMER_START,TIMER_END,TIMER_WAIT :事件的时间信息。这些值的单位是皮秒(万亿分之一秒)。 TIMER_START 和 TIMER_END 值表示事件的开始时间和结束时间。 TIMER_WAIT 是事件执行消耗的时间(持续时间)
如果事件未执行完成,则TIMER_END为当前时间,TIMER_WAIT为当前为止所经过的时间(TIMER_END - TIMER_START)
如果instruments配置表setup_instruments中对应的instruments 的TIMED字段被设置为 NO,则该instruments禁用时间收集功能,那么事件采集的信息记录中,TIMER_START,TIMER_END和TIMER_WAIT字段值均为NULL
WORK_COMPLETED,WORK_ESTIMATED:这些列提供了阶段事件进度信息
表中的WORK_COMPLETED和WORK_ESTIMATED两列,它们共同协作显示每一行的进度显示:
-
1)、WORK_COMPLETED:显示阶段事件已完成的工作单元数
-
2)、WORK_ESTIMATED:显示预计阶段事件将要完成的工作单元数
如果instruments没有提供进度相关的功能,则该instruments执行事件采集时就不会有进度信息显示,WORK_COMPLETED和WORK_ESTIMATED列都会显示为NULL。如果进度信息可用,则进度信息如何显示取决于instruments的执行情况。performance_schema表提供了一个存储进度数据的容器,但不会假设你会定义何种度量单位来使用这些进度数据:
-
1)、“工作单元”是在执行过程中随时间增加而增加的整数度量,例如执行过程中的字节数、行数、文件数或表数。对于特定instruments的“工作单元”的定义留给提供数据的instruments代码
-
2)、WORK_COMPLETED值根据检测的代码不同,可以一次增加一个或多个单元
-
3)、WORK_ESTIMATED值根据检测代码,可能在阶段事件执行过程中发生变化
阶段事件进度指示器的表现行为有以下几种情况:
-
1)、instruments不支持进度:没有可用进度数据, WORK_COMPLETED和WORK_ESTIMATED列都显示为NULL
-
- 、instruments支持进度但对应的工作负载总工作量不可预估(无限进度):只有WORK_COMPLETED列有意义(因为他显示正在执行的进度显示),WORK_ESTIMATED列此时无效,显示为0,因为没有可预估的总进度数据。通过查询events_stages_current表来监视会话,监控应用程序到目前为止执行了多少工作,但无法报告对应的工作是否接近完成
-
3)、instruments支持进度,总工作量可预估(有限进度):WORK_COMPLETED和WORK_ESTIMATED列值有效。这种类型的进度显示可用于online DDL期间的copy表阶段监视。通过查询events_stages_current表,可监控应用程序当前已经完成了多少工作,并且可以通过WORK_COMPLETED / WORK_ESTIMATED计算的比率来预估某个阶段总体完成百分比
NESTING_EVENT_ID :事件的嵌套事件 EVENT_ID 值(父事件ID)
NESTING_EVENT_TYPE :嵌套事件类型。有效值为: TRANSACTION,STATEMENT,STAGE,WAIT。 阶段事件的嵌套事件通常是 statement
对于events_stages_current表允许使用TRUNCATE TABLE语句来进行清理
PS:stage事件拥有一个进度展示功能,我们可以利用该进度展示功能来了解一些长时间执行的SQL的进度百分比,例如:对于需要使用COPY方式执行的online ddl,那么需要copy的数据量是一定的,可以明确的,so…这就可以为"stage/sql/copy to tmp table stage" instruments提供一个有结束边界参照的进度数据信息,这个instruments所使用的工作单元就是需要复制的数据行数,此时WORK_COMPLETED和WORK_ESTIMATED列值都是有效的可用的,两者的计算比例就表示当前copy表完成copy的行数据百分比。
要查看copy表阶段事件的正在执行的进度监视功能,需要打开相关的instruments和consumers,然后查看events_stages_current表,如下:
配置相关instruments和consumers
UPDATE setup_instruments SET ENABLED=‘YES’ WHERE NAME=‘stage/sql/copy to tmp table’;
UPDATE setup_consumers SET ENABLED=‘YES’ WHERE NAME LIKE ‘events_stages_%’;
然后在执行ALTER TABLE语句期间,查看events_stages_current表
6.3、events_stages_history 表
events_stages_history表包含每个线程最新的N个阶段事件。 在server启动时,N的值会自动调整。 如果要显式设置N值大小,可以在server启动之前设置系统变量performance_schema_events_stages_history_size的值。stages事件在执行结束时才添加到events_stages_history表中。 当添加新事件到events_stages_history表时,如果events_stages_history表已满,则会丢弃对应线程较旧的事件events_stages_history与events_stages_current表结构相同
PS:允许使用TRUNCATE TABLE语句
6.4、events_stages_history_long 表
events_stages_history_long表包含最近的N个阶段事件。 在server启动时,N的值会自动调整。 如果要显式设置N值大小,可以在server启动之前设置系统变量performance_schema_events_stages_history_long_size的值。stages事件执行结束时才会添加到events_stages_history_long表中,当添加新事件到events_stages_history_long表时,如果events_stages_history_long表已满,则会丢弃该表中较旧的事件events_stages_history_long与events_stages_current表结构相同
PS:允许使用TRUNCATE TABLE语句
七、语句事件表
语句事件记录表与等待事件记录表一样,也有三张表,这些表记录了当前与最近在MySQL实例中发生了哪些语句事件,时间消耗是多少。记录了各种各样的语句执行产生的语句事件信息。
要注意:语句事件相关配置中, setup_instruments 表中 statement/* 开头的所有 instruments 配置默认开启, setup_consumers 表中 statements 相关的 consumers 配置默认开启了 events_statements_current、events_statements_history、 statements_digest (对应 events_statements_summary_by_digest 表,详见后续章节)但没有开启 events_statements_history_long。
7.1、events_statements_current 表
events_statements_current表包含当前语句事件,每个线程只显示一行最近被监视语句事件的当前状态。
在包含语句事件行的表中,events_statements_current当前事件表是基础表。其他包含语句事件表中的数据在逻辑上来源于当前事件表(汇总表除外)。例如:events_statements_history和events_statements_history_long表是最近的语句事件历史的集合,events_statements_history表中每个线程默认保留10行事件历史信息,events_statements_history_long表中默认所有线程保留10000行事件历史信息
表记录内容示例(以下信息仍然来自select sleep(100);语句的语句事件信息)
root@localhost : performance_schema 12:36:35> select * from events_statements_current where SQL_TEXT=‘select sleep(100)’\G;
*************************** 1. row ***************************
THREAD_ID: 46
EVENT_ID: 334
END_EVENT_ID: NULL
EVENT_NAME: statement/sql/select
SOURCE: socket_connection.cc:101
TIMER_START: 15354770719802000
TIMER_END: 15396587017809000
TIMER_WAIT: 41816298007000
LOCK_TIME: 0
SQL_TEXT: select sleep(100)
DIGEST: NULL
DIGEST_TEXT: NULL
CURRENT_SCHEMA: NULL
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: NULL
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 0
ROWS_SENT: 0
ROWS_EXAMINED: 0
CREATED_TMP_DISK_TABLES: 0
CREATED_TMP_TABLES: 0
SELECT_FULL_JOIN: 0
SELECT_FULL_RANGE_JOIN: 0
SELECT_RANGE: 0
SELECT_RANGE_CHECK: 0
SELECT_SCAN: 0
SORT_MERGE_PASSES: 0
SORT_RANGE: 0
SORT_ROWS: 0
SORT_SCAN: 0
NO_INDEX_USED: 0
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0
1 row in set (0.00 sec)
以上的输出结果与语句的等待事件形式类似,这里不再赘述,
7.2、events_statements_current 表完整的字段含义
THREAD_ID,EVENT_ID:与事件关联的线程号和事件启动时的事件编号,可以使用THREAD_ID和EVENT_ID列值来唯一标识该行,这两行的值作为组合条件时不会出现相同的数据行
END_EVENT_ID:当一个事件开始执行时,对应行记录的该列值被设置为NULL,当一个事件执行结束时,对应的行记录的该列值被更新为该事件的ID
EVENT_NAME:产生事件的监视仪器的名称。该列值来自setup_instruments表的NAME值。对于SQL语句,EVENT_NAME值最初的instruments是statement/com/Query,直到语句被解析之后,会更改为更合适的具体instruments名称,如:statement/sql/insert
SOURCE:源文件的名称及其用于检测该事件的代码位于源文件中的行号,您可以检查源代码来确定涉及的代码
TIMER_START,TIMER_END,TIMER_WAIT:事件的时间信息。这些值的单位是皮秒(万亿分之一秒)。 TIMER_START和TIMER_END值表示事件的开始时间和结束时间。TIMER_WAIT是事件执行消耗的时间(持续时间)
如果事件未执行完成,则TIMER_END为当前时间,TIMER_WAIT为当前为止所经过的时间(TIMER_END - TIMER_START)。
如果监视仪器配置表setup_instruments中对应的监视器TIMED字段被设置为 NO,则不会收集该监视器的时间信息,那么对于该事件采集的信息记录中,TIMER_START,TIMER_END和TIMER_WAIT字段值均为NULL
LOCK_TIME:等待表锁的时间。该值以微秒进行计算,但最终转换为皮秒显示,以便更容易与其他performance_schema中的计时器进行比较
SQL_TEXT:SQL 语句的文本。如果该行事件是与 SQL 语句无关的 command 事件,则该列值为 NULL 。默认情况下,语句最大显示长度为 1024 字节。如果要修改,则在 server 启动之前设置系统变量 performance_schema_max_sql_text_length 的值
DIGEST :语句摘要的 MD5 hash 值,为32位十六进制字符串,如果在 setup_consumers表中statement_digest 配置行没有开启,则语句事件中该列值为 NULL
DIGEST_TEXT:标准化转换过的语句摘要文本,如果setup_consumers表中statements_digest配置行没有开启,则语句事件中该列值为NULL。performance_schema_max_digest_length系统变量决定着在存入该表时的最大摘要语句文本的字节长度(默认为1024字节),要注意:用于计算摘要语句文本的原始语句文本字节长度由系统变量max_digest_length控制,而存入表中的字节长度由系统变量performance_schema_max_digest_length控制,所以,如果performance_schema_max_digest_length小于max_digest_length时,计算出的摘要语句文本如果大于了performance_schema_max_digest_length定义的长度会被截断
CURRENT_SCHEMA :语句使用的默认数据库(使用 use db_name 语句即可指定默认数据库),如果没有则为 NULL
OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE :对于嵌套语句(存储程序最终是通过语句调用的,所以如果一个语句是由存储程序调用的,虽然说这个语句事件是嵌套在存储程序中的,但是实际上对于事件类型来讲,仍然是嵌套在语句事件中),这些列包含有关父语句的信息。如果不是嵌套语句或者是父语句本身产生的事件,则这些列值为 NULL
OBJECT_INSTANCE_BEGIN: 语句的唯一标识,该列值是内存中对象的地址
MYSQL_ERRNO: 语句执行的错误号,此值来自代码区域的语句诊断区域
RETURNED_SQLSTATE: 语句执行的 SQLSTATE 值,此值来自代码区域的语句诊断区域
MESSAGE_TEXT: 语句执行的具体错误信息,此值来自代码区域的语句诊断区域
ERRORS: 语句执行是否发生错误。如果 SQLSTATE 值以 00 (完成)或 01 (警告)开始,则该列值为0。其他任何 SQLSTATE 值时,该列值为1
WARNINGS :语句警告数,此值来自代码区域的语句诊断区域
ROWS_AFFECTED :受该语句影响的行数。有关“受影响”的含义的描述,参见连接: https://dev.mysql.com/doc/refman/5.7/en/mysql-affected-rows.html
使用mysql_query()或mysql_real_query()函数执行语句后,可能会立即调用mysql_affected_rows()函数。如果是UPDATE,DELETE或INSERT,则返回最后一条语句更改、删除、插入的行数。对于SELECT语句,mysql_affected_rows()的工作方式与mysql_num_rows()一样(在执行结果最后返回的信息中看不到effected统计信息)
对于UPDATE语句,受影响的行值默认为实际更改的行数。如果在连接到mysqld时指定了CLIENT_FOUND_ROWS标志给mysql_real_connect()函数,那么affected-rows的值是“found”的行数。即WHERE子句匹配到的行数
对于REPLACE语句,如果发生新旧行替换操作,则受影响的行值为2,因为在这种情况下,实际上是先删除旧值,后插入新值两个行操作
对于INSERT … ON DUPLICATE KEY UPDATE语句,如果行作为新行插入,则每行的affected计数为1,如果发生旧行更新为新行则每行affected计数为2,如果没有发生任何插入和更新,则每行的affected计数为0 (但如果指定了CLIENT_FOUND_ROWS标志,则没有发生任何的插入和更新时,即set值就为当前的值时,每行的受影响行值计数为1而不是0)
在存储过程的CALL语句调用之后,mysql_affected_rows()返回的影响行数是存储程序中的最后一个语句执行的影响行数值,如果该语句返回-1,则存储程序最终返回0受影响。所以在存储程序执行时返回的影响行数并不可靠,但是你可以自行在存储程序中实现一个计数器变量在SQL级别使用ROW_COUNT()来获取各个语句的受影响的行值并相加,最终通过存储程序返回这个变量值。
在MySQL 5.7中,mysql_affected_rows()为更多的语句返回一个有意义的值。
-
1)、对于DDL语句,row_count()函数返回0,例如:CREATE TABLE、ALTER TABLE、DROP TABLE之类的语句
-
2)、对于除SELECT之外的DML语句:row_count()函数返回实际数据变更的行数。例如:UPDATE、INSERT、DELETE语句,现在也适用于LOAD DATA INFILE之类的语句,大于0的返回值表示DML语句做了数据变更,如果返回为0,则表示DML语句没有做任何数据变更,或者没有与where子句匹配的记录,如果返回-1则表示语句返回了错误
-
3)、对于SELECT语句:row_count()函数返回-1,例如:SELECT * FROM t1语句,ROW_COUNT()返回-1(对于select语句,在调用mysql_store_result()之前调用了mysql_affected_rows()返回了)。但是对于SELECT * FROM t1 INTO OUTFILE’file_name’这样的语句,ROW_COUNT()函数将返回实际写入文件中的数据行数
-
4)、对于SIGNAL语句:row_count()函数返回0
-
5)、因为mysql_affected_rows()返回的是一个无符号值,所以row_count()函数返回值小于等于0时都转换为0值返回或者不返回给effected值,row_count()函数返回值大于0时则返回给effected值
ROWS_SENT:语句返回给客户端的数据行数
ROWS_EXAMINED:在执行语句期间从存储引擎读取的数据行数
CREATED_TMP_DISK_TABLES:像Created_tmp_disk_tables状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
CREATED_TMP_TABLES:像Created_tmp_tables状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SELECT_FULL_JOIN:像Select_full_join状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SELECT_FULL_RANGE_JOIN:像Select_full_range_join状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SELECT_RANGE:就像Select_range状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SELECT_RANGE_CHECK:像Select_range_check状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SELECT_SCAN:像Select_scan状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SORT_MERGE_PASSES:像Sort_merge_passes状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SORT_RANGE:像Sort_range状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SORT_ROWS:像Sort_rows状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
SORT_SCAN:像Sort_scan状态变量一样的计数值,但是这里只用于这个事件中的语句统计而不针对全局、会话级别
NO_INDEX_USED:如果语句执行表扫描而不使用索引,则该列值为1,否则为0
NO_GOOD_INDEX_USED:如果服务器找不到用于该语句的合适索引,则该列值为1,否则为0
NESTING_EVENT_ID,NESTING_EVENT_TYPE,NESTING_EVENT_LEVEL:这三列与其他列结合一起使用,为顶级(未知抽象的语句或者说是父语句)语句和嵌套语句(在存储的程序中执行的语句)提供以下事件信息
对于顶级语句:
OBJECT_TYPE = NULL,OBJECT_SCHEMA = NULL,OBJECT_NAME = NULL,NESTING_EVENT_ID = NULL,NESTING_EVENT_TYPE = NULL,NESTING_LEVEL = 0
对于嵌套语句:OBJECT_TYPE =父语句对象类型,OBJECT_SCHEMA =父语句数据库级名称,OBJECT_NAME =父语句表级对象名称,NESTING_EVENT_ID =父语句EVENT_ID,NESTING_EVENT_TYPE =‘STATEMENT’,NESTING_LEVEL =父语句NESTING_LEVEL加一,例如:1,表示父语句的下一层嵌套语句
允许使用TRUNCATE TABLE语句
7.3、events_statements_history 表
events_statements_history表包含每个线程最新的N个语句事件。 在server启动时,N的值会自动调整。 要显式设置N的大小,可以在server启动之前设置系统变量 performance_schema_events_statements_history_size 的值。 statement事件执行完成时才会添加到该表中。 当添加新事件到该表时,如果对应线程的事件在该表中的配额已满,则会丢弃对应线程的较旧的事件
events_statements_history与events_statements_current表结构相同
PS:允许使用TRUNCATE TABLE语句
7.4、events_statements_history_long 表
events_statements_history_long表包含最近的N个语句事件。在server启动时,N的值会自动调整。 要显式设置N的大小,可以在server启动之前设置系统变量performance_schema_events_statements_history_long_size的值。 statement事件需要执行结束时才会添加到该表中。 当添加新事件到该表时,如果该表的全局配额已满,则会丢弃该表中较旧的事件
events_statements_history_long与events_statements_current表结构相同
PS:允许使用TRUNCATE TABLE语句
八、事务事件表
事务事件记录表与等待事件记录表一样,也有三张表,这些表记录了当前与最近在MySQL实例中发生了哪些事务事件,时间消耗是多少
要注意:事务事件相关配置中,setup_instruments表中只有一个名为transaction的instrument,默认关闭,setup_consumers表中transactions相关的consumers配置默认关闭了
8.1、events_transactions_current 表
events_transactions_current表包含当前事务事件信息,每个线程只保留一行最近事务的事务事件
在包含事务事件信息的表中,events_transactions_current是基础表。其他包含事务事件信息的表中的数据逻辑上来源于当前事件表。例如:events_transactions_history和events_transactions_history_long表分别包含每个线程最近10行事务事件信息和全局最近10000行事务事件信息
表记录内容示例(以下信息来自对某表执行了一次select等值查询的事务事件信息)
root@localhost : performance_schema 12:50:10> select * from events_transactions_current\G;
*************************** 1. row ***************************
THREAD_ID: 46
EVENT_ID: 38685
END_EVENT_ID: 38707
EVENT_NAME: transaction
STATE: COMMITTED
TRX_ID: 422045139261264
GTID: AUTOMATIC
XID_FORMAT_ID: NULL
XID_GTRID: NULL
XID_BQUAL: NULL
XA_STATE: NULL
SOURCE: handler.cc:1421
TIMER_START: 16184509764409000
TIMER_END: 16184509824175000
TIMER_WAIT: 59766000
ACCESS_MODE: READ WRITE
ISOLATION_LEVEL: READ COMMITTED
AUTOCOMMIT: YES
NUMBER_OF_SAVEPOINTS: 0
NUMBER_OF_ROLLBACK_TO_SAVEPOINT: 0
NUMBER_OF_RELEASE_SAVEPOINT: 0
OBJECT_INSTANCE_BEGIN: NULL
NESTING_EVENT_ID: 38667
NESTING_EVENT_TYPE: STATEMENT
1 row in set (0.00 sec)
以上的输出结果与语句的等待事件形式类似,这里不再赘述,
8.2、events_transactions_current 表完整字段含义
THREAD_ID,EVENT_ID :与事件关联的线程号和事件启动时的事件编号,可以使用 THREAD_ID和EVENT_ID 列值来唯一标识该行,这两行的值作为组合条件时不会出现相同的数据行
END_EVENT_ID:当一个事件开始执行时,对应行记录的该列值被设置为NULL,当一个事件执行结束时,对应的行记录的该列值被更新为该事件的ID
EVENT_NAME:收集该事务事件的instruments的名称。来自setup_instruments表的NAME列值
STATE:当前事务状态。有效值为:ACTIVE(执行了START TRANSACTION或BEGIN语句之后,事务未提交或未回滚之前)、COMMITTED(执行了COMMIT之后)、ROLLED BACK(执行了ROLLBACK语句之后)
TRX_ID:未使用,字段值总是为NULL
GTID:包含gtid_next系统变量的值,其值可能是格式为:UUID:NUMBER的GTID,也可能是:ANONYMOUS、AUTOMATIC。对于AUTOMATIC列值的事务事件,GTID列在事务提交和对应事务的GTID实际分配时都会进行更改(如果gtid_mode系统变量为ON或ON_PERMISSIVE,则GTID列将更改为事务的GTID,如果gtid_mode为OFF或OFF_PERMISSIVE,则GTID列将更改为ANONYMOUS)
XID_FORMAT_ID,XID_GTRID和XID_BQUAL :XA事务标识符的组件。关于XA事务语法详见链接: https://dev.mysql.com/doc/refman/5.7/en/xa-statements.html
XA_STATE:XA事务的状态。有效值为:ACTIVE(执行了XA START之后,未执行其他后续XA语句之前)、IDLE(执行了XA END语句之后,未执行其他后续XA语句之前)、PREPARED(执行了XA PREPARE语句之后,未执行其他后续XA语句之前)、ROLLED BACK(执行了XA ROLLBACK语句之后,未执行其他后续XA语句之前)、COMMITTED(执行了XA COMMIT语句之后)
SOURCE: 源文件的名称及其用于检测该事件的代码位于源文件中的行号,您可以检查源代码来确定涉及的代码
TIMER_START,TIMER_END,TIMER_WAIT :事件的时间信息。这些值的单位是皮秒(万亿分之一秒)。 TIMER_START和TIMER_END 值表示事件的开始时间和结束时间。 TIMER_WAIT 是事件执行消耗的时间(持续时间)
如果事件未执行完成,则TIMER_END为当前时间,TIMER_WAIT为当前为止所经过的时间(TIMER_END - TIMER_START)
如果监视仪器配置表setup_instruments中对应的监视器TIMED字段被设置为 NO,则不会收集该监视器的时间信息,那么对于该事件采集的信息记录中,TIMER_START,TIMER_END和TIMER_WAIT字段值均为NULL
ACCESS_MODE :事务访问模式。有效值为: READ ONLY或READ WRITE
ISOLATION_LEVEL: 事务隔离级别。有效值为: REPEATABLE READ、READ COMMITTED、READ UNCOMMITTED、SERIALIZABLE
AUTOCOMMIT:在事务开始时是否启用了自动提交模式,如果启用则为YES,没有启用则为NO
NUMBER_OF_SAVEPOINTS,NUMBER_OF_ROLLBACK_TO_SAVEPOINT,NUMBER_OF_RELEASE_SAVEPOINT:在事务内执行的SAVEPOINT,ROLLBACK TO SAVEPOINT和RELEASE SAVEPOINT语句的数量
OBJECT_INSTANCE_BEGIN:未使用,字段值总是为NULL
NESTING_EVENT_ID:嵌套事务事件的父事件EVENT_ID值
NESTING_EVENT_TYPE: 嵌套事件类型。有效值为: TRANSACTION、STATEMENT、STAGE、WAIT (由于事务无法嵌套,因此该列值不会出现 TRANSACTION)
允许使用TRUNCATE TABLE语句
8.3、events_transactions_history 表
events_transactions_history表包含每个线程最近的N个事务事件。 在server启动时,N的值会自动调整。 要显式设置N的大小,可以在server启动之前设置系统变量
performance_schema_events_transactions_history_size 的值。事务事件未执行完成之前不会添加到该表中。当有新的事务事件添加到该表时,如果该表已满,则会丢弃对应线程较旧的事务事件
events_transactions_history与events_transactions_current 表结构相同
PS:允许使用TRUNCATE TABLE语句
8.4、events_transactions_history_long 表
events_transactions_history_long表包含全局最近的N个事务事件。在server启动时,N的值会自动调整。 要显式设置N的大小,可以在server启动之前设置系统变量
performance_schema_events_transactions_history_long_size 的值。事务事件在执行完之前不会添加到该表中。当添加新事务事件时,如果该表已满,则会丢弃较旧的事件
events_transactions_history_long与events_transactions_current 表结构相同
PS:允许使用TRUNCATE TABLE语句




