mysql 事务与connection,锁,慢sql,如何解决,杀死执行的线程

2024-09-05 22:32

本文主要是介绍mysql 事务与connection,锁,慢sql,如何解决,杀死执行的线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前提说明

navicat中每打开一个窗口就是打开一个connection,关掉窗口就是关掉connection

事务与connection 

测试事务不提交的情况

(步骤1)先打开一个窗口,开启一个事务T1插入一条数据,这里不进行提交。

由于在一个事务中,所以select 能立刻查出insert的但还没提交的数据。

查询是否开启 事务超时,回滚策略。

SHOW GLOBAL VARIABLES LIKE 'innodb_rollback_on_timeout';

若为off则表示不开启,事务会一直存在,此时只有当连接关闭时,才会回滚。

若为on,则表示开启,当事务超时时,会自动回滚。

查询当前connection的事务id

SELECT TRX_ID
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();

 

(步骤2)再打开一个窗口,开启事务T2,并插入同样的id,会发现一直卡在那,等待id=3的锁释放。

由于事务T1一直没有提交,T2就一直等待锁释放,直到等待锁超时。

查询锁超时的sql:

SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

 如何杀死mysql中的某些线程,如慢sql,锁,事务等

可查询 锁,事务等对应的执行线程,然后杀死

连接mysql,输入命令:

kill 线程id

事务相关-connection 和事务的关系,以及总结

在一个connection中

按步骤执行,第一、二、三步。可发现

(1)START TRANSACTION 会把当前connection中,前面的所有事务(其实,前面最多有一个事务,可参看2解释)都提交(就相当于commit作用)。

(2)一个connection 中一个时间段内,只能有一个活跃事务。

(3)connection 断开,事务就会回滚。

(4)若开启了事务执行超时时间,则事务超时,就会回滚。

#########第一步
START TRANSACTION;
insert into test3(id,name) values(4,'4');
#查询事务id,此时在其他事务中,查不到4
SELECT TRX_ID
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();###########第二步
START TRANSACTION;
#此时在其他事务中可查到id为4的数据
select * from test3;#可以查询到4,说明START TRANSACTION时会把以前没有commit的事务都commit。就相当与执行commit命令
insert into test3(id,name) values(5,'5');
#事务id和第一步不同
SELECT TRX_ID
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();##########第三步
insert into test3(id,name) values(6,'6');
#事务id和第二步一样,说明若不提交或回滚 则后面的sql会追加到前面的事务中。 
#也就是一个connection中 在一个时间段,只能有一个事务活跃。
SELECT TRX_ID
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();
#此时在其他事务中查不到id为5和6的数据
commit;
#此时在其他事务中可查到id为5和6的数据

事务相关操作

本人没有找到关于指定事务id的相关操作命令。。

#查询server中所有innodb中活跃的事务,可根据开始时间判断事务执行了多长时间,长事务
select * from information_schema.innodb_trx;
#根据线程id杀掉
kill 14331733;
#查询事务是否开启超时回滚,若为off,则只能等到connection断开才能回滚
SHOW GLOBAL VARIABLES LIKE 'innodb_rollback_on_timeout';

 慢sql相关

参考mysql查看实时语句和慢sql | Chris Chan's BLOG

mysql 开启慢查询 清空slow_log日志或者slow_log表_zhonglijun_05的博客-CSDN博客_slow_log

#开启慢查询日志
set GLOBAL slow_query_log =1;
show VARIABLES like 'slow_query_log';#设置慢查询日志存储在文件中
set global log_output='FILE';
set GLOBAL slow_query_log_file='D:/temp/mysql/DB-Server-slow.log';#设置慢查询日志存储在表中,即mysql.slow_log
set global log_output='TABLE';
#查询log_output存储类型
show variables like '%log_output%';#设置sql执行多长时间,才记录到日志
set global long_query_time=4;#查询存储早表中的慢查询日志
select * from mysql.slow_log;

如果你想自己试试慢sql是否被记录,那么可以使用select sleep(5);这样的语句,执行效果如下:

mysql> select sleep(5) ;
+----------+
| sleep(5) |
+----------+
|        0 |
+----------+
1 row in set (5.00 sec)mysql> select * from mysql.slow_log;
+---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
| start_time          | user_host                 | query_time | lock_time | rows_sent | rows_examined | db | last_insert_id | insert_id | server_id | sql_text        | thread_id |
+---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
| 2018-01-30 21:45:23 | root[root] @ localhost [] | 00:00:05   | 00:00:00  |         1 |             0 |    |              0 |         0 |         1 | select sleep(5) |         2 |
+---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
1 rows in set (0.00 sec)

查询记录中有thread_id字段。

但是本人测试,只有在执行完后,才会插入慢日志,才能查询到。 

锁相关- 查询当前锁记录的线程 以及等待锁的线程

当前出现的锁

mysql> SELECT * FROM information_schema.INNODB_LOCKs;


锁等待的对应关系

mysql> SELECT * FROM information_schema.INNODB_LOCK_waits;


解释:看事务表INNODB_TRX,里面是否有正在锁定的事务线程,看看ID是否在show processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了,我们需要手动kill掉。

注意:innodb_locks表在8.0.13版本中由performance_schema.data_locks表所代替,innodb_lock_waits表则由performance_schema.data_lock_waits表代替。


原文链接:https://blog.csdn.net/dujianxiong/article/details/90770301

查询当前正在运行的线程

show  processlist;
或者
select * from  information_schema.processlist

可以看到sql 已经执行了多长时间,其中id就是线程id,可在mysql中,用kill 线程id进行杀死

各列的含义和用途:

ID列

一个标识,你要kill一个语句的时候很有用,用命令杀掉此查询 /*/mysqladmin kill 进程号。

user列

显示单前用户,如果不是root,这个命令就只显示你权限范围内的sql语句。

host列

显示这个语句是从哪个ip的哪个端口上发出的。用于追踪出问题语句的用户。

db列

显示这个进程目前连接的是哪个数据库。

command列

显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。

time列

此这个状态持续的时间,单位是秒。

state列

显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个 sql语句,以查询为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成

info列

显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。

这个命令中最关键的就是state列,mysql列出的状态主要有以下几种:

Checking table
 正在检查数据表(这是自动的)。
Closing tables
 正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。
Connect Out
 复制从服务器正在连接主服务器。

Copying to tmp table on disk
 由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。
Creating tmp table
 正在创建临时表以存放部分查询结果。
deleting from main table
 服务器正在执行多表删除中的第一部分,刚删除第一个表。
deleting from reference tables
 服务器正在执行多表删除中的第二部分,正在删除其他表的记录。

Flushing tables
 正在执行FLUSH TABLES,等待其他线程关闭数据表。
Killed
 发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。
Locked
 被其他查询锁住了。
Sending data
 正在处理SELECT查询的记录,同时正在把结果发送给客户端。

Sorting for group
 正在为GROUP BY做排序。
 Sorting for order
 正在为ORDER BY做排序。
Opening tables
 这个过程应该会很快,除非受到其他因素的干扰。例如,在执ALTER TABLE或LOCK TABLE语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。
Removing duplicates
 正在执行一个SELECT DISTINCT方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。

Reopen table
 获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。
Repair by sorting
 修复指令正在排序以创建索引。
Repair with keycache
 修复指令正在利用索引缓存一个一个地创建新索引。它会比Repair by sorting慢些。
Searching rows for update
 正在讲符合条件的记录找出来以备更新。它必须在UPDATE要修改相关的记录之前就完成了。
Sleeping
 正在等待客户端发送新请求.

System lock
 正在等待取得一个外部的系统锁。如果当前没有运行多个mysqld服务器同时请求同一个表,那么可以通过增加--skip-external-locking参数来禁止外部系统锁。
Upgrading lock
 INSERT DELAYED正在尝试取得一个锁表以插入新记录。
Updating
 正在搜索匹配的记录,并且修改它们。


User Lock
 正在等待GET_LOCK()。
Waiting for tables
 该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。以下几种情况下会产生这个通知:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE,或OPTIMIZE TABLE。
waiting for handler insert
 INSERT DELAYED已经处理完了所有待处理的插入操作,正在等待新的请求。
 大部分状态对应很快的操作,只要有一个线程保持同一个状态好几秒钟,那么可能是有问题发生了,需要检查一下。
 还有其他的状态没在上面中列出来,不过它们大部分只是在查看服务器是否有存在错误是才用得着。

其他网上参考

Mysql 锁、事务强制手动kill/释放

1、查看数据库当前的进程,看一下有无正在执行的慢SQL记录线程。

mysql> show  processlist;


2、查看当前的事务

注意:innodb_locks表在8.0.13版本中由performance_schema.data_locks表所代替,innodb_lock_waits表则由performance_schema.data_lock_waits表代替。

当前运行的所有事务

mysql> SELECT * FROM information_schema.INNODB_TRX;


当前出现的锁

mysql> SELECT * FROM information_schema.INNODB_LOCKs;


锁等待的对应关系

mysql> SELECT * FROM information_schema.INNODB_LOCK_waits;


解释:看事务表INNODB_TRX,里面是否有正在锁定的事务线程,看看ID是否在show processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了,我们需要手动kill掉。

搜索的结果是在事务表发现了很多任务,这时候最好都kill掉。

3、批量删除事务表中的事务

我这里用的方法是:通过information_schema.processlist表中的连接信息生成需要处理掉的MySQL连接的语句临时文件,然后执行临时文件中生成的指令。

mysql> select concat('KILL ',id,';') from information_schema.processlist p inner
 join information_schema.INNODB_TRX x on p.id=x.trx_mysql_thread_id where db='test';
+------------------------+
| concat('KILL ',id,';') |
+------------------------+
| KILL 588379;           |
| KILL 588313;           |
| KILL 588275;           |
+------------------------+
3 rows in set
 

kill掉以后再执行SELECT * FROM information_schema.INNODB_TRX; 就是空了。

这时候系统就正常了

原文链接:https://blog.csdn.net/dujianxiong/article/details/90770301

这篇关于mysql 事务与connection,锁,慢sql,如何解决,杀死执行的线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140250

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

mysql8.0.43使用InnoDB Cluster配置主从复制

《mysql8.0.43使用InnoDBCluster配置主从复制》本文主要介绍了mysql8.0.43使用InnoDBCluster配置主从复制,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录1、配置Hosts解析(所有服务器都要执行)2、安装mysql shell(所有服务器都要执行)3、

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

k8s中实现mysql主备过程详解

《k8s中实现mysql主备过程详解》文章讲解了在K8s中使用StatefulSet部署MySQL主备架构,包含NFS安装、storageClass配置、MySQL部署及同步检查步骤,确保主备数据一致... 目录一、k8s中实现mysql主备1.1 环境信息1.2 部署nfs-provisioner1.2.

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in