事务CPU压力源于锁竞争、索引失效、缓冲池争用等综合因素,需结合SHOW PROCESSLIST状态、rows_examined、innodb_row_lock_time_avg及pt-pmp火焰图协同诊断。

查 SHOW PROCESSLIST 看事务卡在哪种状态
事务本身不直接“吃”CPU,但它的执行状态会暴露CPU是否在空转等待或被低效逻辑拖住。比如大量事务停在 Sending data 或 Sorting result,说明CPU正在做计算(排序、聚合),而停在 Locked 或 Waiting for table metadata lock 则大概率是锁竞争,CPU其实在等——这时候top里MySQL进程CPU可能不高,但业务已卡死。
- 执行
SHOW FULL PROCESSLIST,重点筛出Time值大且状态异常的连接,尤其关注Command是Query但State长时间不变的 - 配合
SELECT * FROM performance_schema.events_statements_current WHERE WORK_COMPLETED = 0找出真正卡住的语句(需提前开启performance_schema) - 避免只看
State = "Sleep"就认为没事——它可能是长事务没提交,正拿着锁阻塞别人
用 EXPLAIN FORMAT=JSON 看事务内SQL是否触发全表扫描
事务中一条没走索引的 UPDATE 或 SELECT ... FOR UPDATE,会让InnoDB扫描整张表加锁,不仅IO暴涨,CPU还要反复比对行锁条件、维护锁结构,高并发下直接把CPU推满。
- 对事务里的每条DML/SELECT加
EXPLAIN FORMAT=JSON,重点看execution_plan里type是否为ALL,rows_examined是否远超预期 - 特别注意
WHERE条件含函数(如DATE(create_time))或隐式类型转换(如字符串ID和数字比较),这类写法会让索引失效,且无法从慢日志直接识别——因为语句本身可能不慢,但加了事务锁后就恶性循环 - 不要只依赖
log_queries_not_using_indexes:它只记录无索引的查询,不记录事务中因锁升级导致的额外开销
监控 innodb_row_lock_waits 和 innodb_row_lock_time_avg
这两个状态变量才是事务级CPU压力的“体温计”。当 innodb_row_lock_waits 每秒持续上涨,且 innodb_row_lock_time_avg 超过 10ms,说明事务频繁争抢同一行/页,CPU大量消耗在锁队列调度、唤醒、上下文切换上,而非实际计算。
- 用
SHOW GLOBAL STATUS LIKE 'innodb_row_lock%'实时查看,结合pt-stalk抓取突增时刻的完整堆栈(包括SHOW ENGINE INNODB STATUS输出) - 注意:该指标对
READ COMMITTED隔离级别不敏感,但对REPEATABLE READ下的间隙锁(Gap Lock)极其敏感——一个未覆盖索引的范围查询可能锁住上千个间隙,引发连锁等待 - 别盲目调大
innodb_lock_wait_timeout:它只是让等待变“静默”,不解决争抢根源,反而掩盖问题
抓 pt-pmp 火焰图定位CPU热点函数
当 top 显示 mysqld 进程CPU长期 >80%,但慢日志、锁统计都“看起来正常”时,大概率是事务处理链路中的某个C++函数成了瓶颈,比如 row_sel_store_mysql_rec(回表取数据)、lock_rec_lock(加记录锁)、dict_table_stats_update(统计信息更新)。
- 用
pt-pmp --pid $(pgrep mysqld) --interval 0.1 --run-time 60抓取60秒的调用栈样本,生成火焰图分析最宽的函数分支 - 常见陷阱:在高并发事务场景下,
buf_pool_mutex(缓冲池互斥锁)争用会导致所有线程在buf_pool_get处排队,此时火焰图顶部会密集出现mutex_spin_wait,这不是SQL问题,而是innodb_buffer_pool_instances设置过小(默认1)导致锁粒度太粗 - 别在生产环境直接跑
gdb attach:MySQL线程模型特殊,attach可能触发死锁或崩溃;pt-pmp是安全的替代方案
事务的CPU影响从来不是单点问题——它藏在锁、索引、隔离级别、甚至缓冲池配置的咬合缝隙里。最容易被忽略的是:你以为在优化SQL,其实瓶颈早转移到了锁管理器或内存子系统。盯住 State、rows_examined、innodb_row_lock_time_avg 和火焰图这四个信号,比调任何参数都管用。











