修复“锁超时超时; 尝试重新启动事务“为”卡住“的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进程。 如果没有解决它,只需重新启动计算机。 您不需要删除表并重新加载数据。
我通过删除表并从备份恢复它来解决问题。