一、确认与定位
-
确认整体 CPU 使用情况
top -b -n1 | head -n15
-
观察 MySQL (
mysqld
) 进程所占的%CPU
。 -
如果是多核系统,关注总和以及单核是否满载。
-
-
查看系统负载
uptime
-
Load Average 长期高于 CPU 核数,说明系统压力大。
-
-
查看其它进程情况
ps aux --sort=-%cpu | head -n10
-
确认是否仅 MySQL 占用高,或与其它进程有关。
-
二、操作系统层面排查
-
磁盘 I/O 瓶颈
iostat -xz 1 3
-
查看
%iowait
,若较高(>20%),需检查磁盘性能。
-
-
内存/交换分区
free -m vmstat 1 5
-
确认是否发生大量 swap 使用或频繁换页,导致 CPU 等待。
-
-
网络状况(如果应用有大量远程访问)
netstat -anp | grep ESTABLISHED | wc -l
-
检查连接数和网络丢包。
-
三、MySQL 层面初步诊断
-
查看当前线程状态
SHOW PROCESSLIST;
-
查找
State
长时间处于Copying to tmp table
、Sorting result
、Locked
等状态的线程。 -
批量终止阻塞的查询
-- 1. 把所有超时(>60秒)的会话拼成一条 KILL 语句串 SELECT GROUP_CONCAT(CONCAT('KILL ', id) SEPARATOR ';') INTO @kill_stmt FROM information_schema.processlist WHERE TIME > 60; -- 2. (可选)查看一下拼出来的字符串 SELECT @kill_stmt; -- 3. PREPARE 并执行 PREPARE stmt FROM @kill_stmt; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-
-
查看全局状态指标
SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW GLOBAL STATUS LIKE 'Threads_running'; SHOW GLOBAL STATUS LIKE 'Innodb_rows_read'; SHOW GLOBAL STATUS LIKE 'Slow_queries';
-
关注活动线程数、慢查询数量变化趋势。
-
-
查看全局变量配置
SHOW VARIABLES WHERE Variable_name IN ( 'innodb_buffer_pool_size', 'innodb_buffer_pool_instances', 'query_cache_size', 'max_connections', 'innodb_thread_concurrency' );
-
与服务器内存、连接量匹配是否合理。
-
四、慢查询与热点 SQL 排查
-
开启慢查询日志
SET GLOBAL slow_query_log = ON; SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; SET GLOBAL long_query_time = 1; -- 记录超过1秒的查询
-
分析慢查询日志
使用pt-query-digest
(Percona 工具):pt-query-digest /var/log/mysql/slow.log > slow_report.txt
-
排名前若干耗时、执行次数多的 SQL。
-
-
实时监控
#从MySQL的性能监控系统中获取当前正在执行的SQL语句的性能数据,并按执行时间排序显示最耗时的10条语句。 SELECT * FROM performance_schema.events_statements_current ORDER BY TIMER_WAIT DESC LIMIT 10;
-
Performance Schema 可实时查看最耗时的语句。
-
五、索引与执行计划优化
-
查看慢查询执行计划
EXPLAIN SELECT …;
-
观察是否使用全表扫描(
type = ALL
)、临时表、文件排序等。
-
-
创建或调整索引
-
针对
EXPLAIN
中出现的possible_keys
、key_len
,增加或优化索引。 -
避免对低基数列或频繁更新列建索引。
-
-
SQL 重写
-
拆分复杂查询、避免子查询,使用
JOIN
、分批查询等方式降低单条 SQL 负载。
-
六、MySQL 配置调优
-
InnoDB 缓冲池
[mysqld] innodb_buffer_pool_size = 70% * total_ram innodb_buffer_pool_instances = 根据缓冲池大小适当设置(一般每实例1–2GB)
-
线程并发
innodb_thread_concurrency = CPU_核数 * 2
-
查询缓存(MySQL 5.7 或更低)
-
如果写操作频繁,可考虑关闭:
query_cache_type = 0 query_cache_size = 0
-
-
临时表与排序限制
sort_buffer_size = 2M tmp_table_size = 64M max_heap_table_size = 64M
-
连接数控制
max_connections = 根据业务高峰评估,避免过多连接导致上下文切换
修改完毕后,重启或动态生效:
systemctl restart mysqld
-- 或 --
SET GLOBAL innodb_buffer_pool_size = …;
七、资源隔离与硬件扩展
-
CPU 亲和/资源隔离
-
在多实例部署或虚拟化环境中,可通过
taskset
、cgroups 对 mysqld 进程限流。
-
-
读写分离
-
部署主从或中间件(如 ProxySQL),将读压力分散到只读从库。
-
-
硬件升级
-
如果长期高负载且业务持续增长,可考虑增加 CPU 核数、提升 I/O 性能(NVMe)、扩充内存。
-
八、持续监控与预警
-
监控指标
-
重点监控:CPU、Load、慢查询数、活跃连接数、Buffer Pool 命中率、锁等待、I/O 等。
-
推荐工具:Prometheus+Grafana、Zabbix、Percona Monitoring and Management (PMM)。
-
-
预警配置
-
针对关键指标设置报警阈值(如 CPU 超过80%、慢查询数突增)。
-