InnoDB事务:锁定等待超时

时间:2013-07-13 18:36:21

标签: mysql innodb

我的数据库中有一个表(实际上是几个相关的表),可以通过我们的界面从各个点手动操作,但也可以从两个源连续自动操作。定期更新可能包含大量数据,并可能导致数千次插入/更新。为了提高插入/更新的性能,我在这些自动化源的更新周围使用了“SET autocommit = 0”。这导致了期望的性能改进,甚至可能超过预期。但是现在的问题是,如果自动源重叠或者经常执行手动更新,数据库会锁定并在一段时间后抛出错误:

超过锁定等待超时;尝试重新启动交易

即使在具有autocommit on且没有事务的单个语句中,也可能抛出此异常但我认为如果它与事务冲突也是合理的。我已经阅读了各种建议,遗憾的是没有理想的解决方案。我想我的选择是:

  1. 尝试在表上订购更新/插入,以便以相同的顺序请求所有线程上的锁,并且没有死锁。不幸的是,这是不可能的,需要按照收到的顺序应用更新。

  2. 使用LOCK TABLES序列化事务。这在理论上是可行的但是a)除了两个自动化源之外,表格从系统中的许多点更新,包括触发器,时间表,从各种接口手动。在所有这些地方识别和维护LOCK表并且没有简单的方法知道所有这些都已被识别将是一场噩梦,并且b)LOCK TABLES必须锁定所有涉及的表和更新/插入虽然不经常但有时可能需要由于更新而更新了许多表,并再次需要识别和维护可能更新的所有表,以便它们包含在LOCK表中。

  3. 在每次更新之前使用信号量表,以便像上面的LOCK TABLES一样实现更新的序列化,但实际上不必使用LOCK TABLES。这是一个改进,但仍有问题a)上面的LOCK TABLES。

  4. 还有其他建议吗? autocommit = 0(事务)的改进优势是否可以通过其他不涉及锁的方式实现? innodb是否可以配置为在更新/插入时实际上不会锁定或锁定更少?

    最后的选择可能是移动到MyISAM表。这实际上是通过大量插入/更新操作实现性能改进吗?

    谢谢

1 个答案:

答案 0 :(得分:0)

您仍然可以在不使用长事务的情况下实现autocommit = 0的好处。

a)您可以在每个X语句中提交事务,假设您不需要回滚整个事务

b)您可以在导入之前/之后使用ALTER TABLE x DISABLE keys / ALTER TABLE x ENABLE keys,而不是使用autocommit = 0。这是操作性能改进的原因 - 非唯一索引在事务完成之前不会更新,然后批量更新。