当前位置: 首页 > 面试题库 >

解决MySQL错误“尝试获取锁定时发现死锁;尝试重新开始交易”

贝研
2023-03-14
问题内容

我有一个带有约5,000,000行的MySQL表,该表通过通过DBI连接的并行Perl进程以小方式不断更新。该表有大约10列和几个索引。

一种相当常见的操作有时会导致以下错误:

DBD::mysql::st execute failed: Deadlock found when trying to get lock; try restarting transaction at Db.pm line 276.

触发错误的SQL语句如下所示:

UPDATE file_table SET a_lock = 'process-1234' WHERE param1 = 'X' AND param2 = 'Y' AND param3 = 'Z' LIMIT 47

该错误仅在某些时候触发。我估计会减少1%的来电。但是,使用小表从未发生这种情况,随着数据库的增长,它变得越来越普遍。

请注意,我正在使用file_table中的a_lock字段来确保我正在运行的四个接近相同的进程不会尝试在同一行上工作。此限制旨在将他们的工作分解成小块。

我没有在MySQL或DBD :: mysql上做很多调优。MySQL是标准的Solaris部署,并且数据库连接设置如下:

my $dsn = "DBI:mysql:database=" . $DbConfig::database . ";host=${DbConfig::hostname};port=${DbConfig::port}";
my $dbh = DBI->connect($dsn, $DbConfig::username, $DbConfig::password, { RaiseError => 1, AutoCommit => 1 }) or die $DBI::errstr;

我在网上看到有其他人报告了类似的错误,这可能是真正的僵局。

我有两个问题:

  1. 我的情况到底是什么导致上述错误?

  2. 有没有简单的方法可以解决它或降低它的出现频率?例如,如何准确地执行“在Db.pm第276行重新开始事务”?

提前致谢。


问题答案:

如果您使用的是InnoDB或任何行级事务性RDBMS,则即使在完全正常的情况下, 任何
写入事务也可能导致死锁。较大的表,较大的写入和较长的事务块通常会增加发生死锁的可能性。在您的情况下,可能是这些因素的组合。

真正处理死锁的唯一方法是编写代码以期望它们。如果您的数据库代码编写得很好,通常这并不是很难。通常,您可以放一个try/catch查询执行逻辑,并在发生错误时查找死锁。如果您发现其中一个,那么正常的事情就是尝试再次执行失败的查询。

我强烈建议您阅读MySQL手册中的此页面。它提供了一系列可帮助处理死锁并减少死锁频率的事情。



 类似资料:
  • 问题内容: 我的应用程序(java spring-core)有多个线程同时运行并访问数据库,在某些高峰时间出现异常 我的代码看起来 问题答案: MySQL的InnoDB引擎具有行级锁定功能,即使您的代码正在插入或更新单个行(尤其是要更新的表上有多个索引),也可能导致死锁。最好的选择是围绕它设计代码,以便在由于死锁而失败的情况下重试事务。一些有关MySQL死锁诊断的有用信息以及可能的解决方法在此处提

  • 表以作为主键,列(CHAR(1))可以是“x”或“y”,以及(INT)。这些列上没有索引。存储引擎是InnoDB。 state_positions必须总是连续的,并且对于某个状态可能永远不会有重复的位置,即如果我有5个状态为“x”的用户,他们的state_positions必须是1、2、3、4、5 这是我正在运行的导致死锁的查询: 为了测试,我同时插入了大量的用户,但每次都出现死锁错误。 我读了这

  • 问题内容: 我有一个记录在线用户的innoDB表。用户每次刷新页面时都会对其进行更新,以跟踪他们所访问的页面以及它们对该站点的最后访问日期。然后,我会有一个cron,每15分钟运行一次,以删除旧记录。 我在尝试获取锁时发现了“死锁;昨晚尝试重新启动事务”大约5分钟,这似乎是在向该表中运行INSERT时出现的情况。有人可以建议如何避免此错误吗? ===编辑=== 以下是正在运行的查询: 首次访问网站

  • 问题内容: 我在项目中使用了hibernate模式,并且由于非常简单的数据库操作而获得了随机的表观死锁。 有一个堆栈跟踪:https : //gist.github.com/knyttl/8999006 –让我感到困惑的是,第一个异常是RollbackException,然后是LockAquisition异常。 问题经常发生在类似的条款上: 我很困惑,因为我不知道这是Hibernate,MySQL

  • 我得到以下错误当有多个更新运行特定的表数据库-mysql-innodb引擎语言php-pdo 错误-序列化失败:尝试获取锁时发现死锁 我检查了下面的链接SQLState[40001]:序列化失败:尝试获取锁时发现1213死锁;尝试按Magento位置重新启动事务

  • 问题内容: 我一直在尝试解决我在Golang并发中遇到的这个简单问题。我一直在搜索所有可能的解决方案,但没有发现与我的问题有关的特定信息(否则我可能会被遗漏)。这是我的代码: 它显示错误: 致命错误:所有goroutine都在睡觉-死锁! goroutine 1 [chan接收]:main.main()D:/Code/go/src/testconcurrency/main.go:23 + 0xca