外观
MySQL 存储引擎指标
InnoDB 存储引擎指标
缓冲池指标
缓冲池命中率
sql
-- 计算缓冲池命中率
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';关键指标:
Innodb_buffer_pool_read_requests:缓冲池读取请求数Innodb_buffer_pool_reads:从磁盘读取的次数Innodb_buffer_pool_read_ahead:预读次数Innodb_buffer_pool_read_ahead_evicted:被驱逐的预读页数
缓冲池使用情况
sql
-- 查看缓冲池使用情况
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages%';关键指标:
Innodb_buffer_pool_pages_total:缓冲池总页数Innodb_buffer_pool_pages_free:空闲页数Innodb_buffer_pool_pages_data:包含数据的页数Innodb_buffer_pool_pages_dirty:脏页数Innodb_buffer_pool_pages_misc:其他用途的页数
事务指标
sql
-- 查看事务相关指标
SHOW GLOBAL STATUS LIKE 'Innodb_transaction%';
SHOW GLOBAL STATUS LIKE 'Innodb_row%';关键指标:
Innodb_transactions_active:当前活跃事务数Innodb_transactions_committed:已提交事务数Innodb_transactions_rolled_back:已回滚事务数Innodb_row_reads:读取的行数Innodb_row_inserts:插入的行数Innodb_row_updates:更新的行数Innodb_row_deletes:删除的行数
锁指标
sql
-- 查看锁相关指标
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock%';关键指标:
Innodb_row_lock_current_waits:当前等待锁的数量Innodb_row_lock_waits:锁等待总次数Innodb_row_lock_time:锁等待总时间Innodb_row_lock_time_avg:平均锁等待时间Innodb_row_lock_time_max:最长锁等待时间
日志指标
sql
-- 查看日志相关指标
SHOW GLOBAL STATUS LIKE 'Innodb_log%';关键指标:
Innodb_log_waits:日志缓冲区等待数Innodb_log_write_requests:日志写入请求数Innodb_log_writes:实际日志写入次数Innodb_log_bytes_written:写入的日志字节数Innodb_log_compressed_pages_written:压缩后写入的页数
表空间指标
sql
-- 查看表空间相关指标
SHOW GLOBAL STATUS LIKE 'Innodb_data%';关键指标:
Innodb_data_read:读取的数据字节数Innodb_data_written:写入的数据字节数Innodb_data_reads:数据读取次数Innodb_data_writes:数据写入次数Innodb_data_fsyncs:fsync操作次数
自适应哈希索引指标
sql
-- 查看自适应哈希索引指标
SHOW GLOBAL STATUS LIKE 'Innodb_adaptive_hash%';关键指标:
Innodb_adaptive_hash_searches:哈希索引搜索次数Innodb_adaptive_hash_hash_searches:哈希搜索次数Innodb_adaptive_hash_non_hash_searches:非哈希搜索次数
MyISAM 存储引擎指标
sql
-- 查看MyISAM相关指标
SHOW GLOBAL STATUS LIKE 'Key%';
SHOW GLOBAL STATUS LIKE 'Handler%';关键指标:
Key_blocks_used:使用的键块数Key_blocks_unused:未使用的键块数Key_blocks_not_flushed:未刷新到磁盘的键块数Key_read_requests:键读取请求数Key_reads:从磁盘读取键的次数Key_write_requests:键写入请求数Key_writes:键写入磁盘的次数Handler_read_first:读取索引第一个条目的次数Handler_read_key:通过键读取行的次数Handler_read_next:通过键读取下一行的次数Handler_read_prev:通过键读取前一行的次数Handler_read_rnd:通过随机位置读取行的次数Handler_read_rnd_next:读取下一行的次数Handler_write:插入行的次数Handler_update:更新行的次数Handler_delete:删除行的次数
Memory 存储引擎指标
sql
-- 查看Memory存储引擎相关指标
SHOW GLOBAL STATUS LIKE 'Created_tmp%';关键指标:
Created_tmp_disk_tables:在磁盘上创建的临时表数量Created_tmp_tables:创建的临时表总数Created_tmp_files:创建的临时文件数量
存储引擎监控工具
Performance Schema
sql
-- 启用Performance Schema
SET GLOBAL performance_schema = 1;
-- 查看存储引擎相关的性能数据
SELECT * FROM performance_schema.file_instances WHERE file_name LIKE '%.ibd' OR file_name LIKE '%.frm';
SELECT * FROM performance_schema.events_waits_current WHERE event_name LIKE 'wait/io/file/innodb%';Sys Schema
sql
-- 使用Sys Schema查看存储引擎状态
SELECT * FROM sys.innodb_buffer_pool_stats\G;
SELECT * FROM sys.innodb_lock_waits\G;
SELECT * FROM sys.schema_table_lock_waits\G;第三方监控工具
Prometheus + Grafana
- Exporter:使用mysql_exporter收集MySQL指标
- Dashboard:使用预配置的MySQL仪表盘监控存储引擎指标
- 告警:设置基于存储引擎指标的告警规则
Zabbix
- 模板:使用MySQL模板监控存储引擎关键指标
- 监控项:配置InnoDB缓冲池、锁等待等监控项
- 触发器:设置基于阈值的触发器
Nagios
- 插件:使用check_mysql_health插件监控存储引擎状态
- 命令:配置自定义命令监控特定存储引擎指标
- 服务:创建服务检查存储引擎健康状态
存储引擎指标告警阈值
InnoDB 告警阈值
| 指标 | 告警阈值 | 严重程度 |
|---|---|---|
| 缓冲池命中率 | < 95% | 警告 |
| 缓冲池命中率 | < 90% | 严重 |
| 活跃事务数 | > 100 | 警告 |
| 活跃事务数 | > 500 | 严重 |
| 锁等待时间 | > 1000ms | 警告 |
| 锁等待时间 | > 5000ms | 严重 |
| 脏页比例 | > 75% | 警告 |
| 脏页比例 | > 90% | 严重 |
MyISAM 告警阈值
| 指标 | 告警阈值 | 严重程度 |
|---|---|---|
| 键缓存命中率 | < 90% | 警告 |
| 键缓存命中率 | < 80% | 严重 |
| 表锁等待 | > 10 | 警告 |
| 表锁等待 | > 50 | 严重 |
存储引擎指标优化建议
InnoDB 优化
缓冲池优化
- 调整
innodb_buffer_pool_size为服务器内存的 50-80% - 对于大内存服务器,使用多个缓冲池实例:
innodb_buffer_pool_instances - 启用缓冲池预读:
innodb_read_ahead_threshold
- 调整
日志优化
- 调整
innodb_log_file_size以减少日志切换频率 - 设置适当的
innodb_log_buffer_size减少磁盘I/O
- 调整
并发优化
- 调整
innodb_thread_concurrency控制并发线程数 - 启用
innodb_adaptive_hash_index提高查询性能 - 设置
innodb_old_blocks_time改善缓冲池使用效率
- 调整
MyISAM 优化
键缓存优化
- 调整
key_buffer_size为服务器内存的 20-30% - 使用
myisam_max_sort_file_size控制排序文件大小
- 调整
并发优化
- 对于只读表,使用
myisam_read_buffer_size提高读取性能 - 对于写操作,使用
myisam_write_buffer_size提高写入性能
- 对于只读表,使用
Memory 存储引擎优化
内存使用优化
- 限制
max_heap_table_size防止内存过度使用 - 合理设置
tmp_table_size控制临时表大小
- 限制
性能优化
- 对于频繁使用的临时表,考虑使用 Memory 存储引擎
- 避免在 Memory 表中存储大字段
常见问题(FAQ)
Q1: 如何监控 InnoDB 缓冲池的使用情况?
A1: 可以使用以下命令监控 InnoDB 缓冲池的使用情况:
sql
-- 查看缓冲池状态
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages%';
-- 计算缓冲池使用率
SELECT
(1 - (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_free') /
(SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_total')) * 100 AS buffer_pool_usage_percent;Q2: 如何识别 MyISAM 表的性能问题?
A2: 可以通过以下指标识别 MyISAM 表的性能问题:
- 键缓存命中率:如果键缓存命中率低于 90%,考虑增加
key_buffer_size - 表锁等待:如果
Table_locks_waited与Table_locks_immediate的比例过高,说明存在表锁竞争 - 全表扫描:如果
Handler_read_rnd_next值过高,说明存在大量全表扫描
Q3: 如何监控存储引擎的 I/O 性能?
A3: 可以使用以下方法监控存储引擎的 I/O 性能:
使用 Performance Schema:
sqlSELECT event_name, count_star, sum_timer_wait, avg_timer_wait FROM performance_schema.events_waits_summary_global_by_event_name WHERE event_name LIKE 'wait/io/file/%' ORDER BY sum_timer_wait DESC;使用 iostat 命令:
bashiostat -x -d 1使用 MySQL 状态变量:
sqlSHOW GLOBAL STATUS LIKE 'Innodb_data%'; SHOW GLOBAL STATUS LIKE 'Innodb_log%';
Q4: 如何优化 InnoDB 的锁等待问题?
A4: 可以通过以下方法优化 InnoDB 的锁等待问题:
分析锁等待:
sqlSELECT * FROM sys.innodb_lock_waits\G;优化 SQL 语句:
- 减少事务持有的锁时间
- 使用更精确的 WHERE 条件
- 避免长时间运行的事务
调整 InnoDB 参数:
innodb_lock_wait_timeout:调整锁等待超时时间innodb_rollback_on_timeout:设置超时后是否回滚事务innodb_deadlock_detect:对于高并发场景,考虑关闭死锁检测
Q5: 如何监控存储引擎的磁盘空间使用情况?
A5: 可以使用以下方法监控存储引擎的磁盘空间使用情况:
查看表空间大小:
sqlSELECT table_schema, table_name, engine, ROUND(data_length / 1024 / 1024, 2) AS data_mb, ROUND(index_length / 1024 / 1024, 2) AS index_mb, ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_mb FROM information_schema.tables WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') ORDER BY total_mb DESC;监控 InnoDB 表空间:
sqlSELECT file_name, ROUND(file_size / 1024 / 1024, 2) AS size_mb, ROUND(tablespace_name) AS tablespace FROM information_schema.files WHERE tablespace_name IS NOT NULL;使用系统命令:
bashdf -h du -sh /path/to/mysql/data/*
