真正能快速定位热锁的是 sys.schema_mutex_waits 视图(mysql 5.7+),它聚合 performance_schema 原始数据,清晰列出等待时间、持有者线程和锁名;需确保 performance_schema 已启用且相关 instruments 开启。

查 MySQL 内核 mutex 竞争用什么命令
直接看 performance_schema.data_locks 和 performance_schema.mutex_instances,但默认不开启。真正能快速定位热锁的是 sys.schema_mutex_waits 视图(MySQL 5.7+),它聚合了 performance_schema 的原始数据,把等待时间、持有者线程、锁名都列清楚了。
实操建议:
- 先确认
performance_schema已启用:SELECT @@performance_schema;必须为1 - 开关键表采集:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'wait/synch/mutex/%'; - 查当前最热 mutex:
SELECT * FROM sys.schema_mutex_waits ORDER BY avg_wait_time DESC LIMIT 5; - 注意:
sys库需预装(MySQL 5.7+ 默认带,但某些精简版或旧部署可能缺失)
innodb_thread_concurrency 设置多少才不卡
这个参数不是“越大越好”,也不是“设 0 就放飞”。它控制 InnoDB 内部线程调度器允许同时进入内核临界区的线程数,设太高会加剧 mutex 争抢(比如 kernel_mutex 或 dict_operation_lock),设太低又浪费 CPU。
实操建议:
- 默认值
0表示不限制,但实际依赖innodb_concurrency_tickets做批处理控制,对高并发写入场景反而更稳 - 若观察到
SHOW ENGINE INNODB STATUS中频繁出现SEMAPHORES下的os_waits高企,且mutex_instances.COUNT_STAR > 10000,可尝试设为32或64 - 必须配合
innodb_concurrency_tickets=5000(默认值)使用,否则单个线程拿到 ticket 后容易霸占太久 - 该参数在 MySQL 8.0.30+ 已被标记为 deprecated,新环境优先调
innodb_adaptive_max_sleep_delay和线程池
哪些 mutex 最常成为瓶颈
不是所有 mutex 都值得调优。真正影响 TPCC 或 OLTP 写密集负载的,集中在三类:字典操作锁、缓冲池链表锁、日志系统锁。它们的名字在 mutex_instances.NAME 里固定可查,别靠猜。
实操建议:
- 高频瓶颈 mutex 示例:
innodb/dict/dict_sys_mutex(建表/删表时争抢)、innodb/buf/buf_pool_mutex(老版本 5.6 中严重,8.0 已分片)、innodb/log/log_sys_mutex(高 TPS 下刷 log buffer 争抢) -
dict_sys_mutex竞争高?说明 DDL 太频繁,或存在未加索引的information_schema查询(如慢查询里带SELECT * FROM TABLES WHERE ...) -
log_sys_mutex竞争高?优先检查innodb_log_buffer_size是否过小(默认 16MB,大事务多时建议 64MB),以及是否启用了innodb_flush_log_at_trx_commit=1却没配 SSD - 别碰
srv_sys_mutex或trx_sys_mutex—— 它们是 InnoDB 内部调度核心,强行优化往往引入死锁或崩溃
用 pt-pmp 抓堆栈确认锁在哪一行代码卡住
pt-pmp(Percona Toolkit 的 stack profiler)不是看 SQL,而是看 mysqld 进程在 OS 层到底卡在哪个函数调用上。对定位 mutex 死等特别有效,比如发现一堆线程全停在 os_event_wait_low 或 ib_mutex_enter_func。
实操建议:
- 安装后执行:
pt-pmp -p $(pgrep -f "mysqld") -g --limit 100,输出按调用栈聚合次数排序 - 关键线索看末尾函数:如果大量栈顶是
row_update_for_mysql→dict_table_get→dict_table_open_on_name→dict_sys_mutex,那就是 DDL + DML 混合导致的字典锁争抢 - 注意:必须用 debug 版 mysqld 或带符号表的二进制(官方 RPM/DEB 通常不含),否则函数名显示为
??? - 别在生产高峰持续运行 ——
pt-pmp会多次gdb attach,可能短暂阻塞线程
mutex 竞争本质是共享资源访问路径上的串行化点,调优不是消灭它,而是让争抢变短、变少、变分散。最容易被忽略的一点:很多“高 mutex 等待”其实源于慢查询没走索引,导致扫描放大了锁持有时间——先看 slow_query_log,再翻 mutex_instances。










