MySQL表不能修改、删除等操作,卡死、锁死情况的处理办法。Waiting for table metadata lock 1205 - Lock wait timeout exceeded; try restarting transaction

MySQL如果频繁的修改一个表的数据,那么这么表会被锁死。造成假死现象。
比如用Navicat等连接工具操作,Navicat会直接未响应,只能强制关闭软件,但是重启后依然无效。

解决办法:

//列出当前的操作process,一般会看到很多waiting的process,说明已经有卡住的proces了,我们要杀死这些process!!

show full processlist;  

//processid表示process的id,比如kill 3301,就会将id为3301的process杀死。
kill processid;  

Waiting for table metadata lock解决办法

// 一次性找到所有未完成的进行,并通过sql语句将其全部找到,然后统一杀死 万不得已,不建议这么做
SELECT
	concat( "kill ", trx_mysql_thread_id, ";" ) AS kill_id 
FROM
	information_schema.INNODB_TRX 
WHERE
	trx_lock_structs = 0 
	AND trx_weight = 0 
	AND trx_rows_locked = 0 
	AND trx_rows_modified = 0 
	AND trx_state = "RUNNING";


// 拿到查询结果执行

使用 kill 将所有的 id 杀死。然后重启MySQL,一般就会解决了。如果还不行,那应该是不可能的吧。。。
 
重启MySQL:

//停止MySQL
net stop mysql  

//启动MySQL
net start mysql  

1205 - Lock wait timeout exceeded; try restarting transaction

更新一个数据量比较大的表时报这个错误

一.原因
意外处理没有关闭连接,导致连接过多、或是要更新的表的锁在其它线程手里、系统异常导致事务未提交,再次请求相同记录等等。

二.解决方案
我们可以通过到information_schema 中来进行查找被锁的语句。

解释:
information_schema这张数据表保存了MySQL服务器所有数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。再简单点,这台MySQL服务器上,到底有哪些数据库、各个数据库有哪些表,每张表的字段类型是什么,各个数据库要什么权限才能访问,等等信息都保存在information_schema表里面。

我们可以用下面三张表来查原因:

innodb_trx 当前运行的所有事务
innodb_locks 当前出现的锁
innodb_lock_waits 锁等待的对应关系

如果数据库中有锁的话,我们可以使用这条语句来查看:

select * from information_schema.innodb_trx;
select * from information_schema.innodb_locks;
select * from information_schema.innodb_lock_waits;

通过这条语句,查询出图中trx_state为 LOCK WAIT为占用系统资源的语句,我们需要杀掉这个锁,执行 kill 线程id号。上面这条记录的trx_mysal_thread_id为250059, 所以我们执行:kill 250059杀掉这个MySQL语句的线程即可。
但是如果没有LOCK WAIT 只有一个RUNNING那么执行 kill 线程id号就可以了

kill 250059

三.扩展
innodb_trx表字段的说明

trx_id: InnoDB内部生成的事务唯一ID,对于只读事务或未申请锁的事务,不会分配此ID。

trx_state: 事务的状态,常见的值有RUNNING(事务正在执行)、LOCK WAIT(事务在等待锁)等。

trx_started: 事务开始的时间戳,帮助判断事务运行的时长。

trx_requested_lock_id: 如果事务处于锁等待状态,此字段标识它正在等待的锁的ID。

trx_wait_started: 如果事务在等待锁,记录等待开始的时间。

trx_weight: 表示事务的“重量”,反映事务修改和锁定的行数。虽然不一定精确,但在解决死锁时,InnoDB会倾向于选择重量较小的事务进行回滚。

trx_mysql_thread_id: MySQL线程ID,与执行事务的客户端线程相关联。

trx_query: 正在执行的事务中的SQL语句文本,这对于诊断问题特别有用,因为它直接展示了导致事务行为的SQL代码。

trx_tables_in_use: 当前事务中涉及的表数量。

trx_tables_locked: 被事务锁定的表数量。

posted on 2023-01-06 15:32  何苦->  阅读(1833)  评论(0)    收藏  举报

导航