Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.1Mb
HTML Download (Zip) - 7.2Mb 挿入バッファー

多くの場合、データベースアプリケーションでは、新しい行が主キーの昇順で挿入されます。この場合、クラスタ化されたインデックスの順序が主キーと同じであるというレイアウトのために、InnoDB テーブルへの挿入時に、ディスクからのランダムな読み取りが必要ありません。

その一方で、通常、セカンダリインデックスは一意ではなく、セカンダリインデックスへの挿入は比較的ランダムな順序で発生します。同様に、削除および更新によって、セカンダリインデックス内の隣接しないデータページが影響を受ける可能性があります。このため、InnoDB で特別なメカニズムが使用されることなく、多数のランダムなディスク I/O が発生します。

インデックスレコードを挿入したり、削除対象のマークを付けたり、一意でないセカンダリインデックスから削除したりすると、InnoDB によって、セカンダリインデックスがバッファープール内に存在するかどうかがチェックされます。これに該当する場合は、InnoDB によって変更が直接インデックスページに適用されます。バッファープール内にインデックスページが見つからない場合は、InnoDB によって、挿入バッファーと呼ばれる特別な構造に変更が記録されます。挿入バッファーは、バッファープール内に完全に収容されるようにサイズが小さく保たれるため、変更を非常にすばやく適用できます。このプロセスは、変更バッファーと呼ばれます。(以前は、挿入にのみ適用されていたため、挿入バッファーと呼ばれていました。データ構造は、引き続き挿入バッファーと呼ばれています。)

挿入バッファーをフラッシュするためのディスク I/O

挿入バッファーは、データベース内のセカンダリインデックスツリーに定期的にマージされます。多くの場合は、複数の変更をインデックスツリーの同じページにマージできるため、ディスク I/O 操作を節約できます。挿入バッファーによって、テーブルへの挿入速度が最大 15 倍に上昇すると測定されています。

挿入バッファーのマージは、トランザクションがコミットされたあとに、発生し続ける可能性があります。実際、これはサーバーがシャットダウンし、再起動したあとまで発生し続ける可能性があります (セクション14.19.2「InnoDB のリカバリの強制的な実行」を参照してください)。

多くのセカンダリインデックスが更新される必要があり、多くの行が挿入されたときは、挿入バッファーのマージに何時間もかかる可能性があります。この期間は、ディスク I/O が増加します。これにより、ディスクに負荷がかかるクエリーは大幅に低速になります。もう 1 つの重要なバックグラウンド I/O 操作は、パージスレッドです (セクション14.2.12「InnoDB マルチバージョン」を参照してください)。

User Comments
  Posted by Marek Kowal on September 30, 2004
If you type show innodb status\G, it will show - under section "INSERT BUFFER AND ADAPTIVE HASH INDEX" line like that:

54737 inserts, 12769 merged recs, 3612 merges

From what I have understood, this basically shows that 54 000 records have been inserted, but only 12 000 have been merged into indexes. The trick I have just found is that even after you stop last query to the database, the database still keeps on doing heavy IO, and what is happening then is that the remaining records are merged. The procedure continues until "inserts"=="merged recs". Only after that the IO really stops.

In my case the merging procedure takes about 3hrs after the last query. Even if you stop the database by shutdown command during merging, when you turn it on again, it will continue to merge the rows anyway. Only then it will make it slower, or so it seems from my experience. Dunno why. Also, if you shut down the database and then start it and it will continue to merge records, the "inserts" counter will be zeroed, so you will have not the slightest idea, how long to wait untill it finishes ;-)

Tip: DO NOT shut down the database until you see that everything is merged. Also, keep an eye on the difference between those values. If it grows constantly during normal operation, you are really missing some resources on your computer (probably IO). Also, merging is usually the reason for big IO even when the traffic drops down and you'd expect the database to perform faster, but it does not ;-) In the worst possible scenario (happened to me), the server was working on maximum IO rate, but was completely unusable, all IO went down to merging. This "deadlock" could only be resolved manually by stopping all queries for 6hrs...

  Posted by Wagner Bianchi on May 27, 2015
Take care when executing the proposed SELECT ... INFORMATION_SCHEMA.INNODB_BUFFER_PAGE mentioned above on a heavy loaded production server. Besides it's going to take several minutes, it's going to impose some hard pressure on MySQL Instance.
Sign Up Login You must be logged in to post a comment.