アプリケーションでラージトランザクションを実行する場合、トランザクションのコミット中にバイナリログを処理するために必要な時間が非常に長くなり、ApsaraDB RDS for MySQL インスタンスが応答を停止したり、長時間書き込みリクエストを処理できなくなることがあります。 この問題を解決するために、ApsaraDB RDS for MySQL はバイナリログキャッシュのフリーフラッシュ機能を提供しています。 この機能は、ラージトランザクションのコミットを最適化し、RDS インスタンスの安定性を向上させます。
前提条件
RDS インスタンスで MySQL 8.0 または MySQL 5.7、および 20240731 以降のマイナーエンジンバージョンが実行されていること。
RDS インスタンスのマイナーエンジンバージョンを表示するには、ApsaraDB RDS コンソールにログインし、[基本情報] ページに移動します。 [構成情報] セクションで、[カーネルバージョンのアップグレード] ボタンが表示されているかどうかを確認します。 ボタンが表示されている場合は、ボタンをクリックして RDS インスタンスのマイナーエンジンバージョンを表示および更新できます。 ボタンが表示されていない場合は、RDS インスタンスで最新のマイナーエンジンバージョンが実行されています。 詳細については、「マイナーエンジンバージョンを更新する」をご参照ください。
実装
バイナリログキャッシュ
バイナリログキャッシュは、一時ファイルによって占有されるセッションレベルのディスク容量です。 バイナリログキャッシュは、バイナリログイベントを一時的に格納するために、セッションごとに割り当てられます。 バイナリログキャッシュのサイズは、メモリキャッシュのサイズと一時ファイルのサイズの合計です。 メモリキャッシュのサイズは、binlog_cache_size パラメーターで指定されます。 トランザクションが大きく、メモリキャッシュがいっぱいの場合、トランザクションのイベントは一時ファイルに記録されます。
トランザクションの実行中、生成されたイベントはバイナリログキャッシュに一時的に格納されます。 トランザクションがコミットされている場合、システムは生成されたイベントをバイナリログキャッシュから 1 つずつ読み取り、終了位置とチェックサムを更新してから、イベントをバイナリログファイルに書き込みます。 プロセス全体で、トランザクション用に生成されたイベントが中断することなくバイナリログに書き込まれることを保証するためにロックが必要です。 その結果、1 つのトランザクションのイベントがバイナリログファイルに書き込まれると、他のトランザクションはブロックされます。
ラージトランザクションからのバイナリログ書き込みによる影響
トランザクションが非常に大きく、数十 GB のバイナリログキャッシュを占有する場合、トランザクションのコミット中にトランザクションのイベントをバイナリログファイルに書き込むのに必要な時間が長くなります。 これにより、次の影響が生じます。
ラージトランザクションのイベントをバイナリログファイルに書き込むには、書き込みロックが必要です。 その結果、RDS インスタンスは書き込みプロセス中に書き込みリクエストを処理できません。
ラージトランザクションのイベントをバイナリログファイルに書き込むと、大量の I/O リソースが消費されます。 I/O リソースが不足している場合、RDS インスタンスが応答を停止する可能性があります。
バイナリログキャッシュのフリーフラッシュ機能の最適化
AliSQL は、バイナリログキャッシュのフリーフラッシュ機能を最適化します。 最適化後、バイナリログキャッシュに格納されている一時ファイルをバイナリログファイルに変換できます。 バイナリログキャッシュのフリーフラッシュ機能が有効になっている場合、ラージトランザクションのコミット中に、バイナリログキャッシュの一時ファイルがバイナリログファイルに変換されます。 これにより、効率が向上し、I/O リソースの消費が削減され、RDS インスタンスに対するラージトランザクションからのバイナリログ書き込みによる影響が軽減されます。
バイナリログキャッシュ機構の最適化
バイナリログキャッシュの一時ファイルをバイナリログファイルに変換するために、AliSQL は次の側面からバイナリログキャッシュ機構を最適化します。
システムがバイナリログキャッシュに一時ファイルを書き込むとき、ファイルヘッダー用に容量が予約されます。 一時ファイルがバイナリログファイルに変換されると、予約容量はバイナリログファイルにイベントヘッダーを格納するために使用されます。
システムがバイナリログキャッシュにデータを書き込むとき、各イベントは予約容量に基づいて終了位置を計算します。
一時ファイルのバイナリログファイルへの変換
ラージトランザクションがコミットされると、システムはバイナリログキャッシュの一時ファイルをバイナリログファイルに変換します。 変換中、バイナリログファイルのヘッダーとヘッダーイベントはすべての予約容量を占有します。 予約容量には、次の種類のデータが格納されます。
ファイルヘッダー: 4 バイトのヘッダー
[ 0xFE 'bin']は、ファイルをバイナリログファイルとして識別するために使用されます。 各バイナリログファイルには、このヘッダーが含まれています。ヘッダーイベント: フォーマット記述イベントと以前のグローバルトランザクション ID (GTID) イベントが含まれています。
空のイベント: 現在のバイナリログファイル内の無視可能なイベントタイプの空のイベントは、残りの予約容量を占有するために使用されます。
GTID イベント: トランザクションの GTID は、トランザクションのコミット中に生成されます。 GTID イベントも予約容量に書き込まれます。
割り当てられた予約容量を持つバイナリログキャッシュ内のイベントは、バイナリログキャッシュの一時ファイルから変換されたバイナリログファイルに格納されます。 イベントには、クエリイベント、テーブルマップイベント、行ベースのイベント、および XID イベントが含まれます。
次のリストは、バイナリログキャッシュのフリーフラッシュ機能を使用して変換されたバイナリログファイルと通常のバイナリログファイルの違いを示しています。
変換されたバイナリログファイルには、空のイベントがあります。
変換されたバイナリログファイルのチェックサムは、デフォルトで無効になっています。
バイナリログキャッシュのフリーフラッシュ機能は、バイナリログファイルのフォーマットを変更しません。 バイナリログファイルを使用したレプリケーションとサードパーティツールは影響を受けません。
パラメーターの説明
loose_binlog_cache_free_flush:
バイナリログキャッシュのフリーフラッシュ機能を有効にするかどうかを指定します。 グローバルシステム変数です。 このパラメーターの値を変更すると、変更はすぐに有効になります。 RDS インスタンスを再起動する必要はありません。
有効値: on および off。
loose_binlog_cache_free_flush_limit_size:
一時ファイルをバイナリログファイルに変換するかどうかを指定します。 バイナリログキャッシュのフリーフラッシュ機能を有効にした後、トランザクションのバイナリログファイルの数がこのパラメーターの値を超えると、トランザクションのコミット中にバイナリログキャッシュに格納されている一時ファイルがバイナリログファイルに変換されます。
デフォルト値: 256 MB。
有効値: 20971520 ~ 18446744073709551615。 単位: バイト。
最適化の効果

上の図は、バイナリログキャッシュのフリーフラッシュ機能が有効になっている場合と無効になっている場合のパフォーマンスレベル 1 (PL1) のエンタープライズ SSD (ESSD) またはプレミアムローカル SSD を使用する RDS インスタンスへのラージトランザクションのコミットに必要な時間の違いを示しています。
バイナリログキャッシュのフリーフラッシュ機能が有効になっている場合、ラージトランザクションのコミットに必要な時間が短縮され、I/O リソースの不足やロック期間が長いなどの問題が解決されます。