我正在运行以下MySQL UPDATE语句:

mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

我没有使用事务,为什么会得到这个错误?我甚至尝试重新启动我的MySQL服务器,它没有帮助。

该表有406,733行。


当前回答

在做一些测试时,我也遇到过类似的问题。

原因-在我的情况下,事务没有从我的spring引导应用程序提交,因为我在执行期间杀死了@transactional函数(当函数更新一些行时)。由于该事务从未提交到数据库(MySQL)。

结果-不能从任何地方更新这些行。但是能够更新表的其他行。

mysql> update some_table set some_value = "Hello World" where id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

解决方案-杀死所有MySQL进程使用

Sudo killall -9 mysqld

Sudo killall -9 mysqld_safe(当发生错误时重新启动服务器,并将运行时信息记录到错误日志中。在我的情况下不需要)

其他回答

在我们的案例中,这个问题与锁本身没有太大关系。

问题是我们的一个应用程序端点需要并行打开2个连接来处理单个请求。

例子:

打开第一个连接 开始事务1 锁定表1中的一行 打开第二个连接 启动事务2 锁定表2中的一行 提交事务2 释放第二个连接 提交事务1 释放第一个连接

我们的应用程序的连接池限制为10个连接。

不幸的是,在负载下,一旦所有连接都被使用,应用程序就停止工作,我们开始遇到这个问题。 我们有几个请求需要打开第二个连接才能完成,但由于连接池的限制而无法完成。因此,这些请求长时间保持对table1行的锁定,导致接下来需要锁定同一行的请求抛出此错误。

解决方案:

在短期内,我们通过增加连接池限制修补了这个问题。 从长远来看,我们删除了所有嵌套连接,以完全解决问题。

小贴士:

您可以通过尝试将连接池限制降低到1并测试应用程序来轻松检查是否有嵌套连接。

我们昨天遇到了这个问题,在仔细研究了这里的每一个建议的解决方案,以及其他答案/论坛的其他几个解决方案后,我们最终在意识到实际问题时解决了它。

由于一些糟糕的计划,我们的数据库存储在一个挂载的卷上,该卷也接收我们的常规自动备份。该容量已达到最大容量。

一旦我们清理了一些空间并重新启动,这个错误就被解决了。

注意,我们也手动终止了几个进程:kill <process_id>;所以这仍然是必要的。

总的来说,我们的结论是,令人难以置信的是,我们的日志或警告都没有直接提到磁盘空间不足,但这似乎确实是根本原因。

mysql> set innodb_lock_wait_timeout=100;

Query OK, 0 rows affected (0.02 sec)

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100   |
+--------------------------+-------+

现在再打开锁。你有100秒的时间向数据库发出一个SHOW ENGINE INNODB STATUS\G,并查看其他哪个事务正在锁定你的事务。

如何强制解锁MySQL中锁定的表:

像这样打破锁可能会导致数据库中的原子性不被强制用于导致锁的sql语句。

这很棘手,正确的解决方案是修复导致锁的应用程序。然而,当美元处于危险之中时,迅速的一脚将使事情再次启动。

1)进入MySQL

mysql -u your_user -p

2)让我们看看锁定的桌子列表

mysql> show open tables where in_use>0;

3)让我们看看当前进程的列表,其中一个正在锁定你的表

mysql> show processlist;

4)终止其中一个进程

mysql> kill <put_process_id_here>;

在做一些测试时,我也遇到过类似的问题。

原因-在我的情况下,事务没有从我的spring引导应用程序提交,因为我在执行期间杀死了@transactional函数(当函数更新一些行时)。由于该事务从未提交到数据库(MySQL)。

结果-不能从任何地方更新这些行。但是能够更新表的其他行。

mysql> update some_table set some_value = "Hello World" where id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

解决方案-杀死所有MySQL进程使用

Sudo killall -9 mysqld

Sudo killall -9 mysqld_safe(当发生错误时重新启动服务器,并将运行时信息记录到错误日志中。在我的情况下不需要)