MySQL通过performance_schema定位未提交事务所执行的SQL
发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,经常会遇到这样一个场景:业务那边觉得数据库"很慢",上去通过show processlist查看发现大量State为在等待lock,如:Waiting for table metadata/level
千家信息网最后更新 2025年01月23日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安全错误
数据库的锁怎样保障安全
校园与班级网络安全教育
网络安全三本大学
数据库 lib
用友云使用阿里云服务器
后端软件开发笔试单选
服务器读不出来u盘
查xrd谱图的数据库
数据库id的字段设置
中国互联网管理服务器
我的世界服务器末地
海口机架式服务器
易语言杀毒软件开发
宜良软件开发咨询报价
阿里云服务器文档管理
广州服务器租用平台
软件开发组队
网络安全讲座如何开展
国泰数据库市场分析
软件开发的实习记录
wi-fidns服务器未响应
吉林博兴服务器
腾讯云服务器安全组默认配置
数据库应用问题
多服务器可以共用带宽
铁路装车软件开发语言是什么
眉山服务器租用
温州软件开发驻场哪家专业
全世界的网络总服务器在哪里
护苗 网络安全信息
数据分析需要数据库技术