DBIを介して接続する並列Perlプロセスによって小さな方法で絶えず更新されている約5,000,000行のMySQLテーブルがあります。テーブルには、約 10 の列といくつかのインデックスがあります。
1 つのかなり一般的な操作で、次のエラーが発生することがあります。
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 フィールドを使用して、実行中の 4 つのほぼ同一のプロセスが同じ行で試行および動作しないようにしていることに注意してください。制限は、作業を小さなチャンクに分割するように設計されています。
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;
他の何人かが同様のエラーを報告しており、これが本当のデッドロック状況である可能性があることをオンラインで見ました。
2 つの質問があります。
上記のエラーの原因は、私の状況について正確には何ですか?
それを回避したり、頻度を減らす簡単な方法はありますか? たとえば、「Db.pm 行 276 でトランザクションを再開する」にはどうすればよいですか?
前もって感謝します。