У меня есть таблица 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;
Я видел онлайн, что несколько других людей сообщили о подобных ошибках и что это может быть подлинной ситуацией тупика.
У меня есть два вопроса:
-
Что именно о моей ситуации вызывает ошибку выше?
-
Есть ли простой способ обойти его или уменьшить его частоту? Например, как именно я говорю о "перезагрузке транзакции на линии Db.pm 276"?
Спасибо заранее.