

# MySQL のデータインポートに関する考慮事項
<a name="MySQL.Procedural.Importing.Advanced"></a>

以下のコンテンツには、MySQL へのデータのロードに関連する技術情報が含まれています。このコンテンツは、MySQL サーバーアーキテクチャに精通しているユーザーを対象としています。

## バイナリログ記録
<a name="MySQL.Procedural.Importing.Advanced.Log"></a>

バイナリログ記録を有効にすると、データロードのパフォーマンスが低下し、ログを無効にした場合と比較して最大 4 倍の追加のディスク領域が必要になります。データのロードに使用されるトランザクションサイズは、システムのパフォーマンスとディスク容量のニーズに直接影響します。トランザクションが大きいほど、より多くのリソースが必要になります。

## トランザクションサイズ
<a name="MySQL.Procedural.Importing.Advanced.Size"></a>

トランザクションサイズは、MySQL データロードの以下の側面に影響します。
+ リソース消費
+ ディスクスペースの使用率
+ プロセスの再開
+ 復旧時間
+ 入力形式 (フラットファイルまたは SQL)

このセクションでは、トランザクションサイズがバイナリログ作成に与える影響について説明し、大量のデータロード中にバイナリログ作成を無効にするケースを作成します。Amazon RDS 自動バックアップ保持期間を設定することで、バイナリログ作成を有効または無効にすることができます。値が 0 以外の場合はバイナリログ作成が有効になり、0 の場合は無効になります。詳細については、「[バックアップの保存期間](USER_WorkingWithAutomatedBackups.BackupRetention.md)」を参照してください。

このセクションでは、大規模なトランザクションが InnoDB に与える影響と、トランザクションサイズを小さく保つことが重要な理由についても説明します。

### 小さいトランザクション
<a name="MySQL.Procedural.Importing.Advanced.Log.Small"></a>

トランザクションが小さい場合、バイナリログ作成により、データのロードに必要なディスク書き込み数が 2 倍になります。この影響は、他のデータベースセッションのパフォーマンスを著しく低下させ、データのロードに必要な時間を長くします。劣化の程度は、以下の要因に一部依存します。
+ アップロードレート
+ ロード中に発生するその他のデータベースアクティビティ
+ Amazon RDS DB インスタンスの容量

バイナリログは、バックアップおよび削除されるまでにロードされたデータの量とほぼ同じディスク容量を消費します。Amazon RDS は、バイナリログを頻繁にバックアップして削除することで、この容量を最小限に抑えます。

### 大きいトランザクション
<a name="MySQL.Procedural.Importing.Advanced.Log.Large"></a>

大規模なトランザクションの場合、バイナリログによって、次の理由により IOPS とディスク使用量が 3 倍になります。
+ バイナリログキャッシュは、トランザクションデータを一時的にディスクに保存します。
+ このキャッシュはトランザクションのサイズに応じて大きくなり、ディスク領域を消費します。
+ トランザクション (コミットまたはロールバック) が完了すると、システムはキャッシュをバイナリログにコピーします。

このプロセスでは、データのコピーが 3 つ作成されます。
+ 元のデータ
+ ディスク上のキャッシュ
+ 最後のバイナリログエントリ

書き込みオペレーションごとに追加の IO が発生し、パフォーマンスにさらに影響を及ぼします。

このため、バイナリログ記録には、ログ記録を無効にした場合と比較して 3 倍のディスク容量が必要です。例えば、1 つのトランザクションとして 10 GiB のデータをロードすると、次の 3 つのコピーが作成されます。
+ テーブルデータに 10 GiB
+ バイナリログキャッシュに 10 GiB
+ バイナリログファイルに 10 GiB

必要な一時ディスク容量の合計は 30 GiB です。

ディスク容量に関する重要な考慮事項:
+ キャッシュファイルは、セッションが終了するか、新しいトランザクションによって別のキャッシュが作成されるまで保持されます。
+ バイナリログはバックアップされるまで保持され、長期間にわたって 20 GiB (キャッシュとログ) が保持される可能性があります。

`LOAD DATA LOCAL INFILE` を使用してデータをロードする場合、ロード前に行われたバックアップからデータベースを復元する必要がある場合に備えて、データ復旧によって 4 番目のコピーが作成されます。復旧時に、MySQL はバイナリログからフラットファイルにデータを抽出します。その後、MySQL は `LOAD DATA LOCAL INFILE` を実行します。上記の例の場合、この復旧には合計 40 GiB、つまりテーブル、キャッシュ、ログ、ローカルファイルごとに 10 GiB の一時ディスク領域が必要です。少なくとも 40 GiB の空きディスク容量がないと、復旧は失敗します。

### 大規模なデータロードの最適化
<a name="MySQL.Procedural.Importing.AnySource.Advanced.Disable"></a>

大量のデータをロードする場合は、バイナリログを無効にして、オーバーヘッドとディスク領域の要件を削減します。バイナリログ記録を無効にするには、バックアップ保持期間を 0 に設定します。ロードが完了したら、バックアップ保持期間を適切なゼロ以外の値に復元します。詳細については、設定テーブルの「[Amazon RDS DB インスタンスを変更する](Overview.DBInstance.Modifying.md)」および「[バックアップ保持期間](USER_ModifyInstance.Settings.md)」を参照してください。

**注記**  
DB インスタンスがリードレプリカのソース DB インスタンスである場合、バックアップ保持期間を 0 に設定することはできません。

データをロードする前に、DB スナップショットを作成することをお勧めします。詳細については、「[手動バックアップの管理](USER_ManagingManualBackups.md)」を参照してください。

## InnoDB
<a name="MySQL.Procedural.Importing.Advanced.InnoDB"></a>

undo ログと復旧のオプションに関する以下の情報は、InnoDB トランザクションを小さくしてデータベースのパフォーマンスを最適化することをサポートしています。

### InnoDB の undo ログについて
<a name="MySQL.Procedural.Importing.Advanced.InnoDB.Undo"></a>

undo ログは、トランザクションのロールバックを有効にし、マルチバージョン同時実行制御 (MVCC) をサポートするログ記録メカニズムです。

MySQL 5.7 以前のバージョンでは、undo ログは InnoDB システムテーブルスペース (通常は ibdata1) に保存され、パージスレッドによって削除されるまで保持されます。その結果、大規模なデータロードトランザクションによってシステムテーブルスペースが非常に大きくなり、データベースを再作成しない限り再利用できないディスク領域が消費される可能性があります。

すべての MySQL バージョンでは、最も古いアクティブなトランザクションがコミットまたはロールバックされるまで、パージスレッドは undo ログの削除を待機する必要があります。データベースが、ロード中に他のトランザクションを処理する場合、そのトランザクションがコミットされ、他のトランザクションが MVCC の undo ログを必要としない場合でも、それらの undo ログも蓄積され、削除できません。この場合、読み取り専用トランザクションを含むすべてのトランザクションが遅くなります。このスローダウンは、すべてのトランザクションが、ロードトランザクションだけでなく、任意のトランザクションが変更するすべての行にアクセスするために発生します。実際には、トランザクションは、長時間実行されるロードトランザクションによって undo ログのクリーンアップ中に消去されなかった undo ログをスキャンする必要があります。これは、変更された行にアクセスするオペレーションのパフォーマンスに影響します。

### InnoDB トランザクション復旧オプション
<a name="MySQL.Procedural.Importing.Advanced.InnoDB.Rollback"></a>

InnoDB はコミットオペレーションを最適化しますが、大規模なトランザクションのロールバックは遅くなります。復旧を高速化するには、ポイントインタイムリカバリを実行するか、DB スナップショットを復元します。詳細については、「[ポイントインタイムリカバリ](USER_PIT.md)」および「[DB インスタンスへの復元](USER_RestoreFromSnapshot.md)」を参照してください。

## データインポート形式
<a name="MySQL.Procedural.Importing.Advanced.InputFormat"></a>

MySQL は、フラットファイルと SQL の 2 つのデータインポート形式をサポートしています。各形式に関する情報を確認して、ニーズに最適なオプションを決定します。

### フラットファイル
<a name="MySQL.Procedural.Importing.Advanced.InputFormat.FlatFiles"></a>

小規模なトランザクションの場合は、`LOAD DATA LOCAL INFILE` を使用してフラットファイルをロードします。このデータインポート形式は、SQL を使用する場合に比べて次のようなメリットがあります。
+ ネットワークトラフィックの削減
+ データ転送コストの削減
+ データベース処理オーバーヘッドの減少
+ より高速な処理

`LOAD DATA LOCAL INFILE` はフラットファイル全体を 1 つのトランザクションとしてロードします。個々のファイルのサイズを小さく保つと、次の利点があります。
+ **再開機能** - どのファイルがロードされたかを追跡できます。ロード中に問題が発生した場合、中断したところから再開できます。一部のデータを Amazon RDS に再送信する必要がある場合でも、ファイルが小さいと、再送信される量は最小限ですみます。
+ **同時データロード** – 単一ファイルのロードに十分な IOPS とネットワーク帯域幅がある場合、同時にロードすれば時間を節約できます。
+ **ロード速度制御** – データロードが他のプロセスに悪影響を及ぼす場合は、ファイル間の間隔を増やすことでロード速度を制御できます。

大規模なトランザクションでは、`LOAD DATA LOCAL INFILE` を使用してデータをインポートするメリットが減ります。大量のデータを小さなファイルに分割できない場合は、SQL の使用を検討してください。

### SQL
<a name="MySQL.Procedural.Importing.Advanced.InputFormat.SQL"></a>

SQL にはフラットファイルに比べて、トランザクションサイズを簡単に小さく保つことができるという大きなメリットがあります。ただし、SQL のロードにはフラットファイルよりもかなり時間がかかる場合があります。また、障害が発生した後、どこから再開するかを判断するのが難しい場合があります。mysqldump ファイルを再開することはできません。mysqldump ファイルのロード中にエラーが発生した場合、ロードを再開するにはファイルを変更するか置き換える必要があります。または、障害の原因を修正した後、ロード前の時点に復元してファイルを再開する必要があります。詳細については、「[ポイントインタイムリカバリ](USER_PIT.md)」を参照してください。

## データベースチェックポイントに Amazon RDS DB スナップショットを使用する
<a name="MySQL.Procedural.Importing.Advanced.Checkpoints"></a>

バイナリログ記録を使用せずに、数時間または数日など長期間にわたってデータをロードする場合は、DB スナップショットを使用して、データの安全性を確保するために定期的なチェックポイントを提供します。各 DB スナップショットは、システム障害やデータ破損イベント時の復旧ポイントとして機能するデータベースインスタンスの一貫したコピーを作成します。DB スナップショットは高速であるため、頻繁なチェックポイント作成によるロードパフォーマンスへの影響は最小限に抑えられます。データベースの耐久性や復旧機能に影響を与えることなく、以前の DB スナップショットを削除できます。DB スナップショットの詳細については、「[手動バックアップの管理](USER_ManagingManualBackups.md)」を参照してください。

## データベースのロード時間を短縮する
<a name="MySQL.Procedural.Importing.Advanced.LoadTime"></a>

以下の項目は、ロード時間を短縮するための追加のヒントです。
+ MySQL データベースにデータをロードする前に、すべてのセカンダリインデックスを作成します。他のデータベースシステムとは異なり、MySQL はセカンダリインデックスを追加または変更するときにテーブル全体を再構築します。このプロセスでは、インデックスが変更された新しいテーブルが作成され、すべてのデータがコピーされ、元のテーブルが削除されます。
+ プライマリキーの順序でデータをロードします。InnoDB テーブルの場合、これによりロード時間が 75%～80% 短縮され、データファイルサイズが 50% 短縮されます。
+ `foreign_key_checks` を `0` に設定して、外部キーの制約を無効にします。これは多くの場合、`LOAD DATA LOCAL INFILE` を使用してロードされたフラットファイルで必要となります。どのロードでも、外部キーチェックを無効にすると、データのロードが高速化されます。ロードが完了したら、`foreign_key_checks` を `1` に設定して制約を再度有効にし、データを検証します。
+ リソース制限に近づかない限り、データを同時にロードします。複数のテーブルセグメント間で同時ロードを有効にするには、必要に応じてパーティションテーブルを使用します。
+ SQL 実行のオーバーヘッドを減らすには、複数の `INSERT` ステートメントを単一の複数値 `INSERT` オペレーションに結合します。`mysqldump` は、この最適化を自動的に実装します。
+ `innodb_flush_log_at_trx_commit` を `0` に設定することで、InnoDB ログ IO オペレーションを減らします。ロードが完了したら、`innodb_flush_log_at_trx_commit` を `1` に戻します。
**警告**  
`innodb_flush_log_at_trx_commit` を `0` に設定すると、InnoDB はコミットごとではなく毎秒ログをフラッシュします。この設定はパフォーマンスを向上させますが、システム障害時にトランザクションが失われるリスクがあります。
+ リードレプリカがない DB インスタンスにデータをロードする場合は、`sync_binlog` を `0` に設定します。ロードが完了したら、`sync_binlog parameter` を `1` に戻します。
+ DB インスタンスをマルチ AZ 配置に変換する前に、シングル AZ DB インスタンスにデータをロードします。DB インスタンスが既にマルチ AZ 配置を使用している場合は、データロードのためにシングル AZ 配置に切り替えることはお勧めしません。これで実現できる改善はわずかだけです。