MySQL通过performance_schema定位未提交事务所执行的SQL
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,经常会遇到这样一个场景:业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:Waiting for table metadata/level
千家信息网最后更新 2025年11月07日MySQL通过performance_schema定位未提交事务所执行的SQL经常会遇到这样一个场景:
业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:
Waiting for table metadata/level lock等
比如在执行一个DDL时,发现被hang住,查看到目前进程状态,有MDL
在实验环境里,我们很快就能定位到,应该是id为585这个线程,但是无法知道正在执行什么sql:
通过information_schema.innodb_trx\G,也不能查询到具体执行了什么sql。
通过简单的kill的确可以解决眼前的问题,但如果继续遇到该问题,也难以定位具体内容。
但其实,performance_schema.events_statements_current提供了相关信息,此处复现一下:
查看一下是否有事务未提交,可以发现的确有:
该事务内的语句执行完毕(处于Sleep),但未提交,就会看不到对应的trx_query:
只能根据trx_mysql_thread_id看到未提交的事务的process id,看一下processlist,INFO内也没有具体内容:
但只要打开了P_S,就可以通过performance_schema.events_statements_current来查看到对应的sql,包括已经执行完,但没有提交的。
通过如下语句,可以扩展show processlist的显示结果,并提供对应的SQL。
结果:
作者微信公众号(持续更新)

业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:
Waiting for table metadata/level lock等
比如在执行一个DDL时,发现被hang住,查看到目前进程状态,有MDL
- mysql> SHOW PROCESSLIST;
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- | Id | User | Host | db | Command | Time | State | Info |
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- | 585 | root | localhost | test | Sleep | 1658 | | NULL |
- | 586 | root | localhost | test | Query | 1654 | Waiting for table metadata lock | alter table t change name name varchar(32) |
- | 590 | root | localhost | test | Query | 0 | starting | show processlist |
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- 3 rows in set (0.00 sec)
在实验环境里,我们很快就能定位到,应该是id为585这个线程,但是无法知道正在执行什么sql:
通过information_schema.innodb_trx\G,也不能查询到具体执行了什么sql。
通过简单的kill的确可以解决眼前的问题,但如果继续遇到该问题,也难以定位具体内容。
但其实,performance_schema.events_statements_current提供了相关信息,此处复现一下:
- session1> BEGIN;
- Query OK, 0 rows affected (0.00 sec)
- session1> UPDATE t SET name='fasdfsad';
- Query OK, 3 rows affected (0.00 sec)
- Rows matched: 3 Changed: 3 Warnings: 0
- session2> ALTER TABLE t CHANGE name name varchar(32)
查看一下是否有事务未提交,可以发现的确有:
该事务内的语句执行完毕(处于Sleep),但未提交,就会看不到对应的trx_query:
- session3> SELECT * FROM information_schema.innodb_trx\G
- *************************** 1. row ***************************
- trx_id: 9614
- trx_state: RUNNING
- trx_started: 2017-09-19 15:58:05
- trx_requested_lock_id: NULL
- trx_wait_started: NULL
- trx_weight: 2
- trx_mysql_thread_id: 585
- trx_query: NULL
- trx_operation_state: NULL
- trx_tables_in_use: 0
- trx_tables_locked: 1
- trx_lock_structs: 2
- trx_lock_memory_bytes: 1136
- trx_rows_locked: 4
- trx_rows_modified: 0
- trx_concurrency_tickets: 0
- trx_isolation_level: REPEATABLE READ
- trx_unique_checks: 1
- trx_foreign_key_checks: 1
- trx_last_foreign_key_error: NULL
- trx_adaptive_hash_latched: 0
- trx_adaptive_hash_timeout: 0
- trx_is_read_only: 0
- trx_autocommit_non_locking: 0
- 1 row in set (0.00 sec)
只能根据trx_mysql_thread_id看到未提交的事务的process id,看一下processlist,INFO内也没有具体内容:
- session3> SHOW PROCESSLIST;
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- | Id | User | Host | db | Command | Time | State | Info |
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- | 585 | root | localhost | test | Sleep | 42 | | NULL |
- | 586 | root | localhost | test | Query | 37 | Waiting for table metadata lock | ALTER TABLE t CHANGE name name varchar(32) |
- | 590 | root | localhost | test | Query | 0 | starting | SHOW PROCESSLIST |
- +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
- 3 rows in set (0.00 sec)
但只要打开了P_S,就可以通过performance_schema.events_statements_current来查看到对应的sql,包括已经执行完,但没有提交的。
- session3> SELECT sql_text FROM performance_schema.events_statements_current;
- +-------------------------------------------------------------------+
- | sql_text |
- +-------------------------------------------------------------------+
- | UPDATE t SET name='fasdfsad' |
- | ALTER TABLE t CHANGE name name varchar(32) |
- | select sql_text from performance_schema.events_statements_current |
- +-------------------------------------------------------------------+
- 3 rows in set (0.00 sec)
通过如下语句,可以扩展show processlist的显示结果,并提供对应的SQL。
- SELECT b.processlist_id, c.db, a.sql_text, c.command, c.time, c.state
- FROM performance_schema.events_statements_current a JOIN performance_schema.threads b USING(thread_id)
- JOIN information_schema.processlist c ON b.processlist_id = c.id
- WHERE a.sql_text NOT LIKE '%performance%';
结果:
- +----------------+------+--------------------------------------------+---------+------+---------------------------------+
- | processlist_id | db | sql_text | command | time | state |
- +----------------+------+--------------------------------------------+---------+------+---------------------------------+
- | 585 | test | UPDATE t SET name='fasdfsad' | Sleep | 243 | |
- | 586 | test | ALTER TABLE t CHANGE name name varchar(32) | Query | 238 | Waiting for table metadata lock |
- +----------------+------+--------------------------------------------+---------+------+---------------------------------+
- 2 rows in set (0.01 sec)
作者微信公众号(持续更新)

事务
定位
内容
语句
信息
环境
结果
问题
复杂
不够
业务
作者
公众
可以通过
场景
常会
很快
数据
数据库
正在
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
升腾鲲鹏网络安全
储存服务器a控和b控
潜渊症连服务器进不去
亚信AntDB数据库
数据库管理工具查询表数据
软件开发模块确认表
网络安全恢复响应时间标准
高淳区公安局网络安全大队
rdlc 数据库 图片
深圳net软件开发服务费
软件开发后数据怎么保存
手机 服务器请求失败
湖南智能软件开发性价比
开通服务器访问权限需要什么
车载网络技术是发展背景
金融行业软件开发资质
无法打开安全数据库文件
方正 服务器
服务器虚拟化适合企业的业务吗
学生网络安全班会相片
网络安全攻防演练题
魔兽世界服务器排队一会上一会下
手机服务器地址在哪里查看
服务器内存有可能不兼容cpu吗
广州智腾互联网科技有限公司
eos无法连接数据库
六六服务器
查询命令行重启数据库
60数据库大全
阿里云 pd数据库与传统数据库