内容简介:MySQL服务器监控是数据库运维的重要组成部分,对于保障数据库的高可用性、性能和稳定性至关重要。本文风哥教程参考MySQL官方文档MySQL Server Administration部分,详细介绍MySQL服务器监控的方法、工具和最佳实践,包括内置监控工具、第三方监控工具和自定义监控脚本的使用,以及监控数据的分析和利用。学习交流加群风哥微信: itpux-com
Part01-基础概念与理论知识
1.1 MySQL监控概述
MySQL服务器监控是指对MySQL数据库的运行状态、性能指标、资源使用情况等进行持续的收集、分析和告警的过程。监控的主要目标包括:
- 保障可用性:及时发现和解决数据库故障,确保业务连续性
- 优化性能:识别性能瓶颈,提高数据库响应速度和吞吐量
- 资源管理:合理分配和利用服务器资源,避免资源浪费
- 容量规划:预测资源需求,提前进行扩容准备
- 安全审计:监控异常访问和操作,保障数据安全
1.2 监控指标分类
MySQL监控指标可以分为以下几类:
- 性能指标:QPS、TPS、响应时间、慢查询等
- 资源指标:CPU、内存、磁盘I/O、网络等
- 连接指标:连接数、连接状态、连接超时等
- 存储指标:数据文件大小、索引大小、碎片率等
- 缓存指标:缓冲池命中率、查询缓存命中率等
- 事务指标:事务数、提交/回滚比例、死锁数等
- 复制指标:复制延迟、复制状态等(主从复制环境)
Part02-生产环境规划与建议
2.1 监控策略规划
在生产环境中,MySQL监控策略的规划需要考虑以下因素:
- 监控范围:确定需要监控的服务器、数据库和指标
- 监控频率:根据指标的重要性和变化频率,确定监控的采样间隔
- 数据存储:确定监控数据的存储方式和保留时间
- 告警阈值:根据业务需求和历史数据,设置合理的告警阈值
- 告警方式:确定告警的通知方式(邮件、短信、即时通讯工具等)
- 告警级别:根据问题的严重程度,设置不同的告警级别
2.2 监控工具选择
选择适合的MySQL监控工具需要考虑以下因素:
- 功能需求:是否满足监控指标的收集、分析和告警需求
- 易用性:工具的安装、配置和使用是否简单易用
- 性能影响:监控工具对MySQL服务器性能的影响是否可以接受
- 扩展性:是否支持集群环境和大规模部署
- 集成性:是否可以与现有的监控系统和工具集成
- 成本:工具的采购、维护和升级成本
2.3 告警机制设计
设计有效的告警机制需要考虑以下因素:
- 告警阈值:设置合理的告警阈值,避免误报和漏报
- 告警级别:根据问题的严重程度,设置不同的告警级别(如警告、严重、紧急)
- 告警通知:选择合适的告警通知方式,确保相关人员及时收到告警
- 告警升级:如果告警未得到及时处理,自动升级告警级别
- 告警抑制:避免同一问题产生过多重复告警
- 告警记录:记录所有告警信息,便于后续分析和改进
Part03-生产环境项目实施方案
3.1 内置监控工具
MySQL提供了多种内置的监控工具,用于收集和查看数据库的运行状态和性能指标。
3.1.1 SHOW STATUS命令
SHOW STATUS命令用于查看MySQL服务器的状态变量。
mysql> SHOW GLOBAL STATUS;
# 输出结果太多,这里只显示部分
+———————————–+—————-+——————-+
| Variable_name | Value | Variable_source |
+———————————–+—————-+——————-+
| Aborted_clients | 5 | global |
| Aborted_connects | 10 | global |
| Binlog_cache_disk_use | 0 | global |
| Binlog_cache_use | 1000 | global |
| Bytes_received | 10485760 | global |
| Bytes_sent | 104857600 | global |
| Com_admin_commands | 100 | global |
| Com_begin | 5000 | global |
| Com_commit | 4900 | global |
| Com_delete | 1000 | global |
| Com_insert | 10000 | global |
| Com_rollback | 100 | global |
| Com_select | 50000 | global |
| Com_update | 19000 | global |
| Connections | 2000 | global |
| Innodb_buffer_pool_reads | 1000 | global |
| Innodb_buffer_pool_read_requests | 1000000 | global |
| Innodb_buffer_pool_write_requests | 500000 | global |
| Queries | 80000 | global |
| Questions | 70000 | global |
| Slow_queries | 20 | global |
| Threads_connected | 20 | global |
| Threads_created | 100 | global |
| Threads_running | 2 | global |
| Uptime | 86400 | global |
+———————————–+—————-+——————-+
# 查看特定的状态变量
mysql> SHOW GLOBAL STATUS LIKE ‘Queries’;
+—————+——-+——————-+
| Variable_name | Value | Variable_source |
+—————+——-+——————-+
| Queries | 80000 | global |
+—————+——-+——————-+
# 计算QPS(每秒查询数)
mysql> SELECT
VARIABLE_VALUE / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Uptime’) AS QPS
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = ‘Queries’;
+———+——————-+
| QPS | VARIABLE_SOURCE |
+———+——————-+
| 0.9259 | global |
+———+——————-+
# 计算缓冲池命中率
mysql> SELECT
ROUND((1 – (VARIABLE_VALUE / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_read_requests’))) * 100, 2) AS BUFFER_POOL_HIT_RATE
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_reads’;
+———————+——————-+
| BUFFER_POOL_HIT_RATE | VARIABLE_SOURCE |
+———————+——————-+
| 99.90 | global |
+———————+——————-+
3.1.2 SHOW VARIABLES命令
SHOW VARIABLES命令用于查看MySQL服务器的系统变量。
mysql> SHOW GLOBAL VARIABLES;
# 输出结果太多,这里只显示部分
# 查看特定的系统变量
mysql> SHOW GLOBAL VARIABLES LIKE ‘max_connections’;
+—————–+——-+——————-+
| Variable_name | Value | Variable_source |
+—————–+——-+——————-+
| max_connections | 1000 | my.cnf |
+—————–+——-+——————-+
# 查看InnoDB相关的系统变量
mysql> SHOW GLOBAL VARIABLES LIKE ‘innodb%’ LIMIT 10;
+—————————+—————-+——————-+
| Variable_name | Value | Variable_source |
+—————————+—————-+——————-+
| innodb_adaptive_flushing | ON | my.cnf |
| innodb_adaptive_hash_index| ON | my.cnf |
| innodb_buffer_pool_chunk_size | 134217728 | compiled in |
| innodb_buffer_pool_instances | 8 | my.cnf |
| innodb_buffer_pool_size | 1073741824 | my.cnf |
| innodb_data_file_path | ibdata1:12M:autoextend | compiled in |
| innodb_data_home_dir | | compiled in |
| innodb_doublewrite | ON | my.cnf |
| innodb_fast_shutdown | 1 | compiled in |
| innodb_file_format | Barracuda | compiled in |
+—————————+—————-+——————-+
3.1.3 SHOW PROCESSLIST命令
SHOW PROCESSLIST命令用于查看当前连接到MySQL服务器的进程信息。
mysql> SHOW PROCESSLIST;
+—–+——+—————–+———+———+——+——————-+———————————————-+
| Id | User | HOST | DB | COMMAND | TIME | STATE | INFO |
+—–+——+—————–+———+———+——+——————-+———————————————-+
| 123 | root | localhost | NULL | Sleep | 100 | | NULL |
| 124 | app_user | 192.168.1.100:54321 | fgedudb | Query | 30 | Sending data | SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10 |
| 125 | app_user | 192.168.1.100:54322 | fgedudb | Sleep | 25 | | NULL |
| 126 | app_user | 192.168.1.100:54323 | fgedudb | Sleep | 20 | | NULL |
| 127 | app_user | 192.168.1.100:54324 | fgedudb | Query | 15 | Sorting result | SELECT * FROM fgedu_users WHERE status = 1 ORDER BY created_at DESC |
+—–+——+—————–+———+———+——+——————-+———————————————-+
# 查看详细的进程信息
mysql> SHOW FULL PROCESSLIST;
# 输出结果包含完整的SQL语句
3.1.4 Performance Schema
Performance Schema是MySQL提供的用于监控服务器性能的功能。
mysql> SHOW GLOBAL VARIABLES LIKE ‘performance_schema’;
+——————–+——-+——————-+
| Variable_name | Value | Variable_source |
+——————–+——-+——————-+
| performance_schema | ON | my.cnf |
+——————–+——-+——————-+
# 查看Performance Schema的监控表
mysql> SHOW TABLES FROM performance_schema LIMIT 10;
+———————————————-+
| Tables_in_performance_schema |
+———————————————-+
| accounts |
| cond_instances |
| events_stages_current |
| events_stages_history |
| events_stages_history_long |
| events_stages_summary_by_account_by_event_name |
| events_stages_summary_by_host_by_event_name |
| events_stages_summary_by_thread_by_event_name |
| events_stages_summary_by_user_by_event_name |
| events_stages_summary_global_by_event_name |
+———————————————-+
# 查询索引使用情况
mysql> SELECT
OBJECT_SCHEMA,
OBJECT_NAME,
INDEX_NAME,
COUNT_FETCH,
COUNT_INSERT,
COUNT_UPDATE,
COUNT_DELETE
FROM
performance_schema.table_io_waits_summary_by_index_usage
WHERE
OBJECT_SCHEMA = ‘fgedudb’
ORDER BY
OBJECT_NAME, INDEX_NAME;
# 输出示例(部分)
+—————+——————+————————+————-+————–+————–+————–+
| OBJECT_SCHEMA | OBJECT_NAME | INDEX_NAME | COUNT_FETCH | COUNT_INSERT | COUNT_UPDATE | COUNT_DELETE |
+—————+——————+————————+————-+————–+————–+————–+
| fgedudb | fgedu_orders | PRIMARY | 2000 | 1000 | 300 | 100 |
| fgedudb | fgedu_orders | fk_order_user_id | 1500 | 0 | 0 | 0 |
| fgedudb | fgedu_orders | idx_order_date | 800 | 0 | 0 | 0 |
| fgedudb | fgedu_orders | idx_status | 0 | 0 | 0 | 0 |
+—————+——————+————————+————-+————–+————–+————–+
3.2 第三方监控工具
除了内置监控工具外,还有许多第三方监控工具可以用于MySQL监控。
3.2.1 MySQL Enterprise Monitor
MySQL Enterprise Monitor是Oracle官方提供的商业监控工具,提供全面的MySQL监控和管理功能。
3.2.2 Nagios
Nagios是一款开源的监控系统,可以通过插件扩展支持MySQL监控。
# yum install nagios-plugins-mysql
# 配置MySQL监控
# vi /etc/nagios/objects/commands.cfg
define command {
command_name check_mysql_health
command_line $USER1$/check_mysql_health –hostname=$HOSTADDRESS$ –username=$ARG1$ –password=$ARG2$ –mode=$ARG3$ $ARG4$
}
# 配置服务监控
# vi /etc/nagios/objects/services.cfg
define service {
use generic-service
host_name mysql-server
service_description MySQL Connections
check_command check_mysql_health!nagios!password!connections!
}
define service {
use generic-service
host_name mysql-server
service_description MySQL QPS
check_command check_mysql_health!nagios!password!questions!
}
define service {
use generic-service
host_name mysql-server
service_description MySQL Slow Queries
check_command check_mysql_health!nagios!password!slow-queries!
}
3.2.3 Zabbix
Zabbix是一款开源的企业级监控系统,提供对MySQL的全面监控支持。
# yum install zabbix-agent-mysql
# 配置MySQL用户
mysql> CREATE USER ‘zabbix’@’localhost’ IDENTIFIED BY ‘password’;
mysql> GRANT USAGE, REPLICATION CLIENT, PROCESS ON *.* TO ‘zabbix’@’localhost’;
mysql> GRANT SELECT ON performance_schema.* TO ‘zabbix’@’localhost’;
# 配置Zabbix agent
# vi /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf
# 确保配置文件中的用户名和密码正确
# 重启Zabbix agent
# systemctl restart zabbix-agent
# 在Zabbix Web界面中添加MySQL监控模板
# 配置 > 主机 > 选择主机 > 模板 > 链接新模板 > 选择MySQL模板
3.2.4 Prometheus + Grafana
Prometheus是一款开源的监控和告警工具,Grafana是一款开源的数据可视化工具,两者结合可以提供强大的MySQL监控能力。
# wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.0/mysqld_exporter-0.15.0.linux-amd64.tar.gz
# tar -xzf mysqld_exporter-0.15.0.linux-amd64.tar.gz
# cd mysqld_exporter-0.15.0.linux-amd64
# 配置MySQL用户
mysql> CREATE USER ‘exporter’@’localhost’ IDENTIFIED BY ‘password’;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO ‘exporter’@’localhost’;
# 创建配置文件
# vi .my.cnf
[client]
user=exporter
password=password
# 启动exporter
# ./mysqld_exporter –config.my-cnf=.my.cnf
# 配置Prometheus
# vi prometheus.yml
scrape_configs:
– job_name: ‘mysql’
static_configs:
– targets: [‘localhost:9104’]
# 启动Prometheus
# ./prometheus –config.file=prometheus.yml
# 配置Grafana
# 在Grafana中添加Prometheus数据源
# 导入MySQL监控仪表盘(ID: 7362)
3.3 自定义监控脚本
除了使用现成的监控工具外,还可以编写自定义的监控脚本,满足特定的监控需求。
# mysql_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# MySQL配置信息
MYSQL_USER=”root”
MYSQL_PASS=”password”
MYSQL_HOST=”localhost”
MYSQL_PORT=”3306″
# 监控指标存储文件
METRICS_FILE=”/mysql/monitor/mysql_metrics.txt”
# 时间戳
TIMESTAMP=$(date ‘+%Y-%m-%d %H:%M:%S’)
# 获取监控指标
QPS=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SELECT VARIABLE_VALUE / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Uptime’) AS QPS FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Queries’;” -N)
TPS=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SELECT (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Com_commit’) + (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Com_rollback’) AS TPS;” -N)
CONNECTIONS=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SHOW GLOBAL STATUS LIKE ‘Threads_connected’;” -N | awk ‘{print $2}’)
MAX_CONNECTIONS=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SHOW GLOBAL VARIABLES LIKE ‘max_connections’;” -N | awk ‘{print $2}’)
SLOW_QUERIES=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SHOW GLOBAL STATUS LIKE ‘Slow_queries’;” -N | awk ‘{print $2}’)
BUFFER_POOL_HIT_RATE=$(mysql -u $MYSQL_USER -p”$MYSQL_PASS” -h $MYSQL_HOST -P $MYSQL_PORT -e “SELECT ROUND((1 – (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_reads’) / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_read_requests’)) * 100, 2) AS BUFFER_POOL_HIT_RATE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = ‘Uptime’;” -N)
# 存储监控指标
echo “$TIMESTAMP QPS=$QPS TPS=$TPS CONNECTIONS=$CONNECTIONS MAX_CONNECTIONS=$MAX_CONNECTIONS SLOW_QUERIES=$SLOW_QUERIES BUFFER_POOL_HIT_RATE=$BUFFER_POOL_HIT_RATE” >> $METRICS_FILE
# 检查告警条件
if (( $(echo “$CONNECTIONS > $MAX_CONNECTIONS * 0.8” | bc -l) )); then
echo “告警:MySQL连接数过高,当前连接数:$CONNECTIONS,最大连接数:$MAX_CONNECTIONS” | mail -s “MySQL连接数告警” dba@fgedu.net.cn
fi
if (( $(echo “$SLOW_QUERIES > 100” | bc -l) )); then
echo “告警:MySQL慢查询数过高,当前慢查询数:$SLOW_QUERIES” | mail -s “MySQL慢查询告警” dba@fgedu.net.cn
fi
if (( $(echo “$BUFFER_POOL_HIT_RATE < 95" | bc -l) )); then echo "告警:MySQL缓冲池命中率过低,当前命中率:$BUFFER_POOL_HIT_RATE%" | mail -s "MySQL缓冲池命中率告警" dba@fgedu.net.cn fi # 保留最近30天的监控数据 find /mysql/monitor -name "mysql_metrics.txt" -mtime +30 -delete
# crontab -e
* * * * * /mysql/scripts/mysql_monitor.sh
# 查看监控数据
# tail -n 10 /mysql/monitor/mysql_metrics.txt
2026-04-02 22:00:00 QPS=0.92 TPS=0.12 CONNECTIONS=20 MAX_CONNECTIONS=1000 SLOW_QUERIES=20 BUFFER_POOL_HIT_RATE=99.90
2026-04-02 22:01:00 QPS=0.93 TPS=0.13 CONNECTIONS=21 MAX_CONNECTIONS=1000 SLOW_QUERIES=20 BUFFER_POOL_HIT_RATE=99.89
2026-04-02 22:02:00 QPS=0.91 TPS=0.11 CONNECTIONS=19 MAX_CONNECTIONS=1000 SLOW_QUERIES=20 BUFFER_POOL_HIT_RATE=99.90
2026-04-02 22:03:00 QPS=0.95 TPS=0.14 CONNECTIONS=22 MAX_CONNECTIONS=1000 SLOW_QUERIES=21 BUFFER_POOL_HIT_RATE=99.88
2026-04-02 22:04:00 QPS=0.94 TPS=0.13 CONNECTIONS=20 MAX_CONNECTIONS=1000 SLOW_QUERIES=21 BUFFER_POOL_HIT_RATE=99.89
2026-04-02 22:05:00 QPS=0.96 TPS=0.15 CONNECTIONS=23 MAX_CONNECTIONS=1000 SLOW_QUERIES=21 BUFFER_POOL_HIT_RATE=99.87
2026-04-02 22:06:00 QPS=0.97 TPS=0.16 CONNECTIONS=25 MAX_CONNECTIONS=1000 SLOW_QUERIES=22 BUFFER_POOL_HIT_RATE=99.86
2026-04-02 22:07:00 QPS=0.95 TPS=0.15 CONNECTIONS=24 MAX_CONNECTIONS=1000 SLOW_QUERIES=22 BUFFER_POOL_HIT_RATE=99.87
2026-04-02 22:08:00 QPS=0.98 TPS=0.17 CONNECTIONS=26 MAX_CONNECTIONS=1000 SLOW_QUERIES=23 BUFFER_POOL_HIT_RATE=99.85
2026-04-02 22:09:00 QPS=0.99 TPS=0.18 CONNECTIONS=28 MAX_CONNECTIONS=1000 SLOW_QUERIES=23 BUFFER_POOL_HIT_RATE=99.84
3.4 监控仪表盘
监控仪表盘可以将监控数据可视化,便于直观地查看数据库的运行状态和性能指标。
– MySQL Enterprise Monitor Dashboard
– Zabbix MySQL Dashboard
– Grafana MySQL Dashboard(ID: 7362、ID: 14057等)
– Prometheus + Grafana MySQL Dashboard
Part04-生产案例与实战讲解
4.1 性能问题排查
使用监控数据排查MySQL性能问题的实战案例。
问题描述:应用程序报告数据库响应时间变慢,需要找出原因并解决
解决方法:使用监控工具收集性能数据,分析并定位问题
# top
%Cpu(s): 90.0 us, 5.0 sy, 0.0 ni, 5.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8192000 total, 204800 free, 7680000 used, 307200 buff/cache
KiB Swap: 4096000 total, 3584000 free, 512000 used. 128000 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
12345 mysql 20 0 1234567 204800 36800 S 85.0 5.0 0:30.00 mysqld
# 2. 检查MySQL连接数
mysql> SHOW GLOBAL STATUS LIKE ‘Threads_connected’;
+——————-+——-+——————-+
| Variable_name | Value | Variable_source |
+——————-+——-+——————-+
| Threads_connected | 200 | global |
+——————-+——-+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘max_connections’;
+—————–+——-+——————-+
| Variable_name | Value | Variable_source |
+—————–+——-+——————-+
| max_connections | 1000 | my.cnf |
+—————–+——-+——————-+
# 3. 检查慢查询
mysql> SHOW GLOBAL STATUS LIKE ‘Slow_queries’;
+—————+——-+——————-+
| Variable_name | Value | Variable_source |
+—————+——-+——————-+
| Slow_queries | 100 | global |
+—————+——-+——————-+
# 查看慢查询日志
# tail -n 50 /mysql/logs/slow.log
# Time: 2026-04-02T22:00:00.123456Z
# User@Host: app_user[app_user] @ 192.168.1.100 [192.168.1.100]
# Query_time: 30.000000 Lock_time: 0.000000 Rows_sent: 10 Rows_examined: 100000
use fgedudb;
SET timestamp=1750000000;
SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10;
# 4. 分析慢查询
mysql> EXPLAIN SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10;
+—-+————-+————+————+——+—————+——+———+——+——–+———-+———————————+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——+—————+——+———+——+——–+———-+———————————+
| 1 | SIMPLE | fgedu_orders| NULL | ALL | NULL | NULL | NULL | NULL | 50000 | 100.00 | Using temporary; Using filesort |
+—-+————-+————+————+——+—————+——+———+——+——–+———-+———————————+
# 5. 优化查询
# 原查询:
SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10;
# 优化后查询:
SELECT * FROM fgedu_orders WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM fgedu_orders) LIMIT 10;
# 验证优化效果
mysql> EXPLAIN SELECT * FROM fgedu_orders WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM fgedu_orders) LIMIT 10;
+—-+————-+————+————+——-+—————+———+———+——+——-+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———+———+——+——-+———-+————-+
| 1 | PRIMARY | fgedu_orders| NULL | range | PRIMARY | PRIMARY | 4 | NULL | 25000 | 100.00 | Using where |
| 2 | SUBQUERY | fgedu_orders| NULL | index | NULL | PRIMARY | 4 | NULL | 50000 | 100.00 | Using index |
+—-+————-+————+————+——-+—————+———+———+——+——-+———-+————-+
# 6. 监控优化后的效果
# 再次查看慢查询数
mysql> SHOW GLOBAL STATUS LIKE ‘Slow_queries’;
+—————+——-+——————-+
| Variable_name | Value | Variable_source |
+—————+——-+——————-+
| Slow_queries | 101 | global |
+—————+——-+——————-+
# 慢查询数停止增长,说明优化有效
4.2 资源瓶颈分析
使用监控数据分析MySQL资源瓶颈的实战案例。
问题描述:服务器内存使用率持续高于90%,需要找出原因并解决
解决方法:使用监控工具分析内存使用情况,定位内存消耗大户
# free -m
total used free shared buff/cache available
Mem: 8192 7680 128 128 384 128
Swap: 4096 512 3584
# 2. 检查MySQL内存配置
mysql> SHOW GLOBAL VARIABLES LIKE ‘innodb_buffer_pool_size’;
+————————-+—————-+——————-+
| Variable_name | Value | Variable_source |
+————————-+—————-+——————-+
| innodb_buffer_pool_size | 6442450944 | my.cnf |
+————————-+—————-+——————-+
# 6442450944 = 6GB
mysql> SHOW GLOBAL VARIABLES LIKE ‘key_buffer_size’;
+—————–+———+——————-+
| Variable_name | Value | Variable_source |
+—————–+———+——————-+
| key_buffer_size | 134217728 | my.cnf |
+—————–+———+——————-+
# 134217728 = 128MB
mysql> SHOW GLOBAL VARIABLES LIKE ‘%cache_size’;
+———————-+———+——————-+
| Variable_name | Value | Variable_source |
+———————-+———+——————-+
| binlog_cache_size | 32768 | my.cnf |
| binlog_stmt_cache_size | 32768 | my.cnf |
| host_cache_size | 279 | my.cnf |
| innodb_ft_cache_size | 8388608 | compiled in |
| innodb_ft_total_cache_size | 6442450944 | compiled in |
| key_cache_size | 134217728 | my.cnf |
| query_cache_size | 0 | my.cnf |
| table_definition_cache | 400 | my.cnf |
| table_open_cache | 2000 | my.cnf |
+———————-+———+——————-+
# 3. 计算MySQL总内存使用
# 公式:
# Total MySQL Memory = innodb_buffer_pool_size + key_buffer_size + (table_open_cache * table_definition_cache) + (max_connections * (read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size + binlog_cache_size)) + other small buffers
# 查看相关参数
mysql> SHOW GLOBAL VARIABLES LIKE ‘max_connections’;
+—————–+——-+——————-+
| Variable_name | Value | Variable_source |
+—————–+——-+——————-+
| max_connections | 1000 | my.cnf |
+—————–+——-+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘read_buffer_size’;
+——————+——–+——————-+
| Variable_name | Value | Variable_source |
+——————+——–+——————-+
| read_buffer_size | 131072 | my.cnf |
+——————+——–+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘read_rnd_buffer_size’;
+———————-+——–+——————-+
| Variable_name | Value | Variable_source |
+———————-+——–+——————-+
| read_rnd_buffer_size | 262144 | my.cnf |
+———————-+——–+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘sort_buffer_size’;
+——————+——–+——————-+
| Variable_name | Value | Variable_source |
+——————+——–+——————-+
| sort_buffer_size | 262144 | my.cnf |
+——————+——–+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘join_buffer_size’;
+——————+——–+——————-+
| Variable_name | Value | Variable_source |
+——————+——–+——————-+
| join_buffer_size | 262144 | my.cnf |
+——————+——–+——————-+
# 4. 计算内存使用
# innodb_buffer_pool_size: 6GB
# key_buffer_size: 128MB
# 连接相关内存: 1000 * (128KB + 256KB + 256KB + 256KB + 32KB) = 1000 * 928KB ≈ 906MB
# 其他内存: 约200MB
# 总内存: 6GB + 128MB + 906MB + 200MB ≈ 7.2GB
# 服务器总内存: 8GB
# MySQL内存使用率: 7.2GB / 8GB = 90%
# 5. 优化内存配置
# 减少innodb_buffer_pool_size
# vi /etc/my.cnf
innodb_buffer_pool_size = 4G
# 重启MySQL
# systemctl restart mysqld
# 验证优化效果
# free -m
total used free shared buff/cache available
Mem: 8192 5680 2128 128 384 2128
Swap: 4096 512 3584
4.3 连接问题处理
使用监控数据处理MySQL连接问题的实战案例。
问题描述:应用程序报告”Too many connections”错误,无法连接到数据库
解决方法:分析连接数情况,调整连接配置或优化应用程序
mysql> SHOW GLOBAL STATUS LIKE ‘Threads_connected’;
+——————-+——-+——————-+
| Variable_name | Value | Variable_source |
+——————-+——-+——————-+
| Threads_connected | 1000 | global |
+——————-+——-+——————-+
# 查看最大连接数
mysql> SHOW GLOBAL VARIABLES LIKE ‘max_connections’;
+—————–+——-+——————-+
| Variable_name | Value | Variable_source |
+—————–+——-+——————-+
| max_connections | 1000 | my.cnf |
+—————–+——-+——————-+
# 2. 查看连接详情
mysql> SHOW PROCESSLIST;
+—–+——+—————–+———+———+——+——-+——————+
| Id | User | Host | db | Command | Time | State | Info |
+—–+——+—————–+———+———+——+——-+——————+
| 123 | root | localhost | NULL | Sleep | 100 | | NULL |
| 124 | app_user | 192.168.1.100:54321 | fgedudb | Sleep | 30 | | NULL |
| 125 | app_user | 192.168.1.100:54322 | fgedudb | Sleep | 25 | | NULL |
| … | … | … | … | … | … | … | … |
| 1123 | app_user | 192.168.1.100:55323 | fgedudb | Sleep | 1 | | NULL |
+—–+——+—————–+———+———+——+——-+——————+
# 3. 分析连接状态
mysql> SELECT
Command,
COUNT(*) AS Count
FROM
information_schema.PROCESSLIST
GROUP BY
Command
ORDER BY
Count DESC;
+———+——-+
| Command | Count |
+———+——-+
| Sleep | 950 |
| Query | 45 |
| Binlog Dump | 5 |
+———+——-+
# 4. 查看连接超时设置
mysql> SHOW GLOBAL VARIABLES LIKE ‘wait_timeout’;
+—————+——-+——————-+
| Variable_name | Value | Variable_source |
+—————+——-+——————-+
| wait_timeout | 28800 | my.cnf |
+—————+——-+——————-+
mysql> SHOW GLOBAL VARIABLES LIKE ‘interactive_timeout’;
+———————+——-+——————-+
| Variable_name | Value | Variable_source |
+———————+——-+——————-+
| interactive_timeout | 28800 | my.cnf |
+———————+——-+——————-+
# 5. 解决方法
# 方法1:增加最大连接数
mysql> SET GLOBAL max_connections = 2000;
Query OK, 0 rows affected (0.00 sec)
# 在配置文件中永久修改
# vi /etc/my.cnf
max_connections = 2000
# 方法2:减少连接超时时间
mysql> SET GLOBAL wait_timeout = 7200;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL interactive_timeout = 7200;
Query OK, 0 rows affected (0.00 sec)
# 在配置文件中永久修改
# vi /etc/my.cnf
wait_timeout = 7200
interactive_timeout = 7200
# 方法3:优化应用程序连接池
# 调整应用程序连接池配置,减少最大连接数,增加连接超时时间
Part05-风哥经验总结与分享
5.1 监控最佳实践
- 全面监控:监控MySQL的各个方面,包括性能、资源、连接、存储等
- 分层监控:从系统层面、数据库层面和应用层面进行分层监控
- 实时监控:对关键指标进行实时监控,及时发现问题
- 历史分析:存储历史监控数据,便于趋势分析和容量规划
- 告警合理:设置合理的告警阈值,避免误报和漏报
- 自动化处理:对于常见问题,实现自动化处理和恢复
- 持续优化:根据监控数据,持续优化MySQL配置和应用程序
- 文档化:记录监控策略、告警规则和处理流程,便于团队协作
5.2 常见问题与解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 监控数据不准确 | 统计信息过时,监控工具配置错误,采样频率不合理 | 定期更新统计信息,检查监控工具配置,调整采样频率 |
| 告警过多 | 告警阈值设置过低,告警规则不合理,重复告警 | 调整告警阈值,优化告警规则,实现告警抑制 |
| 告警过少 | 告警阈值设置过高,监控指标不全面,告警通知方式失效 | 降低告警阈值,增加监控指标,检查告警通知方式 |
| 监控工具影响性能 | 监控频率过高,监控查询过于复杂,监控工具资源消耗过大 | 降低监控频率,优化监控查询,选择性能影响小的监控工具 |
| 监控数据存储问题 | 存储容量不足,存储性能下降,数据保留时间过长 | 增加存储容量,优化存储性能,设置合理的数据保留时间 |
| 监控仪表盘不直观 | 指标选择不合理,布局混乱,可视化效果差 | 选择关键指标,优化布局,使用合适的可视化图表 |
from MySQL:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
