我有一個大約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