変更バッファは、secondary index ページが buffer pool にない場合に、そのページに対する変更をキャッシュする特別なデータ構造です。 バッファされた変更は、INSERT
、UPDATE
または DELETE
操作 (DML) によって発生する可能性があり、後で他の読取り操作によってページがバッファプールにロードされるときにマージされます。
clustered indexes とは異なり、セカンダリインデックスは通常一意ではなく、セカンダリインデックスへの挿入は比較的ランダムな順序で行われます。 同様に、削除および更新は、インデックスツリーに隣接して配置されていないセカンダリインデックスページに影響する可能性があります。 キャッシュされた変更を後でマージすると、影響を受けるページが他の操作によってバッファープールに読み込まれるときに、セカンダリインデックスページをディスクからバッファープールに読み込むために必要な大量のランダムアクセス I/O が回避されます。
システムがほとんどアイドル状態のとき、または低速シャットダウン中に実行されるパージ操作は、定期的に更新されたインデックスページをディスクに書き込みます。 パージ操作では、各値がすぐにディスクに書き込まれた場合よりも効率的に、一連のインデックス値のディスクブロックを書き込むことができます。
変更バッファのマージでは、影響を受ける行と更新するセカンダリインデックスが多数ある場合、数時間かかることがあります。 この期間中、ディスク I/O が増加し、ディスクバインドされたクエリーの速度が大幅に低下する可能性があります。 変更バッファのマージは、トランザクションがコミットされた後、およびサーバーが停止して再起動された後でも継続して発生する場合があります (詳細は、セクション15.21.2「InnoDB のリカバリの強制的な実行」 を参照してください)。
メモリー内では、変更バッファはバッファプールの一部を占有します。 ディスクでは、変更バッファはシステムテーブルスペースの一部であり、データベースサーバーの停止時にインデックス変更がバッファされます。
変更バッファにキャッシュされるデータのタイプは、innodb_change_buffering
変数によって制御されます。 詳細は、変更バッファリングの構成を参照してください。 最大変更バッファサイズを構成することもできます。 詳細は、変更バッファの最大サイズの構成を参照してください。
インデックスに降順のインデックスカラムが含まれている場合、または主キーに降順のインデックスカラムが含まれている場合、セカンダリインデックスでは変更バッファリングはサポートされません。
変更バッファに関するよくある質問への回答は、セクションA.16「MySQL 8.0 FAQ : InnoDB 変更バッファ」 を参照してください。
INSERT
、UPDATE
および DELETE
操作がテーブルに対して実行される場合、インデックス付けされたカラムの値 (特にセカンダリキーの値) はソートされていない順序であることがよくあり、セカンダリインデックスを最新の状態にするにはかなりの I/O が必要です。 関連する page が buffer pool に存在しない場合、change buffer はセカンダリインデックスエントリへの変更をキャッシュするため、ディスクからすぐにページを読み取ることなく、高コストの I/O 操作を回避できます。 バッファされた変更は、ページがバッファプールにロードされ、更新されたページが後でディスクにフラッシュされるときにマージされます。 InnoDB
のメインスレッドは、それらのバッファリングされた変更を、サーバーがほぼアイドル状態にあるときと低速シャットダウン中にマージします。
ディスクの読取りおよび書込みが少なくなる可能性があるため、変更バッファ機能は、バルク挿入などの大量の DML 操作を使用するアプリケーションなど、I/O-bound,であるワークロードに最も役立ちます。
ただし、変更バッファはバッファプールの一部を占有するため、データページのキャッシュに使用できるメモリーが削減されます。 ワーキングセットがバッファプールにほぼ収まる場合、またはテーブルのセカンダリインデックスが比較的少ない場合は、変更バッファリングを無効にすると便利です。 作業データセットがバッファプール内に完全に収まる場合、変更バッファリングはバッファプールにないページにのみ適用されるため、余分なオーバーヘッドは発生しません。
innodb_change_buffering
構成パラメータを使用して、InnoDB
が変更バッファリングを実行する範囲を制御できます。 挿入、削除操作 (インデックスレコードが最初に削除対象としてマークされている場合) およびパージ操作 (インデックスレコードが物理的に削除されている場合) のバッファリングを有効または無効にできます。 更新操作は、挿入と削除の組合せです。 デフォルトの innodb_change_buffering
値は all
です。
許可される innodb_change_buffering
値は次のとおりです:
-
all
デフォルト値: バッファーの挿入、削除のマーキング操作、およびパージ。
-
none
どの操作もバッファリングしません。
-
inserts
挿入操作をバッファリングします。
-
deletes
削除のマーキング操作をバッファリングします。
-
changes
挿入操作と削除マーキング操作の両方をバッファリングします。
-
purges
バックグラウンドで実行される物理的な削除操作をバッファリングします。
innodb_change_buffering
パラメータは、MySQL オプションファイル (my.cnf
または my.ini
) で設定するか、SET GLOBAL
ステートメントを使用して動的に変更できます。これには、グローバルシステム変数の設定に十分な権限が必要です。 セクション5.1.9.1「システム変数権限」を参照してください。 設定を変更しても、新しい操作のバッファリングに影響します。既存のバッファエントリのマージは影響を受けません。
innodb_change_buffer_max_size
変数を使用すると、変更バッファの最大サイズをバッファプールの合計サイズに対する割合として構成できます。 デフォルトでは、innodb_change_buffer_max_size
は 25 に設定されます。 最大設定は 50 です。
大量の挿入、更新および削除アクティビティがある MySQL サーバーで innodb_change_buffer_max_size
を増やすことを検討してください。この場合、変更バッファのマージは新しい変更バッファエントリに対応しないため、変更バッファは最大サイズ制限に達します。
レポートに使用される静的データを使用して MySQL サーバー上の innodb_change_buffer_max_size
を減らすことを検討してください。または、変更バッファがバッファプールと共有されるメモリー領域を大量に消費し、ページが必要以上に早くバッファプールからエージアウトされるようにすることを検討してください。
代表的なワークロードを使用して様々な設定をテストし、最適な構成を決定します。 innodb_change_buffer_max_size
設定は動的で、サーバーを再起動せずに設定を変更できます。
変更バッファの監視には、次のオプションを使用できます:
-
InnoDB
標準モニターの出力には、変更バッファのステータス情報が含まれます。 モニターデータを表示するには、SHOW ENGINE INNODB STATUS
ステートメントを発行します。mysql> SHOW ENGINE INNODB STATUS\G
バッファステータスの変更情報は、
INSERT BUFFER AND ADAPTIVE HASH INDEX
ヘッダーの下にあり、次のように表示されます:------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 4425293, used cells 32, node heap has 1 buffer(s) 13577.57 hash searches/s, 202.47 non-hash searches/s
詳細は、セクション15.17.3「InnoDB 標準モニターおよびロックモニターの出力」を参照してください。
-
INFORMATION_SCHEMA.INNODB_METRICS
テーブルには、InnoDB
標準モニターの出力にあるデータポイントのほとんどと、その他のデータポイントが表示されます。 変更バッファメトリックおよびそれぞれの説明を表示するには、次のクエリーを発行します:mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%ibuf%'\G
INNODB_METRICS
テーブルの使用方法の詳細は、セクション15.15.6「InnoDB INFORMATION_SCHEMA メトリックテーブル」 を参照してください。 -
INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
テーブルには、バッファインデックスの変更やバッファビットマップの変更など、バッファプール内の各ページに関するメタデータが表示されます。 変更バッファページは、PAGE_TYPE
によって識別されます。IBUF_INDEX
は変更バッファインデックスページのページタイプで、IBUF_BITMAP
は変更バッファビットマップページのページタイプです。警告INNODB_BUFFER_PAGE
テーブルをクエリーすると、大幅なパフォーマンスのオーバーヘッドが生じる可能性があります。 パフォーマンスへの影響を回避するために、調査しようとしている問題をテストインスタンスで再現し、テストインスタンスでクエリーを実行してください。たとえば、
INNODB_BUFFER_PAGE
テーブルをクエリーして、合計バッファプールページ数に対するIBUF_INDEX
およびIBUF_BITMAP
ページの概数を確認できます。mysql> SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE PAGE_TYPE LIKE 'IBUF%') AS change_buffer_pages, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE) AS total_pages, (SELECT ((change_buffer_pages/total_pages)*100)) AS change_buffer_page_percentage; +---------------------+-------------+-------------------------------+ | change_buffer_pages | total_pages | change_buffer_page_percentage | +---------------------+-------------+-------------------------------+ | 25 | 8192 | 0.3052 | +---------------------+-------------+-------------------------------+
INNODB_BUFFER_PAGE
テーブルで提供されるその他のデータの詳細は、セクション26.51.1「INFORMATION_SCHEMA INNODB_BUFFER_PAGE テーブル」 を参照してください。 関連する使用方法については、セクション15.15.5「InnoDB INFORMATION_SCHEMA バッファープールテーブル」 を参照してください。 -
Performance Schema には、高度なパフォーマンス監視のための変更バッファ相互排他ロック待機インストゥルメンテーションが用意されています。 変更バッファーインストゥルメンテーションを表示するには、次のクエリーを発行します:
mysql> SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%wait/synch/mutex/innodb/ibuf%'; +-------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +-------------------------------------------------------+---------+-------+ | wait/synch/mutex/innodb/ibuf_bitmap_mutex | YES | YES | | wait/synch/mutex/innodb/ibuf_mutex | YES | YES | | wait/synch/mutex/innodb/ibuf_pessimistic_insert_mutex | YES | YES | +-------------------------------------------------------+---------+-------+
InnoDB
mutex 待機の監視の詳細は、セクション15.16.2「パフォーマンススキーマを使用した InnoDB Mutex 待機のモニタリング」 を参照してください。