MySQL-sys
参考文献
- 千金良方: MySQL性能优化金字塔法则
sys
系统库使用基础环境
-
因为
sys
系统库提供了一些代替直接访问performance_schema
的视图,所以必须启用performance_schema
(将performance_schema
系统参数设置为ON
),sys
系统库的大部分功能才能正常使用 -
要完全访问sys系统库,用户必须具有以下权限.
- 对所有
sys
表和视图具有SELECT
权限. - 对所有
sys
存储过程和函数具有EXECUTE
权限. - 对
sys_config
表具有INSERT、UPDATE
权限. - 对某些特定的
sys
系统库存储过程和函数需要额外权限,如ps_setup_save()
存储过程,需要与临时表相关的权限.
- 对所有
-
还要有与被
sys
系统库执行访问的对象相关的权限.- 任何被sys系统库访问的
performance_schema
表都需要有SELECT
权限,如果要使用sys
系统库对performance_schema
相关表执行更新,则需要有performance_schema
相关表的UPDATE
权限. INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
表的PROCESS
权限.
- 任何被sys系统库访问的
-
如果要充分使用sys系统库的功能,则必须启用某些
performance_schema
的instruments
和consumers
.- 所有的
wait instruments
. - 所有的
stage instruments
. - 所有的
statement instruments
. - 对于所启用的类型事件的
instruments
,还需要启用对应类型的consumers
(xxx_current
和xxx_history_long
).要了解某存储过程具体做了什么事情,可以通过show create procedure procedure_name;
语句查看.
- 所有的
-
可以使用
sys
系统库本身来启用所有需要的instruments
和consumers
(而不需要手动使用DML
语句来启用).- 启用所有的
wait instruments
:CALL sys.ps_setup_enable_instrument('wait');
. - 启用所有的
stage instruments
:CALL sys.ps_setup_enable_instrument('stage');
. - 启用所有的
statement instruments
:CALL sys.ps_setup_enable_instrument('statement');
. - 启用所有事件类型的
current
表:CALL sys.ps_setup_enable_consumer('current');
. - 启用所有事件类型的
history_long
表:CALL sys.ps_setup_enable_consumer('history_long');
- 如果启用了一些默认配置之外的配置,则可以使用存储过程
CALL sys.ps_setup_reset_to_default(TRUE);
快速恢复到performance_schema
的默认配置.
- 启用所有的
sys
库使用
- 在
sys
系统库下包含很多视图,它们以各种方式对performance_schema
表进行聚合计算展示.这些视图大部分是成对出现的,两个视图名称相同,但有一个视图是带x$
前缀的,例如:host_summary_by_file_io
和x$host_summary_by_file_io
,代表按照主机进行汇总统计的文件I/O性能数据,两个视图访问的数据源是相同的,但是在创建视图的语句中,不带x$
前缀的视图显示的是相关数值经过单位换算后的数据(单位是毫秒、秒、分钟、小时、天等),带x$
前缀的视图显示的是原始的数据(单位是皮秒).
示例
1 | # 查看当前正在执行的语句进度信息 |
查看慢SQL语句慢在哪里
1 | root@192.168.11.216 [sys] 15:01:16>call sys.ps_setup_enable_instrument('wait'); |
查看是否有事务锁等待
1 | root@192.168.11.216 [sys] 15:00:48> select * from innodb_lock_waits\G |
字段名 | 含义 |
---|---|
wait_started |
发生等待的开始时间 |
wait_age |
线程已经等待了多久,该值是一个时间格式值 |
wait_age_secs |
线程已经等待了几秒钟,该值是一个纯整型值. |
locked_table |
锁等待的表名.此字段值格式为:schema_name.table_name |
locked_index |
锁等待的索引名称 |
locked_type |
锁等待的锁类型 |
waiting_trx_id |
等待的事务 ID |
waiting_trx_started |
发生锁等待的事务开始时间 |
waiting_trx_age |
发生锁等待的事务的等待时间,该值是一个时间格式值 |
waiting_trx_rows_locked |
发生锁等待的事务已经锁定的行数(如果是复合事务会累积计算) |
waiting_trx_rows_modified |
发生锁等待的事务已经修改的行数(如果是复合事务会累积计算) |
waiting_pid |
发生锁等待的事务的 processlist_id |
waiting_query |
发生锁等待的事务的 SQL 语句文本 |
waiting_lock_id |
发生锁等待的锁 ID |
waiting_lock_mode |
发生锁等待的锁模式 |
blocking_trx_id |
持有锁的事务 ID |
blocking_pid |
持有锁的事务的 processlist_id |
blocking_query |
持有锁的事务的 SQL 语句文本 |
blocking_lock_id |
持有锁的锁 ID |
blocking_lock_mode |
持有锁的锁模式 |
blocking_trx_started |
持有锁的事务的开始时间 |
blocking_trx_age |
持有锁的事务已经等待了多长时间,该值是时间格式值 |
blocking_trx_rows_locked |
持有锁的事务已经锁定的行数 |
blocking_trx_rows_modified |
持有锁的事务已经修改的行数 |
sql_kill_blocking_query |
执行 KILL 语句来杀死持有锁的查询语句(而不是整个会话).该字段是 MySQL 5.7.9 中新增的 |
sql_kill_blocking_connection |
执行 KILL 语句以杀死持有锁的整个会话.该字段是 MySQL 5.7.9 中新增的 |
查看是否有MDL
锁等待
- 通过
schema_table_lock_waits
视图可以查看当前链接线程的MDL锁等待信息,显示哪些会话被MDL锁阻塞,是谁阻塞了这些会话,数据来源:performance_schema
下的threads、metadata_locks、events_statements_current
表.
1 | # 首先开启mdl相关的instrument |
字段名 | 含义 |
---|---|
object_schema |
被锁定表所在的数据库 |
object_name |
被锁定表的名称 |
waiting_thread_id |
等待锁的线程 ID |
waiting_pid |
等待锁的进程 ID |
waiting_account |
等待锁的用户账户 |
waiting_lock_type |
等待的锁类型(如:TABLE LOCK、ROW LOCK) |
waiting_lock_duration |
等待锁的持续时间类型(如:TRANSACTION、EXPLICIT) |
waiting_query |
导致等待的 SQL 查询文本 |
waiting_query_secs |
导致等待的 SQL 查询的执行时间(秒) |
waiting_query_rows_affected |
导致等待的 SQL 查询影响的行数 |
waiting_query_rows_examined |
导致等待的 SQL 查询检查的行数 |
blocking_thread_id |
持有锁的线程 ID |
blocking_pid |
持有锁的进程 ID |
blocking_account |
持有锁的用户账户 |
blocking_lock_type |
持有锁的锁类型(如:TABLE LOCK、ROW LOCK) |
blocking_lock_duration |
持有锁的持续时间类型(如:TRANSACTION、EXPLICIT) |
sql_kill_blocking_query |
用于终止持有锁的查询的 SQL 命令 |
sql_kill_blocking_connection |
用于终止持有锁的连接的 SQL 命令 |
查看InnoDB
缓冲池中的热点数据有哪些
-
使用
innodb_buffer_stats_by_schema
视图可以按照schema
分组查询InnoDB
缓冲池的统计信息,默认按照已分配的buffer size
(缓冲区大小)降序排列(allocated
字段).数据来源:information_schema.innodb_buffer_page
1
2
3
4
5
6
7
8
9
10
11root@192.168.11.216 [sys] 15:25:50>select * from innodb_buffer_stats_by_schema;
+---------------+-----------+------------+-------+--------------+-----------+-------------+
| object_schema | allocated | data | pages | pages_hashed | pages_old | rows_cached |
+---------------+-----------+------------+-------+--------------+-----------+-------------+
| sbtest | 71.97 MiB | 59.50 MiB | 4606 | 1649 | 2228 | 96081 |
| athena | 13.58 MiB | 10.61 MiB | 869 | 104 | 146 | 2692 |
| mysql | 2.22 MiB | 1.38 MiB | 142 | 89 | 53 | 1347 |
| sys | 16.00 KiB | 338 bytes | 1 | 0 | 0 | 6 |
+---------------+-----------+------------+-------+--------------+-----------+-------------+
4 rows in set (0.28 sec)
查看冗余索引
-
使用
schema_redundant_indexes
视图可以查看重复或冗余索引,数据来源:sys.x$schema_flattened_keys
,该数据来源视图被称作schema_redundant_indexes
视图的辅助视图.1
2
3
4
5
6
7
8
9
10
11
12
13root@192.168.11.216 [sys] 15:29:55>select * from schema_redundant_indexes limit 1\G
*************************** 1. row ***************************
table_schema: dbt3
table_name: lineitem
redundant_index_name: i_l_orderkey
redundant_index_columns: l_orderkey
redundant_index_non_unique: 1
dominant_index_name: PRIMARY
dominant_index_columns: l_orderkey,l_linenumber
dominant_index_non_unique: 0
subpart_exists: 0
sql_drop_index: ALTER TABLE `dbt3`.`lineitem` DROP INDEX `i_l_orderkey`
1 row in set (0.02 sec)
查看未使用的索引
-
使用
schema_unused_indexes
视图可以查看不活跃的索引(没有任何事件发生的索引,表示该索引从未使用过),在默认情况下按照schema名称和表名进行排序.数据来源:performance_schema.table_io_waits_summary_by_index_usage
,该视图在服务器启动并运行足够长的时间后,所查询出的数据才比较实用;否则,使用该视图查询出的数据可能并不十分可靠,因为统计的数据可能并不精确,有一部分业务查询逻辑可能还来不及查询.1
2
3
4
5
6root@192.168.11.216 [sys] 15:30:21>select * from schema_unused_indexes limit 1\G
*************************** 1. row ***************************
object_schema: athena
object_name: dicom_patient_info
index_name: key_patient_name
1 row in set (0.09 sec)
查询表的增、删、改、查数据量和I/O耗时统计信息
-
使用
schema_table_statistics_with_buffer
视图可以查询表的增、删、改、查数据量,I/O耗时,以及在InnoDB缓冲池中占用情况等统计信息,在默认情况下按照增、删、改、查操作的总表I/O延迟时间(执行时间,也可以理解为存在最多I/O争用的表)降序排列.数据来源:performance_schema.table_io_waits_summary_by_table、sys.x$ps_schema_table_statistics_ io、sys.x$innodb_buffer_stats_by_table
.另外,该视图在内部使用了辅助视图sys.x$ps_ schema_table_statistics_io
1
root@192.168.11.216 [sys] 15:31:31>select * from schema_table_statistics_with_buffer limit 1\G
查看MySQL磁盘文件产生的磁盘流量与读写比例
-
使用
io_global_by_file_by_bytes
视图可以按照文件路径+名称分组(磁盘文件名)查看全局的I/O读写字节数、读写文件I/O事件数量统计信息,在默认情况下按照总I/O读写字节数进行降序排列.数据来源:performance_schema.file_summary_by_instance
1
2
3
4
5
6
7
8
9
10
11
12root@192.168.11.216 [sys] 15:33:06>select * from io_global_by_file_by_bytes limit 1\G
*************************** 1. row ***************************
file: @@datadir/#ib_16384_1.dblwr
count_read: 1
total_read: 8.19 MiB
avg_read: 8.19 MiB
count_write: 577344
total_written: 8.81 GiB
avg_write: 16.00 KiB
total: 8.82 GiB
write_pct: 99.91
1 row in set (0.04 sec)
查看哪些语句使用了全表扫描
-
使用
statements_with_full_table_scans
视图可以查看全表扫描或者没有使用最优索引的语句(经过标准化转换的语句文本),在默认情况下按照全表扫描次数与语句总次数百分比和语句总延迟时间(执行时间)降序排列.数据来源:performance_schema.events_statements_ summary_by_digest
1
root@192.168.11.216 [sys] 15:34:07>select * from statements_with_full_table_scans limit 1\G
查看哪些语句使用了文件排序
-
使用
statements_with_sorting
视图可以查看执行了文件排序的语句,在默认情况下按照语句总延迟时间(执行时间)降序排列.数据来源:performance_schema.events_statements_ summary_by_digest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16root@192.168.11.216 [sys] 15:35:07>select * from statements_with_sorting limit 1\G
*************************** 1. row ***************************
query: SELECT `user_id` , `username` ... ? ORDER BY `created_time` DESC
db: athena
exec_count: 143
total_latency: 412.21 ms
sort_merge_passes: 0
avg_sort_merges: 0
sorts_using_scans: 143
sort_using_range: 0
rows_sorted: 3352
avg_rows_sorted: 23
first_seen: 2024-06-28 09:45:27.905146
last_seen: 2024-06-28 14:46:46.075047
digest: d155d6b92e1cc530703a86fd6548e5640fbc9319734729e943a2a6f6ac982e80
1 row in set (0.12 sec)
查看哪些语句使用了临时表
-
使用
statements_with_temp_tables
视图可以查看使用了临时表的语句,在默认情况下按照磁盘临时表数量和内存临时表数量进行降序排列.数据来源:performance_schema.events_ statements_summary_by_digest
.1
root@192.168.11.216 [sys] 15:40:06>select * from statements_with_temp_tables limit 1\G