获取“锁超时超时; 尝试重新启动事务“即使我没有使用事务

我正在运行下面的MySQL UPDATE语句:

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

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

该表有406,733行。

您正在使用交易; autocommit不会禁用事务,只是使它们在语句结束时自动提交。

现在发生的事情是,一些其他线程在某些logging上持有logging锁(您正在更新表中的每条logging!)太久,并且您的线程正在超时。

你可以通过发行一个看到更多的事件细节

 SHOW ENGINE INNODB STATUS\G 

在事件发生后。 理想的做法是在一台安静的testing机器上进行。

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

像这样打破locking可能会导致数据库中的primefaces性不能在导致locking的sql语句上执行。

这是骇人听闻的,正确的解决scheme是修复导致锁的应用程序。 然而,当美元在线时,迅速的一击将使事情再次发生。

1)inputMySQL

 mysql -u your_user -p 

2)我们来看看locking表的列表

 mysql> show open tables where in_use>0; 

3)让我们看看当前进程的列表,其中一个locking你的表(s)

 mysql> show processlist; 

4)杀死这些进程之一

 mysql> kill <put_process_id_here>; 
 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 | +--------------------------+-------+ 

现在再次触发locking。 你有100秒的时间来发出一个SHOW ENGINE INNODB STATUS\G到数据库,看看哪些其他交易locking你的。

看看你的数据库是否被微调。 尤其是事务隔离。 增加innodb_lock_wait_timeoutvariables不是个好主意。

在mysql cli中检查你的数据库事务隔离级别:

 mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation; +-----------------------+-----------------+------------------------+ | @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation | +-----------------------+-----------------+------------------------+ | REPEATABLE-READ | REPEATABLE-READ | REPEATABLE-READ | +-----------------------+-----------------+------------------------+ 1 row in set (0.00 sec) 

你可以改进de隔离级别的改进,像READ COMMITTED一样使用oracle,而不是REPEATABLE READ(InnoDB Defaults)

 mysql> SET tx_isolation = 'READ-COMMITTED'; Query OK, 0 rows affected (0.00 sec) mysql> SET GLOBAL tx_isolation = 'READ-COMMITTED'; Query OK, 0 rows affected (0.00 sec) mysql> 

如果需要,也可以尝试使用SELECT FOR UPDATE。

没有任何build议的解决scheme为我工作,但是这样做。

有些东西阻止了查询的执行。 最有可能的另一个查询更新,插入或从您的查询中的表中删除。 你必须找出那是什么:

 SHOW PROCESSLIST; 

一旦你find阻塞进程,find它的id和运行:

 KILL {id}; 

重新运行您的初始查询。

MarkR说的是100%。 autocommit使每个语句成为一个语句事务。

SHOW ENGINE INNODB STATUS应该给你一些关于死锁原因的线索。 仔细看看你的慢查询日志,看看还有什么是查询表,并尝试删除任何做一个完整的表扫描。 行级locking工作正常,但不是当你试图locking所有的行时!

你能更新这个表中的其他logging吗,还是这个表被大量使用? 我在想的是,当它试图获取一个需要更新这个logging的锁的时候,设置的超时已经超时了。 你可能会增加可能有用的时间。

行数不是很大…如果不是主键,则在account_import_id上创build一个索引。

 CREATE INDEX idx_customer_account_import_id ON customer (account_import_id); 

确保数据库表使用InnoDB存储引擎和READ-COMMITTED事务隔离级别。

您可以通过SELECT @@ GLOBAL.tx_isolation,@@ tx_isolation; 在mysql控制台上。

如果它没有设置为READ-COMMITTED,那么你必须设置它。 确保在设置之前,你有超级特权在MySQL。

你可以从http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html获得帮助。;

通过设置这个我认为你的问题将得到解决。


你可能也想检查一下,你不是试图在两个进程中更新它。 用户(@tala)在这种情况下遇到类似的错误消息,可能仔细检查…

晚会(和往常一样)但是我的问题是我写了一些不好的SQL(作为一个新手),有几个进程locking了logging(<s)< – 不确定适当的措词。 我最后不得不只是: SHOW PROCESSLIST ,然后杀死ID使用KILL <id>

当我使用php语言构造出口时,发生了这种事情; 在交易中。 然后,这个事务“挂起”,你需要杀死mysql进程(上面描述了processlist;)

有这个相同的错误,即使我只用一个条目更新一个表,但重新启动MySQL后,它已经解决了。