mysql - InnoDB 事务 : Lock wait timeout

标签 mysql innodb

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

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

即使在启用了自动提交且没有事务的单个语句中也可能抛出此错误,但我想如果它与事务冲突,这也是合理的。我已经阅读了各种建议,不幸的是没有理想的解决方案。我想我的选择是:

  1. 尝试对表进行更新/插入排序,以便所有线程上的锁都以相同的顺序请求,并且不会出现死锁。不幸的是,这是不可能的,需要按照收到的顺序应用更新。

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

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

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

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

谢谢

最佳答案

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

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

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

关于mysql - InnoDB 事务 : Lock wait timeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17633101/

相关文章:

mysql - 如何让innodb成为默认引擎

mysql - 处理数据库完整性

php - 如何将 latin1 表转换为具有序列化值的 utf8?

php - SQL LIMIT 返回 'zero' - 0 - 行(在 PHP 中)

php - 计算有限制的所有行

php - 无法向数据库中插入数据

mysql - 用户对话的数据库模式

mysqld 服务无法启动

mysql - 如何更改 mysql innodb 分区以使用另一个 key ?

Mysql 将巨大的数据库从 innodb 迁移到 ndbcluster 错误 : the table is full