我有一个大约5,000,000行的MySQL表,它们通过并行Perl进程以小方式不断更新,这些并行Perl进程通过DBI连接。该表有大约10列和几个索引。解决MySQL错误“尝试获取锁定时发现死锁;尝试重新启动事务”
一个相当普遍的操作产生了有时以下错误:
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;
我在网上看到,其他几个人也报告了类似的错误,这可能会是一个真正的死锁情况。
我有两个问题:
究竟我的情况是导致上述错误?
有没有简单的方法来解决它或减少其频率?例如,我该如何“重新启动Db.pm 276行的交易”?
在此先感谢。
什么是我们需要捕捉,然后错误代码?仅靠1205就足够了吗? http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html中有超过900个错误代码。您如何知道我们需要执行的所有代码,以便为您的try/catch建议实施适当的解决方案? – Pacerier 2014-12-19 03:52:12
这是否意味着除了“InnoDB或任何行级事务性RDBMS”之外没有这些问题? – 2015-12-31 19:49:07