获取“锁超时超时; 尝试重新启动事务“即使我没有使用事务
我正在运行下面的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后,它已经解决了。