

# Aurora MySQL でのバイナリログのレプリケーションの最適化
<a name="binlog-optimization"></a>

 次に、Aurora MySQL でバイナリログのレプリケーションのパフォーマンスを最適化し、関連する問題のトラブルシューティングを行う方法について説明します。

**ヒント**  
 この説明は、MySQL バイナリログのレプリケーションメカニズムとその仕組みに精通していることを前提としています。背景情報については、MySQL ドキュメントの「[レプリケーション実装ガイド](https://dev.mysql.com/doc/refman/8.0/en/replication-implementation.html)」を参照してください。

## マルチスレッドバイナリログレプリケーション
<a name="binlog-optimization-multithreading"></a>

マルチスレッドのバイナリログレプリケーションでは、SQL スレッドはリレーログからイベントを読み取り、SQL ワーカースレッドが適用されるようにキューに入れます。SQL ワーカースレッドは、コーディネータスレッドによって管理されます。バイナリログイベントは、可能な場合はパラレルに適用されます。並列処理のレベルは、バージョン、パラメータ、スキーマ設計、ワークロード特性などの要因によって異なります。

マルチスレッドバイナリログレプリケーションは、Aurora MySQL バージョン 3 および Aurora MySQL バージョン 2.12.1 以降でサポートされています。マルチスレッドレプリカがバイナリログイベントを効率的に並列処理するには、マルチスレッドバイナリログレプリケーションのソースを設定し、ソースでバイナリログファイルに並列処理情報を含むバージョンを使用する必要があります。

Aurora MySQL DB インスタンスがバイナリログレプリケーションを使用するように構成されている場合、レプリカインスタンスはデフォルトで 3.04 より前の Aurora MySQL バージョンに対してシングルスレッドレプリケーションを使用します。マルチスレッドレプリケーションを有効にするには、カスタムパラメータグループの `replica_parallel_workers` パラメータを `1` より大きい値に設定します。

Aurora MySQL バージョン 3.04 以降では、レプリケーションはデフォルトでマルチスレッド化され、`replica_parallel_workers` は `4` に設定されています。このパラメータはカスタムパラメータグループで変更できます。

予期しない停止に対するデータベースの耐障害性を高めるには、ソースで GTID レプリケーションを有効にし、レプリカで GTID を許可することをお勧めします。GTID レプリケーションを許可するには、ソースとレプリカの両方で `gtid_mode` を `ON_PERMISSIVE` に設定します。GTID ベースのレプリケーションの詳細については、「[GTID ベースレプリケーションを使用する](mysql-replication-gtid.md)」を参照してください。

以下の構成オプションを使用して、マルチスレッドレプリケーションを微調整することができます。使用量に関する情報については、*MySQL リファレンスマニュアル*の[レプリケーションとバイナリログのオプションと可変](https://dev.mysql.com/doc/refman/8.0/en/replication-options.html)を参照してください。マルチスレッドレプリケーションの詳細については、MySQL ブログ「[https://dev.mysql.com/blog-archive/improving-the-parallel-applier-with-writeset-based-dependency-tracking/](https://dev.mysql.com/blog-archive/improving-the-parallel-applier-with-writeset-based-dependency-tracking/)」を参照してください。

最適なパラメータ値は、いくつかの要因によって決まります。例えば、バイナリログレプリケーションのパフォーマンスは、データベースワークロードの特性と、レプリカが実行されている DB インスタンスクラスの影響を受けます。したがって、新しいパラメータ設定を本番インスタンスに適用する前に、これらの構成パラメータに対するすべての変更を徹底的にテストすることをお勧めします。
+ `binlog_format recommended value` - に設定`ROW`
+ `binlog_group_commit_sync_delay`
+ `binlog_group_commit_sync_no_delay_count`
+ `binlog_transaction_dependency_history_size`
+ `binlog_transaction_dependency_tracking` - 推奨値は `WRITESET` です。
+ `replica_preserve_commit_order`
+ `replica_parallel_type` - 推奨値は `LOGICAL_CLOCK` です。
+ `replica_parallel_workers`
+ `replica_pending_jobs_size_max`
+ `transaction_write_set_extraction` - 推奨値は `XXHASH64` です。

スキーマとワークロードの特性は、レプリケーションに並行して影響を与える要因です。最も一般的な問題を次に挙げます。
+ プライマリキーがない – RDS は、プライマリキーがないテーブルの writeset 依存関係を確立できません。`ROW` 形式を使用すると、ソースに対して 1 回のフルテーブルスキャンで 1 つの複数行ステートメントを実行できますが、レプリカで変更された行ごとに 1 回のフルテーブルスキャンになります。プライマリキーがないと、レプリケーションスループットが大幅に低下します。
+ 外部キーの存在 – 外部キーが存在する場合、Amazon RDS は FK 関係を持つテーブルの並列処理に writeset 依存関係を使用できません。
+ トランザクションのサイズ – 1 つのトランザクションが数十または数百メガバイトまたはギガバイトに及ぶ場合、コーディネータースレッドとワーカースレッドの 1 つがそのトランザクションのみの処理に長時間かかることがあります。その間、他のすべてのワーカースレッドは、以前のトランザクションの処理が終了した後もアイドル状態のままになる可能性があります。

Aurora MySQL バージョン 3.06 以降では、複数のセカンダリインデックスを持つ大きなテーブルのトランザクションをレプリケートするときにバイナリログレプリカのパフォーマンスを向上させることができます。この機能により、バイナリログレプリカにセカンダリインデックスの変更を並列で適用するスレッドプールが導入されます。この機能は `aurora_binlog_replication_sec_index_parallel_workers` DB クラスターパラメータによって制御されます。これにより、セカンダリインデックスの変更を適用できる並列スレッドの総数が制御されます。パラメータは、デフォルトで `0` (無効) に設定されています。この機能を有効にしてもインスタンスを再起動する必要はありません。この機能を有効にするには、進行中のレプリケーションを停止し、必要な数の並列ワーカースレッドを設定してから、レプリケーションを再開します。

## バイナリログのレプリケーションの最適化
<a name="binlog-optimization-binlog-io-cache"></a><a name="binlog_boost"></a><a name="binlog_io_cache"></a>

 Aurora MySQL 2.10 以降では、Aurora は、バイナリログのレプリケーションにバイナリログ I/O キャッシュと呼ばれる最適化を自動的に適用します。最後にコミットされたバイナリログイベントをキャッシュすることにより、この最適化は、バイナリログ出典インスタンスでのフォアグラウンドトランザクションへの影響を制限しながら、バイナリログのダンプスレッドのパフォーマンスを向上するように設計されています。

**注記**  
 この機能に使用されるこのメモリは、MySQL `binlog_cache` 設定とは無関係です。  
 この機能は、`db.t2` および `db.t3` インスタンスクラスを使用する Aurora DB インスタンスには適用されません。

この最適化を有効にするために、設定パラメータを調整する必要はありません。特に、以前の Aurora MySQL バージョンで設定パラメータ `aurora_binlog_replication_max_yield_seconds` をゼロ以外の値に調整した場合は、現在使用可能なバージョンでゼロに設定し直します。

これらのステータス変数 `aurora_binlog_io_cache_reads` と `aurora_binlog_io_cache_read_requests` は、バイナリログ I/O キャッシュからデータが読み込まれる頻度をモニタリングするのに役立ちます。
+  `aurora_binlog_io_cache_read_requests` はキャッシュからのバイナリログ I/O 読み取りリクエストの数を示します。
+  `aurora_binlog_io_cache_reads` はキャッシュから情報を取得するバイナリログ I/O 読み取り数を示します。

 次の SQL クエリは、キャッシュされた情報を利用するバイナリログ読み取りリクエストの割合を計算します。この場合、比率が 100 に近づくほど、より良好であることを意味します。

```
mysql> SELECT
  (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS
    WHERE VARIABLE_NAME='aurora_binlog_io_cache_reads')
  / (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS
    WHERE VARIABLE_NAME='aurora_binlog_io_cache_read_requests')
  * 100
  as binlog_io_cache_hit_ratio;
+---------------------------+
| binlog_io_cache_hit_ratio |
+---------------------------+
|         99.99847949080622 |
+---------------------------+
```

 バイナリログ I/O キャッシュ機能には、バイナリログのダンプスレッドに関連する新しいメトリクスも含まれています。*ダンプスレッド*は、新しいバイナリログレプリカがバイナリログ出典インスタンスに接続したときに作成されるスレッドです。

ダンプスレッドメトリクスは、60 秒ごとにプレフィックス `[Dump thread metrics]` を伴ってデータベースログに出力されます。メトリクスには、`Secondary_id`、`Secondary_uuid`、バイナリログのファイル名、各レプリカが読み込んでいる位置など、各バイナリログのレプリカの情報が含まれます。メトリクスには、レプリケーション出典とレプリカの間の距離をバイト単位で表す `Bytes_behind_primary` も含まれます。このメトリクスは、レプリカ I/O スレッドのラグを測定します。この数値は、バイナリログのレプリカの `seconds_behind_master` メトリクスによって表されるレプリカ SQL 適用元スレッドのラグとは異なります。距離が減少するか増加するかを確認することで、バイナリログレプリカが出典に追いついているのか、遅れているのかを判断できます。

## インメモリリレーログ
<a name="binlog-optimization-in-memory-relay-log"></a>

Aurora MySQL バージョン 3.10 以降では、レプリケーションのスループットを向上させるために、インメモリリレーログと呼ばれる最適化を導入しています。この最適化では、すべての中間リレーログコンテンツをメモリにキャッシュすることで、リレーログの I/O パフォーマンスを向上させます。その結果、リレーログコンテンツはメモリ内で簡単にアクセスできる状態となるため、ストレージ I/O オペレーションが最小限に抑えられ、コミットレイテンシーが短縮されます。

デフォルトでは、レプリカが次のいずれかの設定を満たす場合、インメモリリレーログ機能は Aurora マネージドレプリケーションシナリオ (ブルー/グリーンデプロイ、Aurora-Aurora レプリケーション、クロスリージョンレプリカなど) で自動的に有効になります。
+ シングルスレッドレプリケーションモード (replica\$1parallel\$1workers = 0)
+ GTID モードが有効になっているマルチスレッドレプリケーション:
  + 自動位置設定の有効化
  + レプリカで GTID モードを ON に設定
+ replica\$1preserve\$1commit\$1order = ON によるファイルベースのレプリケーション

インメモリリレーログ機能は、t3.large より大きいインスタンスクラスでサポートされていますが、Aurora Serverless インスタンスでは利用できません。リレーログの循環バッファのサイズは 128 MB に固定されています。この機能のメモリ消費量をモニタリングするには、次のクエリを実行できます。

```
SELECT event_name, current_alloc FROM sys.memory_global_by_current_bytes WHERE event_name = 'memory/sql/relaylog_io_cache';
```

インメモリリレーログ機能は、aurora\$1in\$1memory\$1relaylog パラメータで制御します。このパラメータは、DB クラスターまたはインスタンスレベルで設定できます。この機能は、インスタンスを再起動しなくても、動的に有効化または無効化できます。

1. 進行中のレプリケーションを停止する

1. パラメータグループで aurora\$1in\$1memory\$1relaylog を ON (有効) または OFF (無効) に設定します。

1. レプリケーションを再開する

例:

```
CALL mysql.rds_stop_replication;
set aurora_in_memory_relaylog to ON to enable or OFF to disable in cluster parameter group
CALL mysql.rds_start_replication;
```

aurora\$1in\$1memory\$1relaylog を ON に設定している場合でも、特定の条件下ではインメモリリレーログ機能が無効になっている場合があります。この機能の現在のステータスを確認するには、次のコマンドを使用できます。

```
SHOW GLOBAL STATUS LIKE 'Aurora_in_memory_relaylog_status';
```

この機能が予期せず無効になっている場合は、次のコマンドを実行して理由を特定できます。

```
SHOW GLOBAL STATUS LIKE 'Aurora_in_memory_relaylog_disabled_reason';
```

このコマンドは、この機能が現在無効になっている理由を説明するメッセージを返します。