0

データベースから特定のテーブルを取得して単一のテーブルに配置するクエリを 1 日に 1 回実行して、必要な形式で情報をすばやくエクスポートできるようにしています。

問題が発生していますが、次のエラーが表示されます。

私が理解していることから、既にロックが設定されているときに、クエリがテーブルをロックしようとしているように思えます。ただし、テーブルのロックやその仕組みについては何も知らないことを告白します。

本当に私は他のテーブルを読み込もうとしているだけで、それらに書き込もうとはしていません.クエリを作成するがロックを要求しない方法はありますか?

私の質問はとてつもなく長いので、投稿しませんでした。必要なパーツがある場合はお知らせください。投稿できます。

4

2 に答える 2

2

INSERT DELAYEDを使用してみることができます。これが何をするかです。

クライアントが INSERT DELAYED を使用すると、すぐにサーバーから OK を取得し、テーブルが他のスレッドによって使用されていないときに行が挿入されるようにキューに入れられます。

混合状態のデータを表示したい場合は、トランザクション分離レベルを変更できます

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- Problematic SELECT query goes here --
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

ジョン・エリクソンによる別のSO回答から1つを学びました

于 2010-11-12T16:43:42.743 に答える
2

トランザクション分離モード REPEATABLE_READ (デフォルト) を使用している場合、select はロックを作成しません。これは正常です。

ただし、insert ... select を使用している場合はもちろん、宛先テーブルでロックが発生します。

したがって、他の誰も宛先テーブルに書き込んでおらず、一度に実行されているプログラムのコピーが最大で 1 つしかない場合、デッドロックが発生することはありません。

デッドロックは、2 つ (またはそれ以上) のプロセスが競合することを実行しようとしたときに発生します。通常、これには同じ行のペアを異なる順序で更新することが含まれますが、テーブル構造によって異なる場合があります。

考慮すべきアイデア:

  • 外部ロック (innodb へ) を使用して、複数のコピーに対してプロセスをシリアル化します
  • この操作のトランザクション分離モードを READ_COMMITTED に変更します - これが何を意味するかを理解し、許容できる場合。
  • 1 回のトランザクションで行う作業を減らす (より頻繁にコミットする)

デッドロックの直後に、SHOW ENGINE INNODB STATUS を使用して、デッドロックに関係するトランザクションが何をしていたかを確認できます。

他のプロセスが何であり、何をしていたかを確認できるはずです。一般的なログをオンにするか、他のデバッグ手法を使用することを検討してください。

非実稼働システムで必ずテストを行ってください。

于 2010-11-12T16:31:37.330 に答える