У меня есть таблица MySQL с около 5 000 000 строк, которые постоянно обновляются небольшими способами параллельными процессами Perl, соединяющимися через DBI. Таблица содержит около 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% звонков или меньше. Тем не менее, это никогда не происходило с маленькой таблицей и стало более распространенным по мере роста базы данных.
Обратите внимание, что я использую поле a_lock в file_table, чтобы убедиться, что четыре почти идентичных процесса, которые я запускаю, не пытаются работать в одной строке. Предел предназначен для разбивки их работы на небольшие куски.
Я не особо настраивался на 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;
Я видел в Интернете, что несколько других людей сообщали об аналогичных ошибках и что это может быть реальной тупиковой ситуацией.
У меня есть два вопроса:
Что именно в моей ситуации вызывает вышеуказанную ошибку?
Есть ли простой способ обойти это или уменьшить его частоту? Например, как именно я могу «перезапустить транзакцию в строке 276 Db.pm»?
Заранее спасибо.