未提交事务

长期未提交事务,指开启事务后,长时间未向MySQL发出SQL执行请求或事务处理(COMMIT/ROLLBACK)请求,在系统表`information_schema`.`INNODB_TRX` 中状态为RUNNING,而在`information_schema`.`PROCESSLIST`中状态为SlEEP。

## 查看未提交的事务(3秒内未操作的事务)
SELECT
p.ID AS conn_id,
P.USER AS login_user,
P.HOST AS login_host,
p.DB AS database_name,
P.TIME AS trx_sleep_seconds,
TIME_TO_SEC(TIMEDIFF(NOW(),T.trx_started)) AS trx_open_seconds,
T.trx_started,
T.trx_isolation_level,
T.trx_tables_locked,
T.trx_rows_locked,
t.trx_state,
p.COMMAND AS process_state
FROM `information_schema`.`INNODB_TRX` t
INNER JOIN `information_schema`.`PROCESSLIST` p
ON t.trx_mysql_thread_id=p.id
WHERE t.trx_state='RUNNING'
AND p.COMMAND='Sleep'
AND P.TIME>
ORDER BY T.trx_started ASC \G

导致事务长期未提交的因素很多,常见的有:

、事务过程中执行其他非数据库操作,导致事务长期未被处理。
、事务处理异常或实现逻辑有误,导致事务未被正常处理。
、网段异常导致应用端请求未被正常发送给数据库,数据库等待应用后续操作。
、应用服务器性能问题(如CPU爆满),导致应用无法及时切换到该进程进行处理。

对于代码实现逻辑有误的问题,如果DBA能提供该事务执行的SQL语句将有助于研发快递定位,哪如何定位呢?

方式1:使用通用日志

## 查看general log配置
show variables like '%general_log%' ## 开启general log
SET GLOBAL general_log = ;

在通用日志中能看到

--29T13::07.932646+:     Query    SELECT * FROM `sys`.`processlist`
--29T13::36.049694+: Query SELECT * FROM `sys`.`processlist` WHERE CONN_ID=
--29T13::44.378687+: Query SELECT * FROM `sys`.`processlist` WHERE CONN_ID=
--29T13::51.418669+: Query SELECT * FROM `sys`.`processlist` WHERE CONN_ID=

上面的20036是会话连接号(connection id), 使用SHOW PROCESSLIST 或`information_schema`.`PROCESSLIST`查到的ID即该ID。

对于MySQL 5.7版本,可以使用sys.session视图来查看会话最后一次执行的SQL:

SELECT *
FROM sys.session
WHERE CONN_ID = \G

输出结果为:

            thd_id:
conn_id:
user: admin@172.28.37.35
db: demodb
command: Sleep
state: NULL
time:
current_statement: NULL
statement_latency: NULL
progress: NULL
lock_latency: 157.00 us
rows_examined:
rows_sent:
rows_affected:
tmp_tables:
tmp_disk_tables:
full_scan: YES
last_statement: select * from tb001 limit
last_statement_latency: 607.34 us
current_memory: bytes
last_wait: NULL
last_wait_latency: NULL
source: NULL
trx_latency: NULL
trx_state: NULL
trx_autocommit: NULL
pid:
program_name: mysql

使用系统视图sys.processlist 也能看到类似上面的结果:

SELECT *
FROM sys.processlist
WHERE CONN_ID =

系统视图sys.processlist中数据主要来源于:

performance_schema.events_statements_current
performance_schema.events_statements_history

且上面两个表中记录的数据需要使用线程号(THREAD ID),可以使用performance_schema.threads来与连接号(CONNECTION ID/PROCESSLIST ID)进行关联。

因此可以将查询未提交事务的SQL优化为:

## 查看未提交的事务(3秒内未操作的事务)
SELECT
p.ID AS conn_id,
P.USER AS login_user,
P.HOST AS login_host,
p.DB AS database_name,
P.TIME AS trx_sleep_seconds,
TIME_TO_SEC(TIMEDIFF(NOW(),T.trx_started)) AS trx_open_seconds,
T.trx_started,
T.trx_isolation_level,
T.trx_tables_locked,
T.trx_rows_locked,
t.trx_state,
p.COMMAND AS process_state,
(
SELECT GROUP_CONCAT(REPLACE(REPLACE(REPLACE(T1.`SQL_TEXT`,'\n',' '),'\r',' '),'\t',' ') SEPARATOR ';
')
FROM performance_schema.events_statements_history AS T1
INNER JOIN performance_schema.threads AS T2
ON T1.`THREAD_ID`=T2.`THREAD_ID`
WHERE T2.`PROCESSLIST_ID`=P.id
) AS trx_sql_text
FROM `information_schema`.`INNODB_TRX` t
INNER JOIN `information_schema`.`PROCESSLIST` p
ON t.trx_mysql_thread_id=p.id
WHERE t.trx_state='RUNNING'
AND p.COMMAND='Sleep'
AND P.TIME>
ORDER BY T.trx_started ASC \G

输出结果中trx_sql_text即该事务执行过的SQL语句。

查看每个未提交事务执行过多的所有SQL

SELECT @dt_ts:=UNIX_TIMESTAMP(NOW());
SELECT
@dt_timer:=MAX(SH.TIMER_START)
FROM performance_schema.threads AS T1
INNER JOIN performance_schema.events_statements_history AS SH
ON T1.`THREAD_ID`=SH.`THREAD_ID`
WHERE T1.PROCESSLIST_ID=CONNECTION_ID(); SELECT
SH.CURRENT_SCHEMA AS database_name,
REPLACE(REPLACE(REPLACE(SH.`SQL_TEXT`,'\n',' '),'\r',' '),'\t',' ') AS executed_sql,
FROM_UNIXTIME(@dt_ts-CAST((@dt_timer-SH.TIMER_START)/1000000000000 AS SIGNED)) AS start_time,
FROM_UNIXTIME(@dt_ts-CAST((@dt_timer+SH.TIMER_END)/1000000000000 AS SIGNED)) AS end_time,
(SH.TIMER_END-SH.TIMER_START)/1000000000000 AS used_seconds,
SH.TIMER_WAIT/1000000000000 AS wait_seconds,
SH.LOCK_TIME/1000000000000 AS lock_seconds,
SH.ROWS_AFFECTED AS affected_rows,
SH.ROWS_SENT AS send_rows
FROM performance_schema.threads AS T1
INNER JOIN performance_schema.events_statements_history AS SH
ON T1.`THREAD_ID`=SH.`THREAD_ID`
WHERE T1.PROCESSLIST_ID IN (
SELECT
p.ID AS conn_id
FROM `information_schema`.`INNODB_TRX` t
INNER JOIN `information_schema`.`PROCESSLIST` p
ON t.trx_mysql_thread_id=p.id
WHERE t.trx_state='RUNNING'
AND p.COMMAND='Sleep'
AND P.TIME>3
)
AND SH.TIMER_START<@dt_timer
ORDER BY SH.TIMER_START ASC;

PS:如果使用MySQL 5.7早期版本热备升级到MySQL 5.7后期版本,可能会导致sys库上很多视图和函数无法正常使用,需要使用mysql_upgrade进行升级。

/export/servers/mysql/bin/mysql_upgrade \
--host='127.0.0.1' \
--port=3305 \
--user='admin' \
--password="admin_psw"

MySQL Transaction--查看未提交事务执行的SQL的更多相关文章

  1. mysql怎么终止当前正在执行的sql语句

    mysql怎么终止当前正在执行的sql语句 show processlist; kill 要杀的ID kill 7

  2. [LINQ2Dapper]最完整Dapper To Linq框架(五)---查看Linq实际执行的SQL

    此例子是使用LINQ2Dapper封装,效率优于EntityFramwork,并且支持.NetFramework和.NetCore框架,只依赖于Dapper支持.net framework4.6.1及 ...

  3. MySQL Transaction--使用SHOW INNODB STATUS 查看未提交事务

    当MySQL服务器出现性能问题时,应该优先排查未提交事务,除可以查询相关系统表外,还可以观察SHOW INNODB STATUS的输出结果来确认未提交事务. 首先查看InnoDB事务的History ...

  4. mysql监控每一条执行的sql语句

    查看日志配置是否打开 SHOW VARIABLES LIKE "general_log%"; SET GLOBAL general_log = 'ON';   打开日志 SET G ...

  5. 查看PostgreSQL正在执行的SQL

    SELECT procpid, START, now() - START AS lap, current_query FROM ( SELECT backendid, pg_stat_get_back ...

  6. 如何查看PostgreSQL正在执行的SQL

    SELECT     procpid,     start,     now() - start AS lap,     current_query FROM     (SELECT          ...

  7. shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作

    mysql  -hhostname -Pport -uusername -ppassword  -e  相关mysql的sql语句,不用在mysql的提示符下运行mysql,即可以在shell中操作m ...

  8. mysql 字符串分割 和 动态执行拼接sql

    本人以前主要用的是MSSQL,最近项目在使用MYSQL,自己是一个 典型的小白.今天就记录一下 一个mysql存储过程,里面需要分割字符串和 动态执行sql语句. 关于字符串 分割我开始使用 LOCA ...

  9. oracle查看未提交事务

    SELECT s.sid, s.serial#, s.event, a.sql_text, a.sql_fulltext, s.username, s.status, s.machine, s.ter ...

随机推荐

  1. SoapUI并发模式

    soapUI支持test suite, test case级别的并发,合理使用这个功能,可以让自动化脚本短时间内跑完,为release省下时间. 1. 如何开启并发模式 图示,click projec ...

  2. node.js学习5--------------------- 返回html内容给浏览器

    /** * http服务器的搭建,相当于php中的Apache或者java中的tomcat服务器 */ // 导包 const http=require("http"); cons ...

  3. Visual C++没事别启用/Za编译选项

    Visual C++对于C++标准的支持不是很完善好像是钦定了的.MS还特意在这里说了些非标准行为[1]以及扩展行为[2].这就不可避免地会让处女座程序猿感到难受(我不是处女座).所以,经过一番goo ...

  4. js 判断变量是否为空或未定义

    判断变量是否定义: if(typeof(hao) == "undefined"){ //未定义 }else{ //定义 } 判断变量是否为空或NULL,是则返回'', 反之返回原对 ...

  5. MSBuild 命令参数

    Build a Visual Studio project or solution using MSBuild Command Line Arguments  常用命令行参数 详解: MSBuild ...

  6. OpenGL之shader着色器的应用,三色渐变的三角形

    学习自: https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/#_7 首先放一张效果图: 本次教程,将着色器单独定 ...

  7. dede织梦系统接入熊掌号推送api,完整详细教程

    第一步:     根据熊掌号要求完成校验页面,官方文档很详细,照着弄就行了 第二步: 开始后台改造 1.进入后台文件夹dede(自己实际的文件夹),然后进入templets目录,打开body_inde ...

  8. python-2018.03.03

    本周用python实现了 1.通过svn模块检出远程代码到本地(ps:修改了windows svn的一个编码模块的小bug),并通过调用MSbuild 编译.发布并打包发布后的代码 (注:以上需要安装 ...

  9. jmeter学习随笔

    1.jmeter配置环境是需要注意jdk版本,不同的jdk版本可支持运行不同版本的jmeter,对应关系如下图 2.HTTP请求和HTTP默认请求的区别 若一个项目中会多次调用相同的接口域名及端口号, ...

  10. UI规范案例-宝龙广场