

# DynamoDB 同一アカウントグローバルテーブル
<a name="globaltables-SameAccount"></a>

同一アカウントグローバルテーブルは、1 つの AWS アカウント内の AWS リージョン間で DynamoDB テーブルデータを自動的にレプリケートします。同一アカウントグローバルテーブルは、すべてのレプリカが同じアカウントの境界、所有権、アクセス許可モデルを共有するため、マルチリージョンアプリケーションを実行するための最もシンプルなモデルを提供します。レプリカテーブル用の AWS リージョンを選択すると、グローバルテーブルはすべてのレプリケーションを自動的に処理します。グローバルテーブルは、DynamoDB が利用可能なすべてのリージョンで使用できます。

同一アカウントグローバルテーブルには以下の利点があります。
+ 選択した AWS リージョン間で DynamoDB テーブルデータを自動的にレプリケートして、ユーザーに近いデータを配置する
+ リージョンの分離またはパフォーマンス低下時にアプリケーションの可用性を高める
+ 組み込みの競合の解決を使用して、アプリケーションのビジネスロジックに集中できるようにする
+ 同一アカウントグローバルテーブルを作成するときは、[マルチリージョンの結果整合性 (MREC)](V2globaltables_HowItWorks.md#V2globaltables_HowItWorks.consistency-modes.mrec) または [マルチリージョンの強力な整合性 (MRSC)](V2globaltables_HowItWorks.md#V2globaltables_HowItWorks.consistency-modes.mrsc) のいずれかを選択できます。

**Topics**
+ [DynamoDB グローバルテーブルの仕組み](V2globaltables_HowItWorks.md)
+ [チュートリアル: グローバルテーブルの作成](V2globaltables.tutorial.md)
+ [DynamoDB グローバルテーブルのセキュリティ](globaltables-security.md)

# DynamoDB グローバルテーブルの仕組み
<a name="V2globaltables_HowItWorks"></a>

以下のセクションでは、Amazon DynamoDB におけるグローバルテーブルの概念および動作について説明します。

## 概念
<a name="V2globaltables_HowItWorks.KeyConcepts"></a>

*グローバルテーブル*は、AWS リージョン間でテーブルデータをレプリケートする DynamoDB 機能です。

*レプリカテーブル* (または、レプリカ) は、グローバルテーブルの一環として機能する DynamoDB テーブルです。グローバルテーブルは、異なる AWS リージョンにまたがる 2 つ以上のレプリカテーブルで構成されます。各グローバルテーブルは、AWS リージョンごとに 1 つのレプリカのみを持つことができます。グローバルテーブル内のすべてのレプリカは、同じテーブル名、プライマリキースキーマ、および項目データを共有します。

アプリケーションが 1 つのリージョンのレプリカにデータを書き込むと、DynamoDB は自動的にその書き込みをグローバルテーブル内の他のすべてのレプリカにレプリケートします。グローバルテーブルの詳しい使用方法については、[チュートリアル: グローバルテーブルの作成](V2globaltables.tutorial.md) を参照してください。

## バージョン
<a name="V2globaltables_HowItWorks.versions"></a>

DynamoDB グローバルテーブルには、バージョン 2019.11.21 (現行) と[バージョン 2017.11.29 (レガシー)](globaltables.V1.md) の 2 つのバージョンがあります。可能な限り、バージョン 2019.11.21 (現行) を使用する必要があります。このドキュメントセクションの情報は、バージョン 2019.11.21 (現行) 用です。詳細については、「[グローバルテーブルのバージョンを確認する](V2globaltables_versions.md#globaltables.DetermineVersion)」を参照してください。

## 利用可能な状況
<a name="V2globaltables_HowItWorks.availability"></a>

グローバルテーブルは、マルチリージョンの高可用性アーキテクチャの実装を容易にすることで、ビジネス継続性の向上に役立ちます。1 つの AWS リージョンのワークロードに障害が発生した場合、アプリケーショントラフィックを別のリージョンに移行し、同じグローバルテーブル内の別のレプリカテーブルに対して読み取りと書き込みを実行できます。

グローバルテーブル内の各レプリカテーブルは、単一リージョンの DynamoDB テーブルと同じ耐久性と可用性を提供します。グローバルテーブルは 99.999% の可用性[サービスレベルアグリーメント (SLA)](https://aws.amazon.com//dynamodb/sla/) を提供しますが、単一リージョンテーブルでは 99.99% です。

## 整合性モード
<a name="V2globaltables_HowItWorks.consistency-modes"></a>

グローバルテーブルを作成するときに、その整合性モードを設定できます。グローバルテーブルは、マルチリージョンの結果整合性 (MREC) およびマルチリージョンの強力な整合性 (MRSC) の 2 つの整合性モードをサポートしています。

グローバルテーブルの作成時に整合性モードを指定しない場合、グローバルテーブルはデフォルトでマルチリージョンの結果整合性 (MREC) になります。グローバルテーブルには、異なる整合性モードで設定されたレプリカを含めることはできません。グローバルテーブルの整合性モードを作成後に変更することはできません。

### マルチリージョンの結果整合性 (MREC)
<a name="V2globaltables_HowItWorks.consistency-modes.mrec"></a>

マルチリージョンの結果整合性 (MREC) は、グローバルテーブルのデフォルトの整合性モードです。MREC グローバルテーブルレプリカの項目の変更は、通常は 1 秒以内で他のすべてのレプリカに非同期でレプリケートされます。万一、MREC グローバルテーブルのレプリカで分離または障害が発生した場合、他のリージョンにまだレプリケートされていないデータは、レプリカが正常になるとレプリケートされます。

同じ項目が複数のリージョンで同時に変更された場合、DynamoDB は項目ごとに最新の内部タイムスタンプを使用して競合を解決します。これは「最終書き込み者優先」競合解決方法と呼ばれます。最終的に、項目はすべてのレプリカで最後の書き込みによって作成されたバージョンに収束します。

[強力な整合性のある読み込みオペレーション](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html#DDB-GetItem-request-ConsistentRead)は、その項目が読み取りが発生したリージョンで最後に更新された場合は項目の最新バージョンを返しますが、項目が別のリージョンで最後に更新された場合は古いデータを返す可能性があります。条件付き書き込みは、リージョン内の項目のバージョンに対して条件式を評価します。

MREC グローバルテーブルを作成するには、既存の DynamoDB テーブルにレプリカを追加します。レプリカを追加しても、既存の単一リージョン DynamoDB テーブルまたはグローバルテーブルレプリカのパフォーマンスには影響しません。MREC グローバルテーブルにレプリカを追加して、データがレプリケートされるリージョンの数を拡張したり、不要になったレプリカを MREC グローバルテーブルから削除したりできます。MREC グローバルテーブルは、DynamoDB が利用可能な任意のリージョンにレプリカを持つことができ、[AWS パーティション](https://docs.aws.amazon.com/whitepapers/latest/aws-fault-isolation-boundaries/partitions.html)内のリージョンと同じ数のレプリカを持つことができます。

### マルチリージョンの強力な整合性 (MRSC)
<a name="V2globaltables_HowItWorks.consistency-modes.mrsc"></a>

グローバルテーブルを作成する際に、マルチリージョンの強力な整合性 (MRSC) モードを設定できます。MRSC グローバルテーブルレプリカの項目の変更は、書き込み操作が正常なレスポンスを返す前に、少なくとも 1 つの他のリージョンに同期的にレプリケートされます。MRSC レプリカに対する強力な整合性のある読み込み操作は、常に項目の最新バージョンを返します。条件付き書き込みは、常に条件式を項目の最新バージョンと照合して評価します。

MRSC グローバルテーブルは、厳密に 3 つのリージョンにデプロイする必要があります。MRSC グローバルテーブルは、3 つのレプリカ、または 2 つのレプリカと 1 つの監視で設定できます。監視は、グローバルテーブルレプリカに書き込まれたデータを含む MRSC グローバルテーブルのコンポーネントであり、MRSC の可用性アーキテクチャをサポートしながら、完全なレプリカに代わるオプションを提供します。監視に対して読み取りまたは書き込み操作を実行することはできません。監視は、2 つのレプリカとは異なるリージョンにあります。MRSC グローバルテーブルを作成する際、MRSC テーブルの作成時にレプリカと監視デプロイの両方のリージョンを選択します。MRSC グローバルテーブルに監視が設定されているかどうか、どのリージョンに設定されているかは、[https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) API の出力から判断できます。監視は DynamoDB によって所有および管理され、設定されているリージョンの AWS アカウントには表示されません。

MRSC グローバルテーブルは、次のリージョンセットで利用できます。米国リージョンセット (米国東部バージニア北部、米国東部オハイオ、米国西部オレゴン)、欧州リージョンセット (欧州アイルランド、欧州ロンドン、欧州パリ、欧州フランクフルト)、および AP リージョンセット (アジアパシフィック東京、アジアパシフィックソウル、アジアパシフィック大阪)。MRSC グローバルテーブルはリージョンセットにまたがることはできません (例えば、MRSC グローバルテーブルに米国と欧州の両方のリージョンセットからのレプリカを含めることはできません)。

MRSC グローバルテーブルを作成するには、データを含まない既存の DynamoDB テーブルに 1 つのレプリカと監視または 2 つのレプリカを追加します。既存の単一リージョンテーブルを MRSC グローバルテーブルに変換する場合は、テーブルが空であることを確認する必要があります。単一リージョンテーブルを既存の項目を持つ MRSC グローバルテーブルに変換することはサポートされていません。変換プロセス中にデータがテーブルに書き込まれないよう確認してください。既存の MRSC グローバルテーブルに追加のレプリカを追加することはできません。MRSC グローバルテーブルから単一のレプリカまたは監視を削除することはできません。MRSC グローバルテーブルから 2 つのレプリカを削除するか、1 つのレプリカと監視を削除して、残りのレプリカを単一リージョンの DynamoDB テーブルに変換できます。

別のリージョンで既に変更されている項目を変更しようとすると、書き込み操作は `ReplicatedWriteConflictException` で失敗します。`ReplicatedWriteConflictException` で失敗した書き込みは再試行でき、項目が別のリージョンで変更されなくなった場合に成功します。

MRSC グローバルテーブルには、次の考慮事項が適用されます。
+ MRSC グローバルテーブルでは、有効期限 (TTL) はサポートされていません。
+ ローカルセカンダリインデックス (LSI) は、MRSC グローバルテーブルではサポートされていません。
+ CloudWatch Contributor Insights の情報は、オペレーションが発生したリージョンについてのみ報告されます。

## 整合性モードの選択
<a name="V2globaltables_HowItWorks.choosing-consistency-mode"></a>

マルチリージョン整合性モードを選択するための重要な基準は、アプリケーションが低レイテンシーの書き込みと強力な整合性のある読み込みを優先するか、グローバルな強力な整合性を優先するかです。

MREC グローバルテーブルは、MRSC グローバルテーブルと比較して書き込みレイテンシーが低く、強力な整合性のある読み込みレイテンシーを持ちます。MREC グローバルテーブルには、レプリカ間のレプリケーション遅延と等しい目標復旧時点 (RPO) があり、レプリカのリージョンに応じて通常は数秒です。

次の場合は、MREC モードを使用する必要があります。
+ アプリケーションは、データが別のリージョンで更新された場合に、強力な整合性のある読み込みオペレーションから返される古いデータを許容できます。
+ マルチリージョンの読み取り整合性よりも、書き込みレイテンシーが低く、強力な整合性のある読み込みレイテンシーを優先します。
+ マルチリージョンの高可用性戦略では、0 を超える RPO を許容できます。

MRSC グローバルテーブルは、MREC グローバルテーブルと比較して書き込みレイテンシーが高く、強力な整合性のある読み込みレイテンシーを持ちます。MRSC グローバルテーブルは、目標復旧時点 (RPO) ゼロをサポートします。

MRSC モードは、次の場合に使用します。
+ 複数のリージョン間で強力な整合性のある読み込みが必要です。
+ グローバル読み取り整合性は、書き込みレイテンシーの短縮よりも優先されます。
+ マルチリージョンの高可用性戦略では、RPO を 0 にする必要があります。

## グローバルテーブルのモニタリング
<a name="monitoring-global-tables"></a>

マルチリージョンの結果整合性 (MREC) 用に設定されたグローバルテーブルは [`ReplicationLatency`](metrics-dimensions.md#ReplicationLatency) メトリクスを CloudWatch に発行します。このメトリクスは、項目がレプリカテーブルに書き込まれてから、その項目がグローバルテーブルの別のレプリカに表示されるまでの経過時間を追跡します。`ReplicationLatency` はミリ秒単位で表し、グローバルテーブル内のすべての送信元と送信先のリージョンペアに対して出力されます。

一般的な `ReplicationLatency` 値は、選択した AWS リージョン間の距離と、ワークロードタイプやスループットなどの他の変数によって異なります。例えば、米国西部 (北カリフォルニア) (us-west-1) リージョンのソースレプリカは、アフリカ (ケープタウン) (af-south-1) リージョンと比較して、米国西部 (オレゴン) (us-west-2) リージョンへの `ReplicationLatency` が低くなります。

`ReplicationLatency` の値が上昇している場合、1 つのレプリカからの更新が他のレプリカテーブルにタイムリーに伝播されていないことを示している可能性があります。この場合、アプリケーションの読み込みおよび書き込みアクティビティを別の AWS リージョンに一時的にリダイレクトすることができます。

マルチリージョンの強力な整合性 (MRSC) 用に設定されたグローバルテーブルは、`ReplicationLatency` メトリクスを発行しません。

## フォールトインジェクションテスト
<a name="fault-injection-testing"></a>

MREC と MRSC のグローバルテーブルはどちらも、制御されたフォールトインジェクション実験を実行してアプリケーションの耐障害性を向上させるためのフルマネージドサービスである [AWS Fault Injection Service](https://docs.aws.amazon.com/resilience-hub/latest/userguide/testing.html) (AWS FIS) と統合されています。AWS FIS を使用すると、次のことができます。
+ 特定の障害シナリオを定義する実験テンプレートを作成します。
+ アプリケーションの耐障害性を検証するため、リージョンの分離 (つまり、選択したレプリカとのレプリケーションを一時停止すること) をシミュレートして障害を注入し、エラー処理、復旧メカニズム、1 つの AWS リージョンで中断が発生した場合のマルチリージョントラフィックシフトの動作をテストします。

例えば、米国東部 (バージニア北部)、米国東部 (オハイオ)、米国西部 (オレゴン) にレプリカがあるグローバルテーブルでは、米国東部 (バージニア北部) と米国西部 (オレゴン) が通常のオペレーションを継続している間に、米国東部 (オハイオ) で実験を実行してリージョンの分離をテストできます。この制御されたテストは、本番稼働用ワークロードに影響を与える前に潜在的な問題を特定して解決するのに役立ちます。

AWS FIS でサポートされているアクションの完全なリストについては、「*AWS FIS ユーザーガイド*」の「[アクションターゲット](https://docs.aws.amazon.com/fis/latest/userguide/action-sequence.html#action-targets)」を参照してください。また、リージョン間の DynamoDB レプリケーションを一時停止するには、「[クロスリージョン接続](https://docs.aws.amazon.com/fis/latest/userguide/cross-region-scenario.html)」を参照してください。

AWS FIS で使用できる Amazon DynamoDB グローバルテーブルアクションの詳細については、「*AWS FIS ユーザーガイド*」の「[DynamoDB グローバルテーブルアクションリファレンス](https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html#dynamodb-actions-reference)」を参照してください。

フォールトインジェクション実験の実行を開始するには、「AWS FIS ユーザーガイド」の「[AWS FIS 実験の計画](https://docs.aws.amazon.com/fis/latest/userguide/getting-started-planning.html)」を参照してください。

**注記**  
MRSC での AWS FIS 実験中は、結果整合性のある読み込みが許可されますが、MREC と同様に請求モードの変更やテーブルスループットの設定などのテーブル設定の更新は許可されません。エラーコードの詳細については、CloudWatch メトリクス [`FaultInjectionServiceInducedErrors`](metrics-dimensions.md#FaultInjectionServiceInducedErrors) を確認してください。

## 有効期限 (TTL)
<a name="global-tables-ttl"></a>

MREC 用に設定されたグローバルテーブルは[有効期限](TTL.md) (TTL) 削除の設定をサポートしています。TTL 設定は、グローバルテーブル内のすべてのレプリカに対して自動的に同期されます。TTL がリージョン内のレプリカから項目を削除すると、削除はグローバルテーブル内の他のすべてのレプリカにレプリケートされます。TTL は書き込み容量を消費しないため、削除が発生したリージョンでは TTL 削除に対して課金されません。ただし、グローバルテーブルのレプリカが存在する他のリージョンでレプリケートされた削除に対しては課金されます。

TTL 削除レプリケーションは、削除がレプリケートされるレプリカの書き込み容量を消費します。プロビジョンドキャパシティ用に設定されたレプリカは、書き込みスループットと TTL 削除スループットの組み合わせがプロビジョンド書き込みキャパシティを超える場合、リクエストをスロットリングすることがあります。

マルチリージョンの強力な整合性 (MRSC) 用に設定されたグローバルテーブルは、有効期限 (TTL) 削除の設定をサポートしていません。

## Streams
<a name="global-tables-streams"></a>

マルチリージョンの結果整合性 (MREC) 用に設定されたグローバルテーブルは、レプリカテーブルの [DynamoDB Stream](Streams.md) からこれらの変更を読み取り、その変更を他のすべてのレプリカテーブルに適用することで、変更をレプリケートします。したがって、Streams は MREC グローバルテーブル内のすべてのレプリカでデフォルトで有効になっており、それらのレプリカで無効にすることはできません。MREC レプリケーションプロセスでは、短期間に複数の変更を 1 つのレプリケートされた書き込みに結合する場合があり、各レプリカの Stream にわずかに異なるレコードが含まれる場合があります。MREC レプリカの Streams レコードは常に項目ごとに順序付けられますが、項目間の順序はレプリカによって異なる場合があります。

マルチリージョンの強力な整合性 (MRSC) 用に設定されたグローバルテーブルは、レプリケーションに DynamoDB Streams を使用しないため、MRSC レプリカでは Streams はデフォルトで有効になっていません。MRSC レプリカで Streams を有効にできます。MRSC レプリカの Streams レコードは、Stream レコードの順序付けを含め、すべてのレプリカで同じです。

グローバルテーブル内の他のリージョンではなく、特定のリージョンで発生した変更について Streams レコードを処理するアプリケーションを作成する場合は、各項目にその項目の変更が発生したリージョンを定義する属性を追加できます。この属性を使用して、特定のリージョンの変更に対してのみ Lambda 関数を呼び出す Lambda イベントフィルターの使用など、他のリージョンで発生した変更について Streams レコードをフィルタリングできます。

## トランザクション
<a name="global-tables-transactions"></a>

MREC 用に設定されたグローバルテーブルでは、DynamoDB トランザクションオペレーション ([https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html) および [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html)) は、操作が呼び出されたリージョン内でのみアトミックです。トランザクション書き込みはリージョン間でユニットとしてレプリケートされません。つまり、特定の時点で、トランザクション内の書き込みの一部のみが、他のレプリカでの読み取り操作によって返される可能性があります。

例えば、米国東部 (オハイオ) リージョンと米国西部 (オレゴン) リージョンにレプリカを持つグローバルテーブルがある場合、米国東部 (オハイオ) リージョンで `TransactWriteItems` オペレーションを実行すると、変更がレプリケートされたときに米国西部 (オレゴン) では部分的に完了したトランザクションが観察されることがあります。変更は、ソースリージョンでコミットされた場合にのみ、他のリージョンにレプリケートされます。

マルチリージョンの強力な整合性 (MRSC) 用に設定されたグローバルテーブルはトランザクションオペレーションをサポートしておらず、これらのオペレーションが MRSC レプリカで呼び出されるとエラーが返されます。

## 読み取りおよび書き込みスループット
<a name="V2globaltables_HowItWorks.Throughput"></a>

### プロビジョニングモード
<a name="gt_throughput.provisioned"></a>

レプリケーションは書き込み容量を消費します。プロビジョンドキャパシティ用に設定されたレプリカは、アプリケーションの書き込みスループットとレプリケーションスループットの組み合わせがプロビジョンド書き込みキャパシティを超えると、リクエストをスロットリングすることがあります。プロビジョニングモードを使用するグローバルテーブルの場合、読み取り容量と書き込み容量の両方の自動スケーリング設定がレプリカ間で同期されます。

レプリカレベルで [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ProvisionedThroughputOverride.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ProvisionedThroughputOverride.html) パラメータを使用して、グローバルテーブル内の各レプリカの読み取り容量設定を個別に設定できます。デフォルトでは、プロビジョニングされた読み取り容量への変更は、グローバルテーブル内のすべてのレプリカに適用されます。グローバルテーブルに新しいレプリカを追加する場合、レプリカレベルのオーバーライドが明示的に指定されていない限り、ソーステーブルまたはレプリカの読み取り容量が初期値として使用されます。

### オンデマンドモード
<a name="gt_throughput.on-demand"></a>

オンデマンドモードに設定されたグローバルテーブルの場合、書き込み容量はすべてのレプリカ間で自動的に同期されます。DynamoDB はトラフィックに基づいて容量を自動的に調整するため、レプリカ固有の読み取りまたは書き込み容量設定を管理する必要はありません。

## 設定の同期
<a name="V2globaltables_HowItWorks.setting-synchronization"></a>

DynamoDB グローバルテーブルの設定は、テーブルの動作とレプリケーションのさまざまな側面を制御する設定パラメータです。これらの設定は DynamoDB コントロールプレーン API を通じて管理され、グローバルテーブルを作成または変更するときに設定できます。グローバルテーブルは、すべてのレプリカで特定の設定を自動的に同期して一貫性を維持し、リージョン固有の最適化に柔軟性を持たせます。どの設定が同期され、どのように動作するかを理解することは、グローバルテーブルを効果的に設定するのに役立ちます。設定は、レプリカ間でどのように同期されるかに基づいて、3 つの主要なカテゴリに分類されます。

次の設定は常にグローバルテーブルのレプリカ間で同期されます。
+ キャパシティモード (プロビジョンドキャパシティまたはオンデマンド)
+ テーブルのプロビジョニングされた書き込み容量
+ テーブル書き込みの自動スケーリング
+ キースキーマの属性定義
+ グローバルセカンダリインデックス (GSI) 定義
+ GSI のプロビジョニングされた書き込みキャパシティ
+ GSI の書き込み自動スケーリング
+ サーバー側の暗号化 (SSE)
+ MREC モードでの Streams 定義
+ 有効期限 (TTL)
+ ウォームスループット
+ オンデマンドの最大書き込みスループット

以下の設定はレプリカ間で同期されますが、レプリカごとに上書きできます。
+ テーブルのプロビジョニングされた読み込みキャパシティ
+ テーブル読み取りの自動スケーリング
+ GSI のプロビジョニングされた読み込み容量キャパシティ
+ GSI の読み取り自動スケーリング
+ テーブルクラス
+ オンデマンドの最大読み取りスループット

**注記**  
上書き可能な設定値は、設定が他のレプリカで変更されると変更されます。例えば、米国東部 (バージニア北部) と米国西部 (オレゴン) にレプリカを持つ MREC グローバルテーブルがあるとします。米国東部 (バージニア北部) レプリカのプロビジョニングされた読み込みスループットは 200 RCU に設定されています。米国西部 (オレゴン) のレプリカでは、プロビジョニングされた読み込みスループットオーバーライドが 100 RCU に設定されています。米国東部 (バージニア北部) レプリカのプロビジョニングされた読み込みスループット設定を 200 RCU から 300 RCU に更新すると、新しいプロビジョニングされた読み込みスループット値が米国西部 (オレゴン) のレプリカにも適用されます。これにより、米国西部 (オレゴン) レプリカのプロビジョニングされた読み込みスループット設定が、オーバーライドされた値である 100 RCU から新しい値である 300 RCU に変更されます。

以下の設定はレプリカ間で同期されません。
+ 削除保護
+ ポイントインタイムリカバリ
+ タグ
+ テーブルの CloudWatch Contributor Insights の有効化
+ GSI の CloudWatch Contributor Insights の有効化
+ Kinesis Data Streams 定義
+ リソースポリシー
+ MRSC モードでの Streams 定義

他のすべての設定はレプリカ間で同期されません。

## DynamoDB Accelerator (DAX)
<a name="V2globaltables_HowItWorks.dax"></a>

グローバルテーブルレプリカへの書き込みは DynamoDB Accelerator (DAX) をバイパスし、DynamoDB を直接更新します。その結果、書き込みが DAX キャッシュを更新しないため、DAX キャッシュが古くなる可能性があります。グローバルテーブルレプリカ用に設定された DAX キャッシュは、キャッシュ TTL の有効期限が切れた場合にのみ更新されます。

## グローバルテーブルの管理に関する考慮事項
<a name="management-considerations"></a>

新しいグローバルテーブルレプリカの追加に使用したテーブルは、新しいレプリカが作成されてから 24 時間が経過するまで削除できません。

グローバルテーブルレプリカを含む AWS リージョンを無効にすると、それらのレプリカは、リージョンが無効になってから 20 時間後に単一リージョンテーブルに永続的に変換されます。

# チュートリアル: グローバルテーブルの作成
<a name="V2globaltables.tutorial"></a>

このセクションでは、任意の整合性モード用に設定された DynamoDB グローバルテーブルを作成するための手順を順を追って説明します。アプリケーションの要件に基づいて、マルチリージョンの結果整合性 (MREC) モードまたはマルチリージョンの強力な整合性 (MRSC) モードのいずれかを選択します。

MREC グローバルテーブルは、書き込みレイテンシーを低くし、AWS リージョン全体で結果整合性を実現します。MRSC グローバルテーブルは、MREC よりも書き込みレイテンシーがわずかに高いリージョン間で強力な整合性のある読み込みを提供します。データ整合性、レイテンシー、可用性に関するアプリケーションのニーズに最適な整合性モードを選択します。

**Topics**
+ [MREC 用に設定されたグローバルテーブルの作成](#V2creategt_mrec)
+ [MRSC 用に設定されたグローバルテーブルの作成](#create-gt-mrsc)

## MREC 用に設定されたグローバルテーブルの作成
<a name="V2creategt_mrec"></a>

このセクションでは、マルチリージョンの結果整合性 (MREC) モードでグローバルテーブルを作成する方法を示します。MREC はグローバルテーブルのデフォルトの整合性モードであり、AWS リージョン全体で非同期レプリケーションによる低レイテンシーの書き込みを提供します。1 つのリージョンの項目に加えられた変更は、通常、1 秒以内に他のすべてのリージョンにレプリケートされます。これにより、MREC は低い書き込みレイテンシーを優先し、異なるリージョンがわずかに異なるバージョンのデータを返す短い期間を許容できるアプリケーションに最適です。

DynamoDB が利用可能な任意の AWS リージョンでレプリカを含む MREC グローバルテーブルを作成し、レプリカをいつでも追加または削除できます。次の例は、複数のリージョンにレプリカを持つ MREC グローバルテーブルを作成する方法を示しています。

### DynamoDB コンソールを使用した MREC グローバルテーブルの作成
<a name="mrec-console"></a>

AWS マネジメントコンソール を使用してグローバルテーブルを作成するには、次の手順に従います。以下の例では、レプリカテーブルを持つグローバルテーブルを米国およびヨーロッパに作成します。

1. AWS マネジメントコンソール にサインインして DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. この例では、ナビゲーションバーのリージョンセレクターから **[米国東部 (オハイオ)]** を選択します。

1. コンソールの左側のナビゲーションペインで、**[テーブル]** を選択します。

1. **[Create Table]** (テーブルの作成) を選択します。

1. **[テーブルの作成]** ページで、次の操作を行います。

   1. **[テーブル名]** に **Music** と入力します。

   1. **[パーティションキー]** に **Artist** と入力します。

   1. **[ソートキー]** に **SongTitle** と入力します。

   1. 他のデフォルトの設定はそのままにして、**[テーブルの作成]** を選択します。

      この新しいテーブルは、新しいグローバルテーブルの最初のレプリカテーブルとして機能します。これは、後で追加する他のレプリカテーブルのプロトタイプです。

1. テーブルがアクティブになった後、次の操作を行います。

   1. テーブルのリストから **[ミュージック]** テーブルを選択します。

   1. **[グローバルテーブル]** タブを選択します。

   1. **レプリカの作成**を選択します。

1. **[利用可能なレプリケーションリージョン]** ドロップダウンリストから、**[米国西部 (オレゴン) us-west-2]** を選択します。

   コンソールは、選択したリージョンに同一名のテーブルが存在しないことを確認します。同一名のテーブルが存在する場合は、そのリージョンで新しいレプリカテーブルを作成する前に既存のテーブルを削除する必要があります。

1. **レプリカの作成**を選択します。これで、米国西部 (オレゴン) us-west-2 リージョンでテーブル作成プロセスが開始されます。

   **[Music]** テーブル (およびその他すべてのレプリカテーブル) の **[グローバルテーブル]** タブに、テーブルが複数のリージョンでレプリケートされたことが示されます。

1. 前のステップを繰り返して別のリージョンを追加しますが、リージョンとして **[欧州 (フランクフルト) eu-central-1]** を選択します。

1. レプリケーションをテストするには、次の操作を行います。

   1. 米国東部 (オハイオ) リージョンでAWS マネジメントコンソールを使用していることを確認します。

   1. **[テーブルアイテムの探索]** を選択します。

   1. **[項目を作成]** を選択します。

   1. **[アーティスト]** に「**item\$11**」、**[曲名]** に「**Song Value 1**」と入力します。

   1. **[項目を作成]** を選択します。

1. 他のリージョンに切り替えてレプリケーションを確認します。

   1. 右上隅のリージョンセレクターから、**[欧州 (フランクフルト)]** を選択します。

   1. **[ミュージック]** テーブルに、作成した項目が含まれていることを確認します。

   1. **[米国西部 (オレゴン)]** で検証を繰り返します。

### AWS CLI または Java を使用した MREC グローバルテーブルの作成
<a name="mrec-cli-java"></a>

------
#### [ CLI ]

次のコード例は、最終的な一貫性を備えたマルチリージョンレプリケーション (MREC) を使用して DynamoDB グローバルテーブルを管理する方法を示しています。
+ マルチリージョンレプリケーション (MREC)を備えたテーブルを作成します。
+ レプリカテーブルの項目を配置および取得します。
+ レプリカを一つずつ削除します。
+ テーブルを削除してクリーンアップします。

**Bash スクリプトを使用した AWS CLI**  
マルチリージョンレプリケーションを備えたテーブルを作成します。  

```
# Step 1: Create a new table (MusicTable) in US East (Ohio), with DynamoDB Streams enabled (NEW_AND_OLD_IMAGES)
aws dynamodb create-table \
    --table-name MusicTable \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST \
    --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
    --region us-east-2

# Step 2: Create an identical MusicTable table in US East (N. Virginia)
aws dynamodb update-table --table-name MusicTable --cli-input-json \
'{
  "ReplicaUpdates":
  [
    {
      "Create": {
        "RegionName": "us-east-1"
      }
    }
  ]
}' \
--region us-east-2

# Step 3: Create a table in Europe (Ireland)
aws dynamodb update-table --table-name MusicTable --cli-input-json \
'{
  "ReplicaUpdates":
  [
    {
      "Create": {
        "RegionName": "eu-west-1"
      }
    }
  ]
}' \
--region us-east-2
```
マルチリージョンテーブルについて説明します。  

```
# Step 4: View the list of replicas created using describe-table
aws dynamodb describe-table \
    --table-name MusicTable \
    --region us-east-2 \
    --query 'Table.{TableName:TableName,TableStatus:TableStatus,MultiRegionConsistency:MultiRegionConsistency,Replicas:Replicas[*].{Region:RegionName,Status:ReplicaStatus}}'
```
レプリカテーブルに項目を配置します。  

```
# Step 5: To verify that replication is working, add a new item to the Music table in US East (Ohio)
aws dynamodb put-item \
    --table-name MusicTable \
    --item '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
    --region us-east-2
```
レプリカテーブルから項目を取得します。  

```
# Step 6: Wait for a few seconds, and then check to see whether the item has been 
# successfully replicated to US East (N. Virginia) and Europe (Ireland)
aws dynamodb get-item \
    --table-name MusicTable \
    --key '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
    --region us-east-1

aws dynamodb get-item \
    --table-name MusicTable \
    --key '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
    --region eu-west-1
```
レプリカを削除します。  

```
# Step 7: Delete the replica table in Europe (Ireland) Region
aws dynamodb update-table --table-name MusicTable --cli-input-json \
'{
  "ReplicaUpdates":
  [
    {
      "Delete": {
        "RegionName": "eu-west-1"
      }
    }
  ]
}' \
--region us-east-2

# Delete the replica table in US East (N. Virginia) Region
aws dynamodb update-table --table-name MusicTable --cli-input-json \
'{
  "ReplicaUpdates":
  [
    {
      "Delete": {
        "RegionName": "us-east-1"
      }
    }
  ]
}' \
--region us-east-2
```
テーブルを削除してクリーンアップします。  

```
# Clean up: Delete the primary table
aws dynamodb delete-table --table-name MusicTable --region us-east-2

echo "Global table demonstration complete."
```
+ API の詳細については、*AWS CLI コマンドリファレンス*の以下のトピックを参照してください。
  + [CreateTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/CreateTable)
  + [DeleteTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/DeleteTable)
  + [DescribeTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/DescribeTable)
  + [GetItem](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/GetItem)
  + [PutItem](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/PutItem)
  + [UpdateTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/UpdateTable)

------
#### [ Java ]

次のコード例は、複数のリージョンにまたがるレプリカを含む DynamoDB グローバルテーブルを作成して管理する方法を示しています。
+ グローバルセカンダリインデックスおよび DynamoDB Streams を含むテーブルを作成します。
+ 異なるリージョンにレプリカを追加して、グローバルテーブルを作成します。
+ グローバルテーブルからレプリカを削除します。
+ テスト項目を追加して、リージョン間のレプリケーションを検証します。
+ グローバルテーブル設定とレプリカのステータスについて説明します。

**SDK for Java 2.x**  
AWS SDK for Java 2.x を使用して、グローバルセカンダリインデックスおよび DynamoDB Streams を含むテーブルを作成します。  

```
    public static CreateTableResponse createTableWithGSI(
        final DynamoDbClient dynamoDbClient, final String tableName, final String indexName) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (indexName == null || indexName.trim().isEmpty()) {
            throw new IllegalArgumentException("Index name cannot be null or empty");
        }

        try {
            LOGGER.info("Creating table: " + tableName + " with GSI: " + indexName);

            CreateTableRequest createTableRequest = CreateTableRequest.builder()
                .tableName(tableName)
                .attributeDefinitions(
                    AttributeDefinition.builder()
                        .attributeName("Artist")
                        .attributeType(ScalarAttributeType.S)
                        .build(),
                    AttributeDefinition.builder()
                        .attributeName("SongTitle")
                        .attributeType(ScalarAttributeType.S)
                        .build())
                .keySchema(
                    KeySchemaElement.builder()
                        .attributeName("Artist")
                        .keyType(KeyType.HASH)
                        .build(),
                    KeySchemaElement.builder()
                        .attributeName("SongTitle")
                        .keyType(KeyType.RANGE)
                        .build())
                .billingMode(BillingMode.PAY_PER_REQUEST)
                .globalSecondaryIndexes(GlobalSecondaryIndex.builder()
                    .indexName(indexName)
                    .keySchema(KeySchemaElement.builder()
                        .attributeName("SongTitle")
                        .keyType(KeyType.HASH)
                        .build())
                    .projection(
                        Projection.builder().projectionType(ProjectionType.ALL).build())
                    .build())
                .streamSpecification(StreamSpecification.builder()
                    .streamEnabled(true)
                    .streamViewType(StreamViewType.NEW_AND_OLD_IMAGES)
                    .build())
                .build();

            CreateTableResponse response = dynamoDbClient.createTable(createTableRequest);
            LOGGER.info("Table creation initiated. Status: "
                + response.tableDescription().tableStatus());

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to create table: " + tableName + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用して、テーブルがアクティブになるまで待ちます。  

```
    public static void waitForTableActive(final DynamoDbClient dynamoDbClient, final String tableName) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }

        try {
            LOGGER.info("Waiting for table to become active: " + tableName);

            try (DynamoDbWaiter waiter =
                DynamoDbWaiter.builder().client(dynamoDbClient).build()) {
                DescribeTableRequest request =
                    DescribeTableRequest.builder().tableName(tableName).build();

                waiter.waitUntilTableExists(request);
                LOGGER.info("Table is now active: " + tableName);
            }

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to wait for table to become active: " + tableName + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用して、レプリカを追加して、グローバルテーブルを作成または拡張します。  

```
    public static UpdateTableResponse addReplica(
        final DynamoDbClient dynamoDbClient,
        final String tableName,
        final Region replicaRegion,
        final String indexName,
        final Long readCapacity) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (replicaRegion == null) {
            throw new IllegalArgumentException("Replica region cannot be null");
        }
        if (indexName == null || indexName.trim().isEmpty()) {
            throw new IllegalArgumentException("Index name cannot be null or empty");
        }
        if (readCapacity == null || readCapacity <= 0) {
            throw new IllegalArgumentException("Read capacity must be a positive number");
        }

        try {
            LOGGER.info("Adding replica in region: " + replicaRegion.id() + " for table: " + tableName);

            // Create a ReplicationGroupUpdate for adding a replica
            ReplicationGroupUpdate replicationGroupUpdate = ReplicationGroupUpdate.builder()
                .create(builder -> builder.regionName(replicaRegion.id())
                    .globalSecondaryIndexes(ReplicaGlobalSecondaryIndex.builder()
                        .indexName(indexName)
                        .provisionedThroughputOverride(ProvisionedThroughputOverride.builder()
                            .readCapacityUnits(readCapacity)
                            .build())
                        .build())
                    .build())
                .build();

            UpdateTableRequest updateTableRequest = UpdateTableRequest.builder()
                .tableName(tableName)
                .replicaUpdates(replicationGroupUpdate)
                .build();

            UpdateTableResponse response = dynamoDbClient.updateTable(updateTableRequest);
            LOGGER.info("Replica addition initiated in region: " + replicaRegion.id());

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to add replica in region: " + replicaRegion.id() + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用してグローバルテーブルからレプリカを削除します。  

```
    public static UpdateTableResponse removeReplica(
        final DynamoDbClient dynamoDbClient, final String tableName, final Region replicaRegion) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (replicaRegion == null) {
            throw new IllegalArgumentException("Replica region cannot be null");
        }

        try {
            LOGGER.info("Removing replica in region: " + replicaRegion.id() + " for table: " + tableName);

            // Create a ReplicationGroupUpdate for removing a replica
            ReplicationGroupUpdate replicationGroupUpdate = ReplicationGroupUpdate.builder()
                .delete(builder -> builder.regionName(replicaRegion.id()).build())
                .build();

            UpdateTableRequest updateTableRequest = UpdateTableRequest.builder()
                .tableName(tableName)
                .replicaUpdates(replicationGroupUpdate)
                .build();

            UpdateTableResponse response = dynamoDbClient.updateTable(updateTableRequest);
            LOGGER.info("Replica removal initiated in region: " + replicaRegion.id());

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to remove replica in region: " + replicaRegion.id() + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用してテスト項目を追加して、レプリケーションを検証します。  

```
    public static PutItemResponse putTestItem(
        final DynamoDbClient dynamoDbClient, final String tableName, final String artist, final String songTitle) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (artist == null || artist.trim().isEmpty()) {
            throw new IllegalArgumentException("Artist cannot be null or empty");
        }
        if (songTitle == null || songTitle.trim().isEmpty()) {
            throw new IllegalArgumentException("Song title cannot be null or empty");
        }

        try {
            LOGGER.info("Adding test item to table: " + tableName);

            Map<String, software.amazon.awssdk.services.dynamodb.model.AttributeValue> item = new HashMap<>();
            item.put(
                "Artist",
                software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder()
                    .s(artist)
                    .build());
            item.put(
                "SongTitle",
                software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder()
                    .s(songTitle)
                    .build());

            PutItemRequest putItemRequest =
                PutItemRequest.builder().tableName(tableName).item(item).build();

            PutItemResponse response = dynamoDbClient.putItem(putItemRequest);
            LOGGER.info("Test item added successfully");

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to add test item to table: " + tableName + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用して、グローバルテーブル設定とレプリカを記述します。  

```
    public static DescribeTableResponse describeTable(final DynamoDbClient dynamoDbClient, final String tableName) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }

        try {
            LOGGER.info("Describing table: " + tableName);

            DescribeTableRequest request =
                DescribeTableRequest.builder().tableName(tableName).build();

            DescribeTableResponse response = dynamoDbClient.describeTable(request);

            LOGGER.info("Table status: " + response.table().tableStatus());
            if (response.table().replicas() != null
                && !response.table().replicas().isEmpty()) {
                LOGGER.info("Number of replicas: " + response.table().replicas().size());
                response.table()
                    .replicas()
                    .forEach(replica -> LOGGER.info(
                        "Replica region: " + replica.regionName() + ", Status: " + replica.replicaStatus()));
            }

            return response;

        } catch (ResourceNotFoundException e) {
            LOGGER.severe("Table not found: " + tableName + " - " + e.getMessage());
            throw e;
        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to describe table: " + tableName + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用したグローバルテーブル操作の完全な例。  

```
    public static void exampleUsage(final Region sourceRegion, final Region replicaRegion) {

        String tableName = "Music";
        String indexName = "SongTitleIndex";
        Long readCapacity = 15L;

        // Create DynamoDB client for the source region
        try (DynamoDbClient dynamoDbClient =
            DynamoDbClient.builder().region(sourceRegion).build()) {

            try {
                // Step 1: Create the initial table with GSI and streams
                LOGGER.info("Step 1: Creating table in source region: " + sourceRegion.id());
                createTableWithGSI(dynamoDbClient, tableName, indexName);

                // Step 2: Wait for table to become active
                LOGGER.info("Step 2: Waiting for table to become active");
                waitForTableActive(dynamoDbClient, tableName);

                // Step 3: Add replica in destination region
                LOGGER.info("Step 3: Adding replica in region: " + replicaRegion.id());
                addReplica(dynamoDbClient, tableName, replicaRegion, indexName, readCapacity);

                // Step 4: Wait a moment for replica creation to start
                Thread.sleep(5000);

                // Step 5: Describe table to view replica information
                LOGGER.info("Step 5: Describing table to view replicas");
                describeTable(dynamoDbClient, tableName);

                // Step 6: Add a test item to verify replication
                LOGGER.info("Step 6: Adding test item to verify replication");
                putTestItem(dynamoDbClient, tableName, "TestArtist", "TestSong");

                LOGGER.info("Global table setup completed successfully!");
                LOGGER.info("You can verify replication by checking the item in region: " + replicaRegion.id());

                // Step 7: Remove replica and clean up table
                LOGGER.info("Step 7: Removing replica from region: " + replicaRegion.id());
                removeReplica(dynamoDbClient, tableName, replicaRegion);
                DeleteTableResponse deleteTableResponse = dynamoDbClient.deleteTable(
                    DeleteTableRequest.builder().tableName(tableName).build());
                LOGGER.info("MREC global table demonstration completed successfully!");

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Thread was interrupted", e);
            } catch (DynamoDbException e) {
                LOGGER.severe("DynamoDB operation failed: " + e.getMessage());
                throw e;
            }
        }
    }
```
+ API の詳細については、「*AWS SDK for Java 2.x API リファレンス*」の以下のトピックを参照してください。
  + [CreateTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/CreateTable)
  + [DescribeTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/DescribeTable)
  + [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem)
  + [UpdateTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateTable)

------

## MRSC 用に設定されたグローバルテーブルの作成
<a name="create-gt-mrsc"></a>

このセクションでは、マルチリージョンの強力な整合性 (MRSC) グローバルテーブルを作成する方法について説明します。MRSC グローバルテーブルは、リージョン間で項目の変更を同期的にレプリケートし、レプリカに対する強力な整合性のある読み込みオペレーションが常に項目の最新バージョンを返すようにします。単一リージョンテーブルを MRSC グローバルテーブルに変換する場合は、テーブルが空であることを確認する必要があります。単一リージョンテーブルを既存の項目を持つ MRSC グローバルテーブルに変換することはサポートされていません。変換プロセス中にデータがテーブルに書き込まれないよう確認してください。

MRSC グローバルテーブルは、3 つのレプリカ、または 2 つのレプリカと 1 つの監視で設定できます。MRSC グローバルテーブルを作成するときに、レプリカとオプションの監視がデプロイされるリージョンを選択します。次の例では、米国東部 (バージニア北部) および米国東部 (オハイオ) リージョンにレプリカを持つ MRSC グローバルテーブルを作成し、米国西部 (オレゴン) リージョンに監視を配置します。

**注記**  
グローバルテーブルを作成する前に、Service Quota のスループット制限がすべてのターゲットリージョンで一貫していることを確認してください。これは、グローバルテーブルの作成に必要です。グローバルテーブルのスループット制限の詳細については、「[グローバルテーブルのクォータ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ServiceQuotas.html#gt-limits-throughput)」を参照してください。

### DynamoDB コンソールを使用した MRSC グローバルテーブルの作成
<a name="mrsc_console"></a>

AWS マネジメントコンソール を使用してグローバルテーブルを作成するには、次の手順に従います。

1. AWS マネジメントコンソール にサインインして DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. ナビゲーションバーのリージョンセレクターで、MRSC を使用したグローバルテーブルが[サポートされている](V2globaltables_HowItWorks.md#V2globaltables_HowItWorks.consistency-modes)リージョン (**us-east-2** など) を選択します。

1. ナビゲーションペインで、**[Table]** (テーブル) を選択します。

1. **[テーブルの作成]** を選択します。

1. **[テーブルの作成]** ページで、次の操作を行います。

   1. **[テーブル名]** に「**Music**」と入力します。

   1. **[パーティションキー]** に「**Artist**」と入力し、デフォルトの **[文字列]** タイプのままにします。

   1. **[ソートキー]** に「**SongTitle**」と入力し、デフォルトの **[文字列]** タイプのままにします。

   1. 他のデフォルトの設定はそのままにして、**[テーブルの作成]** を選択します

      この新しいテーブルは、新しいグローバルテーブルの最初のレプリカテーブルとして機能します。これは、後で追加する他のレプリカテーブルのプロトタイプです。

1. テーブルがアクティブになるまで待ってから、テーブルリストから選択します。

1. **[グローバルテーブル]** タブを選択して、**[レプリカを作成]** を選択します。

1. **[レプリカの作成]** ページで、次の操作を行います。

   1. **[マルチリージョン整合性]** で、**[強力な整合性]** を選択します。

   1. **[レプリケーションリージョン 1]** で、「**US East (N. Virginia) us-east-1**」を選択します。

   1. **[レプリケーションリージョン 2]** で、「**US West (Oregon) us-west-2**」を選択します。

   1. 米国西部 (オレゴン) リージョンの **[監視として設定する]** を確認します。

   1. **[レプリカの作成]** を選択します。

1. レプリカと監視の作成プロセスが完了するまで待ちます。テーブルが使用可能になると、レプリカのステータスは **[アクティブ]** と表示されます。

### AWS CLI または Java を使用した MRSC グローバルテーブルの作成
<a name="mrsc-cli-java"></a>

開始する前に、監視リージョンを持つ MRSC グローバルテーブルを作成するために必要なアクセス許可が IAM プリンシパルにあることを確認してください。

次のサンプル IAM ポリシーでは、米国東部 (オハイオ) に DynamoDB テーブル (`MusicTable`) を作成し、米国東部 (バージニア北部) にレプリカ、米国西部 (オレゴン) に監視リージョンを作成できます。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:CreateTable",
                "dynamodb:CreateTableReplica",
                "dynamodb:CreateGlobalTableWitness",
                "dynamodb:DescribeTable",
                "dynamodb:UpdateTable",
                "dynamodb:DeleteTable",
                "dynamodb:DeleteTableReplica",
                "dynamodb:DeleteGlobalTableWitness",
                "dynamodb:Scan",
                "dynamodb:Query",
                "dynamodb:UpdateItem",
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:DeleteItem",
                "dynamodb:BatchWriteItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:us-east-1:123456789012:table/MusicTable",
                "arn:aws:dynamodb:us-east-2:123456789012:table/MusicTable",
                "arn:aws:dynamodb:us-west-2:123456789012:table/MusicTable"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::*:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName": "replication.dynamodb.amazonaws.com"
                }
            }
        }
    ]
}
```

------

次のコード例は、マルチリージョンの強力な整合性 (MRSC) を備えた DynamoDB グローバルテーブルを作成および管理する方法を示しています。
+ マルチリージョンの強力な整合性を備えたテーブルを作成します。
+ MRSC 設定とレプリカのステータスを確認します。
+ 即時読み取りでリージョン間の強力な整合性をテストします。
+ MRSC 保証を使用して条件付き書き込みを実行します。
+ MRSC グローバルテーブルリソースをクリーンアップします。

------
#### [ Bash ]

**Bash スクリプトを使用した AWS CLI**  
マルチリージョンの強力な整合性を備えたテーブルを作成します。  

```
# Step 1: Create a new table in us-east-2 (primary region for MRSC)
# Note: Table must be empty when enabling MRSC
aws dynamodb create-table \
    --table-name MusicTable \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST \
    --region us-east-2

# Wait for table to become active
aws dynamodb wait table-exists --table-name MusicTable --region us-east-2

# Step 2: Add replica and witness with Multi-Region Strong Consistency
# MRSC requires exactly three replicas in supported regions
aws dynamodb update-table \
    --table-name MusicTable \
    --replica-updates '[{"Create": {"RegionName": "us-east-1"}}]' \
    --global-table-witness-updates '[{"Create": {"RegionName": "us-west-2"}}]' \
    --multi-region-consistency STRONG \
    --region us-east-2
```
MRSC 設定とレプリカのステータスを確認します。  

```
# Verify the global table configuration and MRSC setting
aws dynamodb describe-table \
    --table-name MusicTable \
    --region us-east-2 \
    --query 'Table.{TableName:TableName,TableStatus:TableStatus,MultiRegionConsistency:MultiRegionConsistency,Replicas:Replicas[*],GlobalTableWitnesses:GlobalTableWitnesses[*].{Region:RegionName,Status:ReplicaStatus}}'
```
リージョン間の即時読み取りの強力な整合性をテストします。  

```
# Write an item to the primary region
aws dynamodb put-item \
    --table-name MusicTable \
    --item '{"Artist": {"S":"The Beatles"},"SongTitle": {"S":"Hey Jude"},"Album": {"S":"The Beatles 1967-1970"},"Year": {"N":"1968"}}' \
    --region us-east-2

# Read the item from replica region to verify strong consistency (cannot read or write to witness)
# No wait time needed - MRSC provides immediate consistency
echo "Reading from us-east-1 (immediate consistency):"
aws dynamodb get-item \
    --table-name MusicTable \
    --key '{"Artist": {"S":"The Beatles"},"SongTitle": {"S":"Hey Jude"}}' \
    --consistent-read \
    --region us-east-1
```
MRSC 保証を使用して条件付き書き込みを実行します。  

```
# Perform a conditional update from a different region
# This demonstrates that conditions work consistently across all regions
aws dynamodb update-item \
    --table-name MusicTable \
    --key '{"Artist": {"S":"The Beatles"},"SongTitle": {"S":"Hey Jude"}}' \
    --update-expression "SET #rating = :rating" \
    --condition-expression "attribute_exists(Artist)" \
    --expression-attribute-names '{"#rating": "Rating"}' \
    --expression-attribute-values '{":rating": {"N":"5"}}' \
    --region us-east-1
```
MRSC グローバルテーブルリソースをクリーンアップします。  

```
# Remove replica tables (must be done before deleting the primary table)
aws dynamodb update-table \
    --table-name MusicTable \
    --replica-updates '[{"Delete": {"RegionName": "us-east-1"}}]' \
    --global-table-witness-updates '[{"Delete": {"RegionName": "us-west-2"}}]' \
    --region us-east-2

# Wait for replicas to be deleted
echo "Waiting for replicas to be deleted..."
sleep 30

# Delete the primary table
aws dynamodb delete-table \
    --table-name MusicTable \
    --region us-east-2
```
+ API の詳細については、*AWS CLI コマンドリファレンス*の以下のトピックを参照してください。
  + [CreateTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/CreateTable)
  + [DeleteTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/DeleteTable)
  + [DescribeTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/DescribeTable)
  + [GetItem](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/GetItem)
  + [PutItem](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/PutItem)
  + [UpdateItem](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/UpdateItem)
  + [UpdateTable](https://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/UpdateTable)

------
#### [ Java ]

**SDK for Java 2.x**  
MRSC 変換の準備ができたリージョンテーブルを AWS SDK for Java 2.x を使用して作成します。  

```
    public static CreateTableResponse createRegionalTable(final DynamoDbClient dynamoDbClient, final String tableName) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }

        try {
            LOGGER.info("Creating regional table: " + tableName + " (must be empty for MRSC)");

            CreateTableRequest createTableRequest = CreateTableRequest.builder()
                .tableName(tableName)
                .attributeDefinitions(
                    AttributeDefinition.builder()
                        .attributeName("Artist")
                        .attributeType(ScalarAttributeType.S)
                        .build(),
                    AttributeDefinition.builder()
                        .attributeName("SongTitle")
                        .attributeType(ScalarAttributeType.S)
                        .build())
                .keySchema(
                    KeySchemaElement.builder()
                        .attributeName("Artist")
                        .keyType(KeyType.HASH)
                        .build(),
                    KeySchemaElement.builder()
                        .attributeName("SongTitle")
                        .keyType(KeyType.RANGE)
                        .build())
                .billingMode(BillingMode.PAY_PER_REQUEST)
                .build();

            CreateTableResponse response = dynamoDbClient.createTable(createTableRequest);
            LOGGER.info("Regional table creation initiated. Status: "
                + response.tableDescription().tableStatus());

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to create regional table: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to create regional table: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、リージョンテーブルをレプリカと監視を備えた MRSC に変換します。  

```
    public static UpdateTableResponse convertToMRSCWithWitness(
        final DynamoDbClient dynamoDbClient,
        final String tableName,
        final Region replicaRegion,
        final Region witnessRegion) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (replicaRegion == null) {
            throw new IllegalArgumentException("Replica region cannot be null");
        }
        if (witnessRegion == null) {
            throw new IllegalArgumentException("Witness region cannot be null");
        }

        try {
            LOGGER.info("Converting table to MRSC with replica in " + replicaRegion.id() + " and witness in "
                + witnessRegion.id());

            // Create replica update using ReplicationGroupUpdate
            ReplicationGroupUpdate replicaUpdate = ReplicationGroupUpdate.builder()
                .create(CreateReplicationGroupMemberAction.builder()
                    .regionName(replicaRegion.id())
                    .build())
                .build();

            // Create witness update
            GlobalTableWitnessGroupUpdate witnessUpdate = GlobalTableWitnessGroupUpdate.builder()
                .create(CreateGlobalTableWitnessGroupMemberAction.builder()
                    .regionName(witnessRegion.id())
                    .build())
                .build();

            UpdateTableRequest updateTableRequest = UpdateTableRequest.builder()
                .tableName(tableName)
                .replicaUpdates(List.of(replicaUpdate))
                .globalTableWitnessUpdates(List.of(witnessUpdate))
                .multiRegionConsistency(MultiRegionConsistency.STRONG)
                .build();

            UpdateTableResponse response = dynamoDbClient.updateTable(updateTableRequest);
            LOGGER.info("MRSC conversion initiated. Status: "
                + response.tableDescription().tableStatus());
            LOGGER.info("UpdateTableResponse full object: " + response);
            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to convert table to MRSC: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to convert table to MRSC: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC のグローバルテーブル設定を記述します。  

```
    public static DescribeTableResponse describeMRSCTable(final DynamoDbClient dynamoDbClient, final String tableName) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }

        try {
            LOGGER.info("Describing MRSC global table: " + tableName);

            DescribeTableRequest request =
                DescribeTableRequest.builder().tableName(tableName).build();

            DescribeTableResponse response = dynamoDbClient.describeTable(request);

            LOGGER.info("Table status: " + response.table().tableStatus());
            LOGGER.info("Multi-region consistency: " + response.table().multiRegionConsistency());

            if (response.table().replicas() != null
                && !response.table().replicas().isEmpty()) {
                LOGGER.info("Number of replicas: " + response.table().replicas().size());
                response.table()
                    .replicas()
                    .forEach(replica -> LOGGER.info(
                        "Replica region: " + replica.regionName() + ", Status: " + replica.replicaStatus()));
            }

            if (response.table().globalTableWitnesses() != null
                && !response.table().globalTableWitnesses().isEmpty()) {
                LOGGER.info("Number of witnesses: "
                    + response.table().globalTableWitnesses().size());
                response.table()
                    .globalTableWitnesses()
                    .forEach(witness -> LOGGER.info(
                        "Witness region: " + witness.regionName() + ", Status: " + witness.witnessStatus()));
            }

            return response;

        } catch (ResourceNotFoundException e) {
            LOGGER.severe("Table not found: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Table not found: " + tableName)
                .cause(e)
                .build();
        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to describe table: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to describe table: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC の強力な整合性を検証するためのテスト項目を追加します。  

```
    public static PutItemResponse putTestItem(
        final DynamoDbClient dynamoDbClient,
        final String tableName,
        final String artist,
        final String songTitle,
        final String album,
        final String year) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (artist == null || artist.trim().isEmpty()) {
            throw new IllegalArgumentException("Artist cannot be null or empty");
        }
        if (songTitle == null || songTitle.trim().isEmpty()) {
            throw new IllegalArgumentException("Song title cannot be null or empty");
        }

        try {
            LOGGER.info("Adding test item to MRSC global table: " + tableName);

            Map<String, AttributeValue> item = new HashMap<>();
            item.put("Artist", AttributeValue.builder().s(artist).build());
            item.put("SongTitle", AttributeValue.builder().s(songTitle).build());

            if (album != null && !album.trim().isEmpty()) {
                item.put("Album", AttributeValue.builder().s(album).build());
            }
            if (year != null && !year.trim().isEmpty()) {
                item.put("Year", AttributeValue.builder().n(year).build());
            }

            PutItemRequest putItemRequest =
                PutItemRequest.builder().tableName(tableName).item(item).build();

            PutItemResponse response = dynamoDbClient.putItem(putItemRequest);
            LOGGER.info("Test item added successfully with strong consistency");

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to add test item to table: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to add test item to table: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC レプリカから一貫した読み取りを持つ項目を読み取ります。  

```
    public static GetItemResponse getItemWithConsistentRead(
        final DynamoDbClient dynamoDbClient, final String tableName, final String artist, final String songTitle) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (artist == null || artist.trim().isEmpty()) {
            throw new IllegalArgumentException("Artist cannot be null or empty");
        }
        if (songTitle == null || songTitle.trim().isEmpty()) {
            throw new IllegalArgumentException("Song title cannot be null or empty");
        }

        try {
            LOGGER.info("Reading item from MRSC global table with consistent read: " + tableName);

            Map<String, AttributeValue> key = new HashMap<>();
            key.put("Artist", AttributeValue.builder().s(artist).build());
            key.put("SongTitle", AttributeValue.builder().s(songTitle).build());

            GetItemRequest getItemRequest = GetItemRequest.builder()
                .tableName(tableName)
                .key(key)
                .consistentRead(true)
                .build();

            GetItemResponse response = dynamoDbClient.getItem(getItemRequest);

            if (response.hasItem()) {
                LOGGER.info("Item found with strong consistency - no wait time needed");
            } else {
                LOGGER.info("Item not found");
            }

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to read item from table: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to read item from table: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC 保証を使用する条件付きの更新を実行します。  

```
    public static UpdateItemResponse performConditionalUpdate(
        final DynamoDbClient dynamoDbClient,
        final String tableName,
        final String artist,
        final String songTitle,
        final String rating) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (artist == null || artist.trim().isEmpty()) {
            throw new IllegalArgumentException("Artist cannot be null or empty");
        }
        if (songTitle == null || songTitle.trim().isEmpty()) {
            throw new IllegalArgumentException("Song title cannot be null or empty");
        }
        if (rating == null || rating.trim().isEmpty()) {
            throw new IllegalArgumentException("Rating cannot be null or empty");
        }

        try {
            LOGGER.info("Performing conditional update on MRSC global table: " + tableName);

            Map<String, AttributeValue> key = new HashMap<>();
            key.put("Artist", AttributeValue.builder().s(artist).build());
            key.put("SongTitle", AttributeValue.builder().s(songTitle).build());

            Map<String, String> expressionAttributeNames = new HashMap<>();
            expressionAttributeNames.put("#rating", "Rating");

            Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
            expressionAttributeValues.put(
                ":rating", AttributeValue.builder().n(rating).build());

            UpdateItemRequest updateItemRequest = UpdateItemRequest.builder()
                .tableName(tableName)
                .key(key)
                .updateExpression("SET #rating = :rating")
                .conditionExpression("attribute_exists(Artist)")
                .expressionAttributeNames(expressionAttributeNames)
                .expressionAttributeValues(expressionAttributeValues)
                .build();

            UpdateItemResponse response = dynamoDbClient.updateItem(updateItemRequest);
            LOGGER.info("Conditional update successful - demonstrates strong consistency");

            return response;

        } catch (ConditionalCheckFailedException e) {
            LOGGER.warning("Conditional check failed: " + e.getMessage());
            throw e;
        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to perform conditional update: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to perform conditional update: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC レプリカと監視がアクティブになるまで待ちます。  

```
    public static void waitForMRSCReplicasActive(
        final DynamoDbClient dynamoDbClient, final String tableName, final int maxWaitTimeSeconds)
        throws InterruptedException {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (maxWaitTimeSeconds <= 0) {
            throw new IllegalArgumentException("Max wait time must be positive");
        }

        try {
            LOGGER.info("Waiting for MRSC replicas and witnesses to become active: " + tableName);

            final long startTime = System.currentTimeMillis();
            final long maxWaitTimeMillis = maxWaitTimeSeconds * 1000L;
            int backoffSeconds = 5; // Start with 5 second intervals
            final int maxBackoffSeconds = 30; // Cap at 30 seconds

            while (System.currentTimeMillis() - startTime < maxWaitTimeMillis) {
                DescribeTableResponse response = describeMRSCTable(dynamoDbClient, tableName);

                boolean allActive = true;
                StringBuilder statusReport = new StringBuilder();

                if (response.table().multiRegionConsistency() == null
                    || !MultiRegionConsistency.STRONG
                        .toString()
                        .equals(response.table().multiRegionConsistency().toString())) {
                    allActive = false;
                    statusReport
                        .append("MultiRegionConsistency: ")
                        .append(response.table().multiRegionConsistency())
                        .append(" ");
                }
                if (response.table().replicas() == null
                    || response.table().replicas().isEmpty()) {
                    allActive = false;
                    statusReport.append("No replicas found. ");
                }
                if (response.table().globalTableWitnesses() == null
                    || response.table().globalTableWitnesses().isEmpty()) {
                    allActive = false;
                    statusReport.append("No witnesses found. ");
                }

                // Check table status
                if (!"ACTIVE".equals(response.table().tableStatus().toString())) {
                    allActive = false;
                    statusReport
                        .append("Table: ")
                        .append(response.table().tableStatus())
                        .append(" ");
                }

                // Check replica status
                if (response.table().replicas() != null) {
                    for (var replica : response.table().replicas()) {
                        if (!"ACTIVE".equals(replica.replicaStatus().toString())) {
                            allActive = false;
                            statusReport
                                .append("Replica(")
                                .append(replica.regionName())
                                .append("): ")
                                .append(replica.replicaStatus())
                                .append(" ");
                        }
                    }
                }

                // Check witness status
                if (response.table().globalTableWitnesses() != null) {
                    for (var witness : response.table().globalTableWitnesses()) {
                        if (!"ACTIVE".equals(witness.witnessStatus().toString())) {
                            allActive = false;
                            statusReport
                                .append("Witness(")
                                .append(witness.regionName())
                                .append("): ")
                                .append(witness.witnessStatus())
                                .append(" ");
                        }
                    }
                }

                if (allActive) {
                    LOGGER.info("All MRSC replicas and witnesses are now active: " + tableName);
                    return;
                }

                LOGGER.info("Waiting for MRSC components to become active. Status: " + statusReport.toString());
                LOGGER.info("Next check in " + backoffSeconds + " seconds...");

                tempWait(backoffSeconds);

                // Exponential backoff with cap
                backoffSeconds = Math.min(backoffSeconds * 2, maxBackoffSeconds);
            }

            throw DynamoDbException.builder()
                .message("Timeout waiting for MRSC replicas to become active after " + maxWaitTimeSeconds + " seconds")
                .build();

        } catch (DynamoDbException | InterruptedException e) {
            LOGGER.severe("Failed to wait for MRSC replicas to become active: " + tableName + " - " + e.getMessage());
            throw e;
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC レプリカと監視をクリーンアップします。  

```
    public static UpdateTableResponse cleanupMRSCReplicas(
        final DynamoDbClient dynamoDbClient,
        final String tableName,
        final Region replicaRegion,
        final Region witnessRegion) {

        if (dynamoDbClient == null) {
            throw new IllegalArgumentException("DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (replicaRegion == null) {
            throw new IllegalArgumentException("Replica region cannot be null");
        }
        if (witnessRegion == null) {
            throw new IllegalArgumentException("Witness region cannot be null");
        }

        try {
            LOGGER.info("Cleaning up MRSC replicas and witnesses for table: " + tableName);

            // Remove replica using ReplicationGroupUpdate
            ReplicationGroupUpdate replicaUpdate = ReplicationGroupUpdate.builder()
                .delete(DeleteReplicationGroupMemberAction.builder()
                    .regionName(replicaRegion.id())
                    .build())
                .build();

            // Remove witness
            GlobalTableWitnessGroupUpdate witnessUpdate = GlobalTableWitnessGroupUpdate.builder()
                .delete(DeleteGlobalTableWitnessGroupMemberAction.builder()
                    .regionName(witnessRegion.id())
                    .build())
                .build();

            UpdateTableRequest updateTableRequest = UpdateTableRequest.builder()
                .tableName(tableName)
                .replicaUpdates(List.of(replicaUpdate))
                .globalTableWitnessUpdates(List.of(witnessUpdate))
                .build();

            UpdateTableResponse response = dynamoDbClient.updateTable(updateTableRequest);
            LOGGER.info("MRSC cleanup initiated - removing replica and witness. Response: " + response);

            return response;

        } catch (DynamoDbException e) {
            LOGGER.severe("Failed to cleanup MRSC replicas: " + tableName + " - " + e.getMessage());
            throw DynamoDbException.builder()
                .message("Failed to cleanup MRSC replicas: " + tableName)
                .cause(e)
                .build();
        }
    }
```
AWS SDK for Java 2.x を使用して、MRSC ワークフローのデモンストレーションを完了します。  

```
    public static void demonstrateCompleteMRSCWorkflow(
        final DynamoDbClient primaryClient,
        final DynamoDbClient replicaClient,
        final String tableName,
        final Region replicaRegion,
        final Region witnessRegion)
        throws InterruptedException {

        if (primaryClient == null) {
            throw new IllegalArgumentException("Primary DynamoDB client cannot be null");
        }
        if (replicaClient == null) {
            throw new IllegalArgumentException("Replica DynamoDB client cannot be null");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        if (replicaRegion == null) {
            throw new IllegalArgumentException("Replica region cannot be null");
        }
        if (witnessRegion == null) {
            throw new IllegalArgumentException("Witness region cannot be null");
        }

        try {
            LOGGER.info("=== Starting Complete MRSC Workflow Demonstration ===");

            // Step 1: Create an empty single-Region table
            LOGGER.info("Step 1: Creating empty single-Region table");
            createRegionalTable(primaryClient, tableName);

            // Use the existing GlobalTableOperations method for basic table waiting
            LOGGER.info("Intermediate step: Waiting for table [" + tableName + "] to become active before continuing");
            GlobalTableOperations.waitForTableActive(primaryClient, tableName);

            // Step 2: Convert to MRSC with replica and witness
            LOGGER.info("Step 2: Converting to MRSC with replica and witness");
            convertToMRSCWithWitness(primaryClient, tableName, replicaRegion, witnessRegion);

            // Wait for MRSC conversion to complete using MRSC-specific waiter
            LOGGER.info("Waiting for MRSC conversion to complete...");
            waitForMRSCReplicasActive(primaryClient, tableName);

            LOGGER.info("Intermediate step: Waiting for table [" + tableName + "] to become active before continuing");
            GlobalTableOperations.waitForTableActive(primaryClient, tableName);

            // Step 3: Verify MRSC configuration
            LOGGER.info("Step 3: Verifying MRSC configuration");
            describeMRSCTable(primaryClient, tableName);

            // Step 4: Test strong consistency with data operations
            LOGGER.info("Step 4: Testing strong consistency with data operations");

            // Add test item to primary region
            putTestItem(primaryClient, tableName, "The Beatles", "Hey Jude", "The Beatles 1967-1970", "1968");

            // Immediately read from replica region (no wait needed with MRSC)
            LOGGER.info("Reading from replica region immediately (strong consistency):");
            GetItemResponse getResponse =
                getItemWithConsistentRead(replicaClient, tableName, "The Beatles", "Hey Jude");

            if (getResponse.hasItem()) {
                LOGGER.info("✓ Strong consistency verified - item immediately available in replica region");
            } else {
                LOGGER.warning("✗ Item not found in replica region");
            }

            // Test conditional update from replica region
            LOGGER.info("Testing conditional update from replica region:");
            performConditionalUpdate(replicaClient, tableName, "The Beatles", "Hey Jude", "5");
            LOGGER.info("✓ Conditional update successful - demonstrates strong consistency");

            // Step 5: Cleanup
            LOGGER.info("Step 5: Cleaning up resources");
            cleanupMRSCReplicas(primaryClient, tableName, replicaRegion, witnessRegion);

            // Wait for cleanup to complete using basic table waiter
            LOGGER.info("Waiting for replica cleanup to complete...");
            GlobalTableOperations.waitForTableActive(primaryClient, tableName);

            // "Halt" until replica/witness cleanup is complete
            DescribeTableResponse cleanupVerification = describeMRSCTable(primaryClient, tableName);
            int backoffSeconds = 5; // Start with 5 second intervals
            while (cleanupVerification.table().multiRegionConsistency() != null) {
                LOGGER.info("Waiting additional time (" + backoffSeconds + " seconds) for MRSC cleanup to complete...");
                tempWait(backoffSeconds);

                // Exponential backoff with cap
                backoffSeconds = Math.min(backoffSeconds * 2, 30);
                cleanupVerification = describeMRSCTable(primaryClient, tableName);
            }

            // Delete the primary table
            deleteTable(primaryClient, tableName);

            LOGGER.info("=== MRSC Workflow Demonstration Complete ===");
            LOGGER.info("");
            LOGGER.info("Key benefits of Multi-Region Strong Consistency (MRSC):");
            LOGGER.info("- Immediate consistency across all regions (no eventual consistency delays)");
            LOGGER.info("- Simplified application logic (no need to handle eventual consistency)");
            LOGGER.info("- Support for conditional writes and transactions across regions");
            LOGGER.info("- Consistent read operations from any region without waiting");

        } catch (DynamoDbException | InterruptedException e) {
            LOGGER.severe("MRSC workflow failed: " + e.getMessage());
            throw e;
        }
    }
```
+ API の詳細についてはAWS SDK for Java 2.x API リファレンスの**以下のトピックを参照してください。
  + [CreateTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/CreateTable)
  + [DeleteTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/DeleteTable)
  + [DescribeTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/DescribeTable)
  + [GetItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/GetItem)
  + [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem)
  + [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)
  + [UpdateTable](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateTable)

------

# DynamoDB グローバルテーブルのセキュリティ
<a name="globaltables-security"></a>

グローバルテーブルレプリカは DynamoDB テーブルであるため、AWS Identity and Access Management (IAM) ID ポリシーやリソースベースのポリシーなど、単一リージョンテーブルに対して行うレプリカへのアクセスを制御するのと同じ方法を使用します。

このトピックでは、IAM アクセス許可と AWS Key Management Service (AWS KMS) 暗号化を使用して DynamoDB グローバルテーブルを保護する方法について説明します。クロスリージョンレプリケーションと自動スケーリングを許可するサービスリンクロール (SLR)、グローバルテーブル の作成、更新、削除に必要な IAM アクセス許可、マルチリージョンの最終的な一貫性 (MREC) テーブルとマルチリージョンの強力な整合性 (MRSC) テーブルの違いについて説明します。また、クロスリージョンレプリケーションを安全に管理するための AWS KMS 暗号化キーについても説明します。

## グローバルテーブルのサービスリンクロール
<a name="globaltables-slr"></a>

DynamoDB グローバルテーブルは、クロスリージョンレプリケーションと自動スケーリング機能を管理するために、サービスリンクロール (SLR) に依存しています。

これらのロールは、AWS アカウントごとに 1 回だけ設定する必要があります。作成後、同じロールがアカウント内のすべてのグローバルテーブルに機能します。サービスリンクロールの詳細については、「*IAM ユーザーガイド*」の「[サービスリンクロールの使用](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html)」を参照してください。

### レプリケーションサービスにリンクされたロール
<a name="globaltables-replication-slr"></a>

最初のグローバルテーブルを作成するとき、Amazon DynamoDB によって、`AWSServiceRoleForDynamoDBReplication` サービスリンクロール (SLR) が自動的に作成されます。このロールは、クロスリージョンレプリケーションを管理します。

リソースベースのポリシーをレプリカに適用する際は、`AWSServiceRoleForDynamoDBReplicationPolicy` で定義されている SLR プリンシパルへのアクセス許可を拒否しないでください。拒否すると、レプリケーションが中断されます。必要な SLR アクセス許可を拒否すると、影響を受けるレプリカとの間のレプリケーションは停止し、レプリカテーブルのステータスは「`REPLICATION_NOT_AUTHORIZED`」に変わります。
+ マルチリージョンの結果整合性 (MREC) のグローバルテーブルについて、レプリカが 20 時間以上「`REPLICATION_NOT_AUTHORIZED`」ステータスのままである場合、レプリカは 1 つのリージョンの DynamoDB テーブルに変換され、元に戻せなくなります。
+ マルチリージョンの強力な整合性 (MRSC) のグローバルテーブルの場合、必要なアクセス許可を拒否すると、書き込みおよび強力な整合性のある読み込みオペレーションが `AccessDeniedException` になります。レプリカが 7 日以上「`REPLICATION_NOT_AUTHORIZED`」ステータスのままである場合、レプリカは永続的にアクセスできなくなり、書き込みオペレーションと強力な整合性のある読み込みオペレーションはエラーで失敗し続けます。レプリカの削除などの一部の管理オペレーションは成功します。

### 自動スケーリングサービスにリンクされたロール
<a name="globaltables-autoscaling-slr"></a>

プロビジョンドキャパシティモードのグローバルテーブルを設定する場合は、グローバルテーブルに自動スケーリングを設定する必要があります。DynamoDB 自動スケーリングは、AWS Application Auto Scaling Service を使用して、グローバルテーブルレプリカのプロビジョニングされたスループットキャパシティを動的に調整します。Application Auto Scaling サービスは、[https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html) という名前のサービスにリンクされたロール (SLR) を作成します。このサービスにリンクされたロールは、DynamoDB テーブルの自動スケーリングを初めて設定するときに、AWS アカウントで自動的に作成されます。これにより、Application Auto Scaling はプロビジョニングされたテーブル容量を管理でき、CloudWatch アラームを作成できます。

 リソースベースのポリシーをレプリカに適用する際は、[https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSApplicationAutoscalingDynamoDBTablePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSApplicationAutoscalingDynamoDBTablePolicy.html) で定義されている Application Auto Scaling SLR プリンシパルへのアクセス許可を拒否しないでください。拒否すると、自動スケーリング機能が中断されます。

### サービスにリンクされたロールの IAM ポリシーの例
<a name="globaltables-example-slr"></a>

以下の条件の IAM ポリシーは、DynamoDB レプリケーション SLR および AWS 自動スケーリング SLR に必要なアクセス許可には影響しません。この条件は、レプリケーションや自動スケーリングが意図せずに中断されないように、制限の広いポリシーに追加できます。

#### 拒否ポリシーから必要な SLR アクセス許可を除外する
<a name="example-exclude-slr-policy"></a>

次の例は、サービスにリンクされたロールプリンシパルを拒否ステートメントから除外する方法を示しています。

```
"Condition": {
    "StringNotEquals": {
        "aws:PrincipalArn": [
            "arn:aws::iam::111122223333:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication",
            "arn:aws::iam::111122223333:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable"
        ]
    }
}
```

## グローバルテーブルで AWS IAM を使用する方法
<a name="globaltables-iam"></a>

次のセクションでは、さまざまなグローバルテーブルのオペレーションに必要なアクセス許可について説明し、ユーザーとアプリケーションに適切なアクセスを設定するのに役立つポリシーの例を示します。

**注記**  
説明されているすべてのアクセス許可は、影響を受けるリージョンの特定のテーブルリソース ARN に適用する必要があります。テーブルリソース ARN は `arn:aws:dynamodb:region:account-id:table/table-name` の形式に従います。ここでは、実際のリージョン、アカウント ID、テーブル名の値を指定する必要があります。

**Topics**
+ [グローバルテーブルの作成とレプリカの追加](#globaltables-creation-iam)
+ [グローバルテーブルの更新](#globaltables-update-iam)
+ [グローバルテーブルとレプリカの削除](#globaltables-delete-iam)

### グローバルテーブルの作成とレプリカの追加
<a name="globaltables-creation-iam"></a>

DynamoDB グローバルテーブルは、マルチリージョンの結果整合性 (MREC) およびマルチリージョンの強力な整合性 (MRSC) の 2 つの整合性モードをサポートしています。MREC グローバルテーブルは、任意の数のリージョンにまたがって複数のレプリカを持つことができ、結果整合性を提供します。MRSC グローバルテーブルは、3 つのリージョン (3 つのレプリカまたは 2 つのレプリカと 1 つの監視) のみを必要とし、目標復旧時点 (RPO) との強力な整合性を提供します。

グローバルテーブルの作成に必要なアクセス許可は、監視の有無にかかわらず、グローバルテーブルを作成するかどうかによって異なります。

#### グローバルテーブルを作成するためのアクセス許可
<a name="globaltables-creation-iam-all-types"></a>

次のアクセス許可は、最初のグローバルテーブルの作成と、後でレプリカを追加するために必要です。これらのアクセス許可は、マルチリージョンの結果整合性 (MREC) とマルチリージョンの強力な整合性 (MRSC) の両方のグローバルテーブルに適用されます。
+ グローバルテーブルには、DynamoDB が [`AWSServiceRoleForDynamoDBReplication`](#globaltables-replication-slr) サービスリンクロール (SLR) を通じて管理するクロスリージョンレプリケーションが必要です。次のアクセス許可により、DynamoDB はグローバルテーブルを初めて作成するときに、このロールを自動的に作成できます。
  + `iam:CreateServiceLinkedRole`
+ [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) API を使用してグローバルテーブルを作成するか、レプリカを追加するには、ソーステーブルリソースに対して次のアクセス許可が必要です。
  + `dynamodb:UpdateTable`
+ レプリカを追加するには、そのリージョンのテーブルリソースに対して次のアクセス許可が必要です。
  + `dynamodb:CreateTable`
  + `dynamodb:CreateTableReplica`
  + `dynamodb:Query`
  + `dynamodb:Scan`
  + `dynamodb:UpdateItem`
  + `dynamodb:PutItem`
  + `dynamodb:GetItem`
  + `dynamodb:DeleteItem`
  + `dynamodb:BatchWriteItem`

#### 監視を使用した MRSC グローバルテーブルの追加アクセス許可
<a name="globaltables-creation-iam-witness"></a>

監視リージョンを使用してマルチリージョンの強力な整合性 (MRSC) グローバルテーブルを作成する場合、すべての参加リージョン (レプリカリージョンと監視リージョンの両方を含む) のテーブルリソースに対して次のアクセス許可が必要です。
+ `dynamodb:CreateGlobalTableWitness`

#### グローバルテーブルの作成のための IAM ポリシーの例
<a name="globaltables-creation-iam-example"></a>

##### 3 つのリージョンにわたる MREC または MRSC グローバルテーブルの作成
<a name="globaltables-creation-iam-example-three-regions"></a>

次のアイデンティティベースのポリシーでは、必要な DynamoDB レプリケーションのサービスリンクロールの作成など、3 つのリージョンにまたがって「users」という名前の MREC または MRSC グローバルテーブルを作成できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowCreatingUsersGlobalTable",
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateTable",
        "dynamodb:CreateTableReplica",
        "dynamodb:UpdateTable",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:DeleteItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-east-1:123456789012:table/users",
        "arn:aws:dynamodb:us-east-2:123456789012:table/users",
        "arn:aws:dynamodb:us-west-2:123456789012:table/users"
      ]
    },
    {
      "Sid": "AllowCreatingSLR",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication"
      ]
    }
  ]
}
```

------

##### MREC または MRSC グローバルテーブルの作成を特定のリージョンに制限する
<a name="globaltables-creation-iam-example-restrict-regions"></a>

次のアイデンティティベースのポリシーでは、必要な DynamoDB レプリケーションサービスリンクロールの作成など、[aws:RequestedRegion](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requestedregion) 条件キーを使用して、特定のリージョン間で DynamoDB グローバルテーブルのレプリカを作成できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowAddingReplicasToSourceTable",
      "Effect": "Allow",
      "Action": [
        "dynamodb:UpdateTable"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": [
            "us-east-1"
          ]
        }
      }
    },
    {
      "Sid": "AllowCreatingReplicas",
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateTable",
        "dynamodb:CreateTableReplica",
        "dynamodb:UpdateTable",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:DeleteItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": [
            "us-east-2",
            "us-west-2"
          ]
        }
      }
    },
    {
      "Sid": "AllowCreatingSLR",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication"
      ]
    }
  ]
}
```

------

##### 監視付き MRSC グローバルテーブルの作成
<a name="globaltables-creation-iam-example-witness"></a>

次のアイデンティティベースのポリシーでは、us-east-1 と us-east-2 のレプリカと us-west-2 の監視のある「users」という名前の DynamoDB MRSC グローバルテーブルを作成できます。これには、必要な DynamoDB レプリケーションサービスリンクロールの作成が含まれます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowCreatingUsersGlobalTableWithWitness",
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateTable",
        "dynamodb:CreateTableReplica",
        "dynamodb:CreateGlobalTableWitness",
        "dynamodb:UpdateTable",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:DeleteItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-east-1:123456789012:table/users",
        "arn:aws:dynamodb:us-east-2:123456789012:table/users"
      ]
    },
    {
      "Sid": "AllowCreatingSLR",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication"
      ]
    }
  ]
}
```

------

##### MRSC 監視の作成を特定のリージョンに制限する
<a name="globaltables-creation-iam-example-restrict-witness-regions"></a>

このアイデンティティベースのポリシーでは、必要な DynamoDB レプリケーションサービスリンクロールの作成など、[aws:RequestedRegion](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requestedregion) 条件キーとすべてのリージョン間で制限されていない監視の作成を使用して、特定のリージョン間で MRSC グローバルテーブルとレプリカを作成できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowCreatingReplicas",
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateTable",
        "dynamodb:CreateTableReplica",
        "dynamodb:UpdateTable",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:DeleteItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": [
            "us-east-1",
            "us-east-2"
          ]
        }
      }
    },
    {
      "Sid": "AllowCreatingWitness",
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateGlobalTableWitness"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowCreatingSLR",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication"
      ]
    }
  ]
}
```

------

### グローバルテーブルの更新
<a name="globaltables-update-iam"></a>

[https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) API を使用して既存のグローバルテーブルのレプリカ設定を変更するには、API コールを行うリージョンのテーブルリソースに対して次のアクセス許可が必要です。
+ `dynamodb:UpdateTable`

自動スケーリングポリシーや有効期限設定など、他のグローバルテーブル設定も更新できます。これらの追加の更新オペレーションには、次のアクセス許可が必要です。
+ [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTableReplicaAutoScaling.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTableReplicaAutoScaling.html) API を使用してレプリカの自動スケーリングポリシーを更新するには、レプリカを含むすべてのリージョンのテーブルリソースに対して、次のアクセス許可が必要です。
  + `application-autoscaling:DeleteScalingPolicy`
  + `application-autoscaling:DeleteScheduledAction`
  + `application-autoscaling:DeregisterScalableTarget`
  + `application-autoscaling:DescribeScalableTargets`
  + `application-autoscaling:DescribeScalingActivities`
  + `application-autoscaling:DescribeScalingPolicies`
  + `application-autoscaling:DescribeScheduledActions`
  + `application-autoscaling:PutScalingPolicy`
  + `application-autoscaling:PutScheduledAction`
  + `application-autoscaling:RegisterScalableTarget`
+ [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTimeToLive.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTimeToLive.html) API を使用して有効期限設定を更新するには、レプリカを含むすべてのリージョンのテーブルリソースに対して次のアクセス許可が必要です。
  + `dynamodb:UpdateTimeToLive`

  有効期限 (TTL) は、マルチリージョンの結果整合性 (MREC) で設定されたグローバルテーブルでのみサポートされることに注意してください。グローバルテーブルの仕組みに関する詳細については、「[DynamoDB グローバルテーブルの仕組み](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html)」を参照してください。

### グローバルテーブルとレプリカの削除
<a name="globaltables-delete-iam"></a>

グローバルテーブルを削除するには、すべてのレプリカを削除する必要があります。このオペレーションに必要なアクセス許可は、監視リージョンの有無にかかわらず、グローバルテーブルを削除するかどうかによって異なります。

#### グローバルテーブルとレプリカを削除するアクセス許可
<a name="globaltables-delete-iam-all-types"></a>

個々のレプリカを削除したり、グローバルテーブルを完全に削除したりするには、次のアクセス許可が必要です。グローバルテーブル設定を削除すると、異なるリージョンのテーブル間のレプリケーション関係のみが削除されます。最後に残っているリージョンの基盤となる DynamoDB テーブルは削除されません。最後のリージョンのテーブルは、同じデータと設定を持つ標準の DynamoDB テーブルとして引き続き存在し続けます。これらのアクセス許可は、マルチリージョンの結果整合性 (MREC) とマルチリージョンの強力な整合性 (MRSC) の両方のグローバルテーブルに適用されます。
+ [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) API を使用して既存のグローバルテーブルからレプリカを削除するには、API コールを行う元のリージョンのテーブルリソースに対して次のアクセス許可が必要です。
  + `dynamodb:UpdateTable`
+ レプリカを削除する各リージョンのテーブルリソースには、次のアクセス許可が必要です。
  + `dynamodb:DeleteTable`
  + `dynamodb:DeleteTableReplica`

#### 監視を使用した MRSC グローバルテーブルの追加アクセス許可
<a name="globaltables-delete-iam-witness"></a>

監視を使用するマルチリージョンの強力な整合性 (MRSC) グローバルテーブルを削除する場合、すべての参加リージョン (レプリカリージョンと監視リージョンの両方を含む) のテーブルリソースに対して次のアクセス許可が必要です。
+ `dynamodb:DeleteGlobalTableWitness`

#### グローバルテーブルレプリカを削除する IAM ポリシーの例
<a name="globaltables-delete-iam-example"></a>

##### グローバルテーブルレプリカの削除
<a name="globaltables-delete-replicas-iam-example"></a>

このアイデンティティベースのポリシーでは、「users」という名前の DynamoDB グローバルテーブルとそのレプリカを 3 つのリージョン間で削除できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:UpdateTable",
        "dynamodb:DeleteTable",
        "dynamodb:DeleteTableReplica"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-east-1:123456789012:table/users",
        "arn:aws:dynamodb:us-east-2:123456789012:table/users",
        "arn:aws:dynamodb:us-west-2:123456789012:table/users"
      ]
    }
  ]
}
```

------

##### 監視を使用する MRSC グローバルテーブルの削除
<a name="globaltables-delete-witness-iam-example"></a>

このアイデンティティベースのポリシーでは、「users」という名前の MRSC グローバルテーブルのレプリカと監視を削除できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:UpdateTable",
        "dynamodb:DeleteTable",
        "dynamodb:DeleteTableReplica",
        "dynamodb:DeleteGlobalTableWitness"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-east-1:123456789012:table/users",
        "arn:aws:dynamodb:us-east-2:123456789012:table/users"
      ]
    }
  ]
}
```

------

## グローバルテーブルで AWS KMS を使用する方法
<a name="globaltables-kms"></a>

すべての DynamoDB テーブルと同様に、グローバルテーブルレプリカは常に AWS Key Management Service (AWS KMS) に保存されている暗号化キーを使用して保管中のデータを暗号化します。

グローバルテーブル内のすべてのレプリカは、同じタイプの KMS キー (AWS 所有キー、AWS マネージドキー、またはカスタマーマネージドキー) で設定する必要があります。

**重要**  
DynamoDB では、レプリカを削除するには、レプリカの暗号化キーにアクセスする必要があります。レプリカの暗号化に使用されるカスタマーマネージドキーを無効化または削除する場合、まずレプリカを削除し、残りのレプリカのいずれかのテーブルステータスが「`ACTIVE`」に変わるのを待ってから、キーを無効化または削除する必要があります。

マルチリージョンの結果整合性 (MREC) 用に設定されたグローバルテーブルの場合、レプリカの暗号化に使用されるカスタマーマネージドキーへの DynamoDB のアクセスを無効化または取り消すと、レプリカとの間のレプリケーションは停止し、レプリカのステータスは「`INACCESSIBLE_ENCRYPTION_CREDENTIALS`」に変わります。MREC グローバルテーブルのレプリカが 20 時間以上「`INACCESSIBLE_ENCRYPTION_CREDENTIALS`」ステータスのままである場合、レプリカは単一リージョンの DynamoDB テーブルに変換され、元に戻せなくなります。

マルチリージョンの強力な整合性 (MRSC) 用に設定されたグローバルテーブルの場合、レプリカの暗号化に使用されるカスタマーマネージドキーへの DynamoDB のアクセスを無効化または取り消すと、レプリカとの間のレプリケーションは停止し、レプリカへの書き込みまたは強力な整合性のある読み込みを実行しようとするとエラーが返され、レプリカのステータスは「`INACCESSIBLE_ENCRYPTION_CREDENTIALS`」に変わります。MRSC グローバルテーブルのレプリカが 7 日以上「`INACCESSIBLE_ENCRYPTION_CREDENTIALS`」ステータスのままである場合、取り消された特定のアクセス許可に応じて、レプリカはアーカイブされるか、永続的にアクセスできなくなります。