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

相关文章

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

Mysql DATETIME 毫秒坑的解决

《MysqlDATETIME毫秒坑的解决》本文主要介绍了MysqlDATETIME毫秒坑的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 今天写代码突发一个诡异的 bug,代码逻辑大概如下。1. 新增退款单记录boolean save = s

mysql-8.0.30压缩包版安装和配置MySQL环境过程

《mysql-8.0.30压缩包版安装和配置MySQL环境过程》该文章介绍了如何在Windows系统中下载、安装和配置MySQL数据库,包括下载地址、解压文件、创建和配置my.ini文件、设置环境变量... 目录压缩包安装配置下载配置环境变量下载和初始化总结压缩包安装配置下载下载地址:https://d

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

MySQL中的锁和MVCC机制解读

《MySQL中的锁和MVCC机制解读》MySQL事务、锁和MVCC机制是确保数据库操作原子性、一致性和隔离性的关键,事务必须遵循ACID原则,锁的类型包括表级锁、行级锁和意向锁,MVCC通过非锁定读和... 目录mysql的锁和MVCC机制事务的概念与ACID特性锁的类型及其工作机制锁的粒度与性能影响多版本

解决Cron定时任务中Pytest脚本无法发送邮件的问题

《解决Cron定时任务中Pytest脚本无法发送邮件的问题》文章探讨解决在Cron定时任务中运行Pytest脚本时邮件发送失败的问题,先优化环境变量,再检查Pytest邮件配置,接着配置文件确保SMT... 目录引言1. 环境变量优化:确保Cron任务可以正确执行解决方案:1.1. 创建一个脚本1.2. 修