修复“锁超时超时; 尝试重新启动事务“为”卡住“的Mysql表?

从脚本中,我发送了一个这样的数千次的查询到我的本地数据库:

update some_table set some_column = some_value 

我忘了添加where部分,所以同一个列被设置为表中所有行的相同值,并且这已经完成了数千次,并且列被索引,所以相应的索引可能会更新太多次。

我注意到有什么不对,因为它花了太长时间,所以我杀死了剧本。 我甚至从那以后重新启动了我的电脑,但是有些东西卡在表中,因为简单的查询需要很长时间才能运行,而当我尝试删除相关的索引时,它会失败,并显示以下消息:

 Lock wait timeout exceeded; try restarting transaction 

这是一个innodb表,所以卡住的交易可能是隐含的。 我怎样才能解决这个表,并从中删除卡住的交易?

我有一个类似的问题,并通过检查正在运行的线程来解决它。 要查看正在运行的线程,请在mysql命令行界面中使用以下命令:

 SHOW PROCESSLIST; 

如果您不能访问mysql命令行界面,也可以从phpMyAdmin发送。
这将显示具有相应ID和执行时间的线程列表,因此可以杀死执行时间过长的线程。 在phpMyAdmin中,如果您使用的是命令行界面,只需使用KILL命令后跟随线程ID,就可以使用KILL来停止线程。

 KILL 115; 

这将终止相应线程的连接。

您可以检查当前正在运行的交易

 SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started` 

您的交易应该是第一个交易,因为它是列表中最古老的交易。 现在只需从trx_mysql_thread_id并发送KILL命令:

 KILL 1234; 

如果您不确定哪些事务是您的,请经常重复第一个查询,查看哪些事务持续存在。

这开始发生在我的数据库规模增长,我做了很多交易。

事实是有一些方法来优化您的查询或您的数据库,但尝试这两个查询的解决方法。

运行这个:

 SET GLOBAL innodb_lock_wait_timeout = 5000; 

然后这个:

 SET innodb_lock_wait_timeout = 5000; 

检查InnoDB的锁状态

 SHOW ENGINE InnoDB STATUS; 

检查MySQL打开的表格

 SHOW OPEN TABLES WHERE In_use > 0; 

检查未决的InnoDB事务

 SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`; 

检查锁的依赖 – 什么阻止什么

 SELECT * FROM `information_schema`.`innodb_locks`; 

在调查上面的结果之后,你应该能够看到什么是locking什么的。

这个问题的根本原因可能在你的代码中 – 如果你使用像Hibernate这样的JPA,请检查相关的function,尤其是注释。

例如,如此处所述,滥用以下注释可能会导致数据库中的locking:

 @Transactional(propagation = Propagation.REQUIRES_NEW) 

当您为交易build立连接时,您在执行交易之前获得locking。 如果无法获得locking,那么你可以尝试一段时间。 如果仍然无法获得locking,则会抛出locking等待时间超出的错误。 为什么你不能获得locking是因为你没有closures连接。 所以,当你第二次尝试locking的时候,你之前的连接仍然没有closures,并且没有locking,你将无法获得locking。

解决scheme:closures连接或setAutoCommit(true)[根据您的devise]释放locking。

重新启动MySQL,它工作正常。

要小心,如果这样的查询卡住,有一个地方的问题:

  • 在你的查询中(错位字符,笛卡尔积…)
  • 非常多的logging来编辑
  • 复杂的连接或testing(MD5,子串, LIKE %...%等)
  • 数据结构问题
  • 外键模型(链/环锁)
  • 错误索引的数据

正如@syedrakib所说,它可以工作,但这不是一个长期生产的解决scheme。

注意:重新启动会影响您的数据与不一致的状态。

另外,你可以检查MySQL如何用EXPLAIN关键字处理你的查询,看看是否有可能加快查询(索引,复杂testing等等)。

在mysql中转到进程。

所以可以看到有任务还在工作。

杀死特定的进程或等到进程完成。

当试图删除某个特定的logging组时,我遇到了这个问题(在一台Web服务器上使用带有与MySQL的ODBC连接的MS Access 2007)。 通常我会从MySQL中删除某些logging,然后用更新后的logging进行replace(级联删除多个相关logging,这简化了删除单个logging删除的所有相关logging)。

我试图通过在phpMyAdmin的表(优化,刷新等),可用的操作,但我得到需要的权限,当我试图刷新RELOAD错误。 由于我的数据库位于Web服务器上,因此无法重新启动数据库。 从备份还原不是一个选项。

我试着在网上的cPanel mySQL访问上运行删除查询这组logging。 得到相同的错误信息。

我的解决scheme是:我使用了Sun公司的免费MySQL查询浏览器(以前安装在我的电脑上),并在那里运行删除查询。 它马上工作,问题解决了。 然后我可以使用ODBC访问MySQL连接来使用Access脚本再次执行该function。

我用“更新”语句遇到了同样的问题。 我的解决scheme只是简单地通过phpMyAdmin中可用的表操作。 我对表进行了优化,刷新和碎片整理(不是按照这个顺序)。 不需要删除表并从备份中恢复它。 🙂

我遇到过同样的问题。 我认为这是SQL的一个死锁问题。 你可以强制closures从任务pipe理器的SQL进程。 如果没有解决它,只需重新启动计算机。 您不需要删除表并重新加载数据。

我通过删除表并从备份恢复它来解决问题。