千家信息网

MySQL通过performance_schema定位未提交事务所执行的SQL

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,经常会遇到这样一个场景:业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:Waiting for table metadata/level
千家信息网最后更新 2026年11月02日MySQL通过performance_schema定位未提交事务所执行的SQL经常会遇到这样一个场景:
业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:
Waiting for table metadata/level lock等


比如在执行一个DDL时,发现被hang住,查看到目前进程状态,有MDL

  1. mysql> SHOW PROCESSLIST;
  2. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  3. | Id | User | Host | db | Command | Time | State | Info |
  4. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  5. | 585 | root | localhost | test | Sleep | 1658 | | NULL |
  6. | 586 | root | localhost | test | Query | 1654 | Waiting for table metadata lock | alter table t change name name varchar(32) |
  7. | 590 | root | localhost | test | Query | 0 | starting | show processlist |
  8. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  9. 3 rows in set (0.00 sec)

在实验环境里,我们很快就能定位到,应该是id为585这个线程,但是无法知道正在执行什么sql:
通过information_schema.innodb_trx\G,也不能查询到具体执行了什么sql。
通过简单的kill的确可以解决眼前的问题,但如果继续遇到该问题,也难以定位具体内容。


但其实,performance_schema.events_statements_current提供了相关信息,此处复现一下:

  1. session1> BEGIN;
  2. Query OK, 0 rows affected (0.00 sec)

  3. session1> UPDATE t SET name='fasdfsad';
  4. Query OK, 3 rows affected (0.00 sec)
  5. Rows matched: 3 Changed: 3 Warnings: 0


  1. session2> ALTER TABLE t CHANGE name name varchar(32)
发现被hang住


查看一下是否有事务未提交,可以发现的确有:
该事务内的语句执行完毕(处于Sleep),但未提交,就会看不到对应的trx_query:

  1. session3> SELECT * FROM information_schema.innodb_trx\G
  2. *************************** 1. row ***************************
  3. trx_id: 9614
  4. trx_state: RUNNING
  5. trx_started: 2017-09-19 15:58:05
  6. trx_requested_lock_id: NULL
  7. trx_wait_started: NULL
  8. trx_weight: 2
  9. trx_mysql_thread_id: 585
  10. trx_query: NULL
  11. trx_operation_state: NULL
  12. trx_tables_in_use: 0
  13. trx_tables_locked: 1
  14. trx_lock_structs: 2
  15. trx_lock_memory_bytes: 1136
  16. trx_rows_locked: 4
  17. trx_rows_modified: 0
  18. trx_concurrency_tickets: 0
  19. trx_isolation_level: REPEATABLE READ
  20. trx_unique_checks: 1
  21. trx_foreign_key_checks: 1
  22. trx_last_foreign_key_error: NULL
  23. trx_adaptive_hash_latched: 0
  24. trx_adaptive_hash_timeout: 0
  25. trx_is_read_only: 0
  26. trx_autocommit_non_locking: 0
  27. 1 row in set (0.00 sec)


只能根据trx_mysql_thread_id看到未提交的事务的process id,看一下processlist,INFO内也没有具体内容:


  1. session3> SHOW PROCESSLIST;
  2. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  3. | Id | User | Host | db | Command | Time | State | Info |
  4. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  5. | 585 | root | localhost | test | Sleep | 42 | | NULL |
  6. | 586 | root | localhost | test | Query | 37 | Waiting for table metadata lock | ALTER TABLE t CHANGE name name varchar(32) |
  7. | 590 | root | localhost | test | Query | 0 | starting | SHOW PROCESSLIST |
  8. +-----+------+-----------+------+---------+------+---------------------------------+--------------------------------------------+
  9. 3 rows in set (0.00 sec)


但只要打开了P_S,就可以通过performance_schema.events_statements_current来查看到对应的sql,包括已经执行完,但没有提交的。

  1. session3> SELECT sql_text FROM performance_schema.events_statements_current;
  2. +-------------------------------------------------------------------+
  3. | sql_text |
  4. +-------------------------------------------------------------------+
  5. | UPDATE t SET name='fasdfsad' |
  6. | ALTER TABLE t CHANGE name name varchar(32) |
  7. | select sql_text from performance_schema.events_statements_current |
  8. +-------------------------------------------------------------------+
  9. 3 rows in set (0.00 sec)
当然,在复杂的生产环境中,光凭上面的语句查出来的信息,是远远不够的。

通过如下语句,可以扩展show processlist的显示结果,并提供对应的SQL。

  1. SELECT b.processlist_id, c.db, a.sql_text, c.command, c.time, c.state
  2. FROM performance_schema.events_statements_current a JOIN performance_schema.threads b USING(thread_id)
  3. JOIN information_schema.processlist c ON b.processlist_id = c.id
  4. WHERE a.sql_text NOT LIKE '%performance%';

结果:
  1. +----------------+------+--------------------------------------------+---------+------+---------------------------------+
  2. | processlist_id | db | sql_text | command | time | state |
  3. +----------------+------+--------------------------------------------+---------+------+---------------------------------+
  4. | 585 | test | UPDATE t SET name='fasdfsad' | Sleep | 243 | |
  5. | 586 | test | ALTER TABLE t CHANGE name name varchar(32) | Query | 238 | Waiting for table metadata lock |
  6. +----------------+------+--------------------------------------------+---------+------+---------------------------------+
  7. 2 rows in set (0.01 sec)
也可以很容易定位到执行的内容是做了一个update操作未提交。


作者微信公众号(持续更新)


事务 定位 内容 语句 信息 环境 结果 问题 复杂 不够 业务 作者 公众 可以通过 场景 常会 很快 数据 数据库 正在 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司 互联网 科技创新 期待互联网科技 百单互联网科技有限公司 互联网前沿科技 恒生科技互联网指数分析 互联网 科技馆 成都互联网科技公司100强 互联网科技教育视频 阿大互联网科技有限公司 互联网科技大奖都有哪些公司 科技类公司包括互联网吗 卓翼科技产业互联网合作 烟台灵鸽互联网科技有限公司 互联网方面的科技前沿 互联网公司高科技产品 工业互联网科技成果转化 神州科技互联网有限公司 广州梦谷互联网科技有限公司领导 互联网企业和网络科技有限公司 关于新基建和互联网科技 北京互联网科技公司 齐家互联网科技有限公司 湖南洣水互联网科技有限公司扣款 科技赋能互联网健康 互联网大会黑科技排名 来此购互联网科技有限公司 浙江互联网科技研学营 江苏苏星互联网科技有限公司 亚光科技低轨卫星互联网
0