外观
MySQL Performance Schema 和 Sys Schema
Performance Schema 配置
启用 Performance Schema
默认状态:
- MySQL 5.6 及以上:默认启用
- MySQL 5.5:默认禁用
启用方法:
- 在 my.cnf 中配置:ini
[mysqld] performance_schema = ON - 或在启动时指定:bash
mysqld --performance_schema=ON
- 在 my.cnf 中配置:
配置项
performance_schema_max_xxx_size:控制各个缓冲区的大小
performance_schema_max_xxx_instances:控制各个实例的最大数量
performance_schema_xxx_enabled:控制是否启用某个监控项
常用配置示例:
ini[mysqld] performance_schema = ON performance_schema_max_thread_instances = 1000 performance_schema_max_event_classes = 100 performance_schema_max_digest_length = 1024
动态配置
- Performance Schema 支持动态配置,无需重启 MySQL 服务
- 使用 SET 语句修改配置:sql
-- 启用语句监控 UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%statement%'; -- 启用等待事件监控 UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%wait%'; -- 启用阶段事件监控 UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%stage%';
Performance Schema 核心表
配置表
- setup_instruments:控制哪些事件被收集
- setup_consumers:控制哪些事件被存储
- setup_timers:配置事件的计时单位
- setup_objects:控制哪些对象(表、存储过程等)被监控
实例表
- threads:线程信息
- events_waits_current:当前等待事件
- events_waits_history:每个线程最近的 10 个等待事件
- events_waits_history_long:全局最近的 10000 个等待事件
- events_stages_current:当前阶段事件
- events_stages_history:每个线程最近的 10 个阶段事件
- events_stages_history_long:全局最近的 10000 个阶段事件
- events_statements_current:当前语句事件
- events_statements_history:每个线程最近的 10 个语句事件
- events_statements_history_long:全局最近的 10000 个语句事件
- events_transactions_current:当前事务事件
- events_transactions_history:每个线程最近的 10 个事务事件
- events_transactions_history_long:全局最近的 10000 个事务事件
汇总表
- events_waits_summary_by_thread_by_event_name:按线程和事件名称汇总的等待事件
- events_waits_summary_by_instance:按实例汇总的等待事件
- events_waits_summary_global_by_event_name:按事件名称汇总的全局等待事件
- events_stages_summary_by_thread_by_event_name:按线程和阶段名称汇总的阶段事件
- events_stages_summary_global_by_event_name:按阶段名称汇总的全局阶段事件
- events_statements_summary_by_thread_by_event_name:按线程和语句类型汇总的语句事件
- events_statements_summary_by_digest:按语句摘要汇总的语句事件
- events_statements_summary_global_by_event_name:按语句类型汇总的全局语句事件
- events_transactions_summary_by_thread_by_event_name:按线程和事务类型汇总的事务事件
- events_transactions_summary_global_by_event_name:按事务类型汇总的全局事务事件
其他表
- file_summary_by_event_name:文件 I/O 汇总
- file_summary_by_instance:文件实例 I/O 汇总
- table_io_waits_summary_by_table:表 I/O 汇总
- table_lock_waits_summary_by_table:表锁等待汇总
- mutex_instances:互斥锁实例
- rwlock_instances:读写锁实例
- cond_instances:条件变量实例
- file_instances:文件实例
Performance Schema 使用方法
基本查询
查看 Performance Schema 是否启用:
sqlSHOW VARIABLES LIKE 'performance_schema';查看当前等待事件:
sqlSELECT * FROM performance_schema.events_waits_current LIMIT 10;查看最近的语句事件:
sqlSELECT * FROM performance_schema.events_statements_history LIMIT 10;查看表 I/O 统计:
sqlSELECT * FROM performance_schema.table_io_waits_summary_by_table WHERE OBJECT_SCHEMA = 'test' AND OBJECT_NAME = 'mytable';
性能分析示例
1. 分析慢查询
- 查询耗时最长的语句:sql
SELECT DIGEST_TEXT, COUNT_STAR AS exec_count, SUM_TIMER_WAIT AS total_time, AVG_TIMER_WAIT AS avg_time, MAX_TIMER_WAIT AS max_time FROM performance_schema.events_statements_summary_by_digest ORDER BY total_time DESC LIMIT 10;
2. 分析 I/O 等待
- 查询 I/O 等待最多的文件:sql
SELECT FILE_NAME, EVENT_NAME, SUM_NUMBER_OF_BYTES_READ AS total_read, SUM_NUMBER_OF_BYTES_WRITE AS total_write, SUM_TIMER_WAIT AS total_time FROM performance_schema.file_summary_by_instance ORDER BY total_time DESC LIMIT 10;
3. 分析锁等待
- 查询锁等待最多的表:sql
SELECT OBJECT_SCHEMA, OBJECT_NAME, SUM_TIMER_WAIT AS total_wait_time, COUNT_STAR AS wait_count FROM performance_schema.table_lock_waits_summary_by_table ORDER BY total_wait_time DESC LIMIT 10;
4. 分析线程性能
- 查询最活跃的线程:sql
SELECT THREAD_ID, PROCESSLIST_ID, PROCESSLIST_USER, PROCESSLIST_HOST, PROCESSLIST_DB, PROCESSLIST_COMMAND, PROCESSLIST_STATE, SUM_TIMER_WAIT AS total_wait_time FROM performance_schema.threads t JOIN performance_schema.events_waits_summary_by_thread_by_event_name s ON t.THREAD_ID = s.THREAD_ID WHERE PROCESSLIST_ID IS NOT NULL GROUP BY THREAD_ID ORDER BY total_wait_time DESC LIMIT 10;
Sys Schema 常用视图
语句性能视图
1. statement_analysis
作用:提供语句执行的详细统计信息
常用字段:
query_id:语句 IDdb:数据库名称query:SQL 语句exec_count:执行次数err_count:错误次数warn_count:警告次数total_latency:总执行时间avg_latency:平均执行时间max_latency:最大执行时间lock_latency:锁等待时间rows_sent:返回行数rows_examined:扫描行数rows_affected:影响行数tmp_tables:临时表数量tmp_disk_tables:磁盘临时表数量
使用示例:
sqlSELECT * FROM sys.statement_analysis ORDER BY total_latency DESC LIMIT 10;
2. statement_latency_histogram
- 作用:提供语句执行时间的直方图
- 使用示例:sql
SELECT * FROM sys.statement_latency_histogram WHERE db = 'test';
I/O 性能视图
1. io_global_by_file_by_bytes
- 作用:按文件统计 I/O 字节数
- 使用示例:sql
SELECT * FROM sys.io_global_by_file_by_bytes ORDER BY total DESC LIMIT 10;
2. io_global_by_wait_by_bytes
- 作用:按事件类型统计 I/O 字节数
- 使用示例:sql
SELECT * FROM sys.io_global_by_wait_by_bytes ORDER BY total DESC LIMIT 10;
索引使用视图
1. schema_unused_indexes
- 作用:查找未使用的索引
- 使用示例:sql
SELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'test';
2. schema_redundant_indexes
- 作用:查找冗余索引
- 使用示例:sql
SELECT * FROM sys.schema_redundant_indexes WHERE object_schema = 'test';
锁等待视图
1. innodb_lock_waits
- 作用:显示当前的 InnoDB 锁等待
- 使用示例:sql
SELECT * FROM sys.innodb_lock_waits;
2. schema_table_lock_waits
- 作用:显示表锁等待情况
- 使用示例:sql
SELECT * FROM sys.schema_table_lock_waits WHERE object_schema = 'test' ORDER BY wait_time DESC;
内存使用视图
1. memory_global_by_current_bytes
- 作用:按分配类型统计当前内存使用情况
- 使用示例:sql
SELECT * FROM sys.memory_global_by_current_bytes ORDER BY current_bytes DESC LIMIT 10;
2. memory_by_thread_by_current_bytes
- 作用:按线程统计当前内存使用情况
- 使用示例:sql
SELECT * FROM sys.memory_by_thread_by_current_bytes ORDER BY current_bytes DESC LIMIT 10;
主机和用户视图
1. host_summary
- 作用:提供主机级别的性能汇总
- 使用示例:sql
SELECT * FROM sys.host_summary ORDER BY total_latency DESC LIMIT 10;
2. user_summary
- 作用:提供用户级别的性能汇总
- 使用示例:sql
SELECT * FROM sys.user_summary ORDER BY total_latency DESC LIMIT 10;
Sys Schema 使用技巧
性能问题诊断
1. 查找消耗 CPU 最多的查询
- 使用 statement_analysis 视图:sql
SELECT query, exec_count, total_latency, avg_latency, rows_examined, rows_sent FROM sys.statement_analysis WHERE db = 'test' ORDER BY total_latency DESC LIMIT 5;
2. 查找扫描行数过多的查询
- 使用 statement_analysis 视图:sql
SELECT query, exec_count, rows_examined, rows_sent, rows_examined / rows_sent AS rows_ratio FROM sys.statement_analysis WHERE db = 'test' AND rows_sent > 0 ORDER BY rows_ratio DESC LIMIT 5;
3. 查找创建临时表过多的查询
- 使用 statement_analysis 视图:sql
SELECT query, exec_count, tmp_tables, tmp_disk_tables, tmp_disk_tables / tmp_tables AS disk_tmp_ratio FROM sys.statement_analysis WHERE db = 'test' AND tmp_tables > 0 ORDER BY tmp_disk_tables DESC LIMIT 5;
索引优化
1. 查找未使用的索引
- 使用 schema_unused_indexes 视图:sql
SELECT object_schema, object_name, index_name FROM sys.schema_unused_indexes WHERE object_schema NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema');
2. 查找冗余索引
- 使用 schema_redundant_indexes 视图:sql
SELECT table_schema, table_name, redundant_index_name, dominant_index_name FROM sys.schema_redundant_indexes;
锁问题诊断
1. 查找锁等待最长的事务
- 使用 innodb_lock_waits 视图:sql
SELECT waiting_trx_id, waiting_pid, waiting_query, blocking_trx_id, blocking_pid, blocking_query, wait_age FROM sys.innodb_lock_waits ORDER BY wait_age DESC;
2. 查找表锁等待
- 使用 schema_table_lock_waits 视图:sql
SELECT object_schema, object_name, lock_type, lock_duration, wait_count, wait_time FROM sys.schema_table_lock_waits ORDER BY wait_time DESC LIMIT 10;
Performance Schema 和 Sys Schema 最佳实践
配置最佳实践
- 按需启用监控项:只启用需要监控的事件类型,减少性能开销
- 调整缓冲区大小:根据服务器负载调整 Performance Schema 的缓冲区大小
- 定期清理历史数据:定期清理 Performance Schema 的历史数据,避免内存占用过大
- 合理设置采样率:对于高负载系统,可降低采样率,减少性能影响
使用最佳实践
- 结合其他工具:结合慢查询日志、EXPLAIN 等工具进行综合性能分析
- 定期监控:定期收集和分析性能数据,建立性能基线
- 关注关键指标:重点关注执行时间长、扫描行数多、临时表多的语句
- 分析趋势变化:比较不同时间段的性能数据,分析性能变化趋势
- 及时优化:根据性能分析结果,及时优化数据库和查询
性能优化建议
- 优化查询:根据 Performance Schema 和 Sys Schema 的分析结果,优化慢查询
- 优化索引:删除未使用和冗余的索引,优化索引设计
- 优化配置:根据性能数据调整 MySQL 配置参数
- 优化架构:对于高负载系统,考虑分库分表、读写分离等架构优化
- 升级硬件:根据 I/O、CPU、内存等瓶颈,升级相应的硬件资源
不同 MySQL 版本的差异
MySQL 5.5
- Performance Schema:
- 初始版本,功能有限
- 支持基本的事件监控
- 默认禁用
MySQL 5.6
- Performance Schema:
- 增强了事件类型和监控项
- 提高了性能,降低了开销
- 默认启用
- 支持更多的 I/O 监控
MySQL 5.7
- Performance Schema:
- 新增了 Sys Schema
- 增强了语句监控
- 支持更多的等待事件类型
- 改进了内存使用
- Sys Schema:
- 首次引入
- 提供了大量易用的视图
- 简化了 Performance Schema 的使用
MySQL 8.0
- Performance Schema:
- 进一步优化了性能和开销
- 新增了更多的监控项
- 支持监控数据的持久化
- 增强了对并行查询的监控
- Sys Schema:
- 新增了更多的视图
- 改进了现有视图的性能
- 支持更多的性能分析场景
常见问题(FAQ)
Q1: Performance Schema 对性能有影响吗?
A1: Performance Schema 设计为低开销,对性能影响较小。优化建议包括:按需启用监控项,只监控需要的事件;调整缓冲区大小,避免内存占用过大;对于高负载系统,可降低采样率。
Q2: 如何减少 Performance Schema 的内存占用?
A2: 解决方案包括:减少监控的事件类型;降低 performance_schema_max_xxx_instances 等参数值;定期清理历史数据;调整 performance_schema_events_xxx_history_size 参数。
Q3: Sys Schema 视图查询慢怎么办?
A3: 可能原因包括 Performance Schema 数据量过大、视图查询涉及多个表的连接、服务器负载过高等。解决方案包括:优化 Performance Schema 配置,减少数据量;增加服务器资源;限制查询结果数量;定期清理历史数据。
Q4: 如何监控复制性能?
A4: 可以使用以下视图监控复制性能:
sys.replication_applier_status_by_coordinator:监控复制应用状态sys.replication_applier_status_by_worker:监控复制工作线程状态sys.replication_connection_status:监控复制连接状态
Q5: 如何监控 InnoDB 缓冲池使用情况?
A5: 可以使用以下视图监控 InnoDB 缓冲池使用情况:
sys.innodb_buffer_stats_by_schema:按 schema 监控缓冲池使用情况sys.innodb_buffer_stats_by_table:按表监控缓冲池使用情况sys.innodb_buffer_pool_residence_time:监控缓冲池页的驻留时间
