InnoDB
でのエラー処理は、SQL 標準で指定されているものと必ずしも同じではありません。この標準によると、SQL ステートメント中にエラーが発生した場合は必ず、そのステートメントのロールバックを実行するべきです。InnoDB
は場合によって、ステートメントの一部のみ、またはトランザクション全体をロールバックします。次の各項目は、InnoDB
がエラー処理をどのように実行するかについて説明しています。
テーブルスペース内のファイル領域が不足した場合は、MySQL の
Table is full
エラーが発生し、InnoDB
は SQL ステートメントをロールバックします。-
トランザクションデッドロックが発生すると、
InnoDB
はトランザクション全体をロールバックします。これが発生した場合は、トランザクション全体を再試行します。ロック待機のタイムアウトが発生すると、
InnoDB
は、ロックの待機中にタイムアウトが発生した 1 つのステートメントのみをロールバックします。(トランザクション全体がロールバックされるようにするには、--innodb_rollback_on_timeout
オプションを使用してサーバーを起動します。)現在の動作を使用している場合はそのステートメントを、--innodb_rollback_on_timeout
を使用している場合はトランザクション全体を再試行します。デッドロックとロック待機のタイムアウトはどちらもビジー状態のサーバーでは通常のことであり、アプリケーションはそれらが発生する可能性を認識し、発生した場合は再試行によって処理する必要があります。トランザクション中の最初のデータ変更からコミットまでの間に行う作業をできるだけ少なくして、ロックが可能性のある最短の時間、可能性のある最少の行数に対して保持されるようにすることにより、それらが発生する可能性を少なくすることができます。場合によっては、異なるトランザクション間での作業の分割が実際的で、かつ役立つことがあります。
デッドロックまたはロック待機のタイムアウトのためにトランザクションロールバックが発生すると、そのトランザクション内のステートメントの効果が取り消されます。ただし、トランザクション開始ステートメントが
START TRANSACTION
またはBEGIN
ステートメントであった場合、そのステートメントはロールバックによって取り消されません。それ以上の SQL ステートメントは、COMMIT
、ROLLBACK
、または暗黙的なコミットを発生させる何らかの SQL ステートメントが現れるまで、そのトランザクションの一部になります。 ステートメントで
IGNORE
オプションを指定していない場合、重複キーエラーは SQL ステートメントをロールバックします。row too long error
は、SQL ステートメントをロールバックします。その他のエラーはほとんど (
InnoDB
ストレージエンジンレベルの上にある) コードの MySQL レイヤーによって検出され、対応する SQL ステートメントをロールバックします。1 つの SQL ステートメントのロールバックでは、ロックは解放されません。
暗黙的なロールバック中や、明示的な ROLLBACK
SQL ステートメントの実行中に、SHOW PROCESSLIST
は、関連する接続の State
カラムに Rolling back
を表示します。