DynamoDBのバックアップとS3エクスポートを試してみた

# 背景・目的
DynamoDB（以降、DDBという。）のバックアップを試したときのメモを残しておきます。

# まとめ
バックアップとリストアでは、以下の3つが利用できます。

|パターン |特徴 |　仕組み| 用途|
|:-- |:-- |:-- |:-- |
|PITR | 過去35日〜直近5分前までの間で任意の時間に復旧可能| DDBの機能 | 分単位で任意の時間に戻したい場合|
|オンデマンドバックアップ | 任意のタイミングでバックアップを実行| AWS Backupまたは、DDBの機能| 35日より前のデータを使用してリストアしたい場合|
|S３エクスポート | 任意のタイミングでエクスポート<BR>JSONフォーマットで出力される。|DDBの機能| 35日より前のデータを使用してリストアしたい場合、または他のAWSサービス（Athenaなど）で利用する場合<BR>※エクスポートは35日間で任意の時間。|

# 内容
## DDBのバックアップ
DDBでは、以下の方法でバックアップが取れます。
- PITR
- オンデマンドバックアップ
- S3へのエクスポート


### PITR
PITRは、以下の特徴があります。
- 自動バックアップする。
- 誤った書き込みや削除オペレーションから保護ができる。
- 過去35日間の任意の時点にテーブルを復元できる。
- 増分バックアップが維持される。

#### PITRの仕組み
- 有効化には、CLI、マネコン、APIを使用する。
- 有効化後には、明示的に無効化するまで、連続バックアップを行う。
- EarliestRestorableDateTime、LatestRestorableDateTime内の任意の時点に復元が可能。

### オンデマンドバックアップ
オンデマンドバックアップには、以下の特徴があります。
- S3に出力する。
- DynamoDB オンデマンドバックアップの作成と管理に使用できるオプションは2つ
    - AWS Backup
    - DynamoDB
- AWS Backupを使用するほうがより高度なバックアップの設定が可能になります。
    - バックアップウィンドウをカスタマイズ
    - 保持期間

### S3エクスポート
S3エクスポートには、以下の特徴があります。
- JSONフォーマットとIonフォーマットの形式が選べます。
    - DDB JSON（JSONLかと思われる）
    - Amazon Ion
- PITRが前提（有効化する必要あり）
- クロスアカウントのS3バケットに出力

# 実践
## 事前準備
### DDBのテーブル作成とデータ登録
1. 以下の内容を設定し、テーブルを作成します。
    - テーブル名：PITR_TEST
    - パーティションキー：id （数値）
    - ソートキー：time（文字列）
    - テーブルクラス：DynamoDB標準
    - 保管時の暗号化：Amazon DynamoDBが所有
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/dd8ec4d2-5d05-433b-096e-acaa90b9a35f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8360bace-fa4b-641f-756e-6440abe01211.png)

1. データを登録します。アクションから「項目を作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c4b1d4ac-7fe6-bff0-3e86-eb283c28c08e.png)
1. idとtimeに値を入力し、「項目を作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/3fb0f733-3e8d-8ba5-7b3c-330e3c1c61dc.png)

### S3エクスポート用のS3バケットを作成
1. バックアップ用のS3バケットを作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/724b8f80-f981-f86f-8aa4-29139260b9f8.png)

## PITR〜リストアまで確認
### PITRを設定
1. テーブルのバックアップタブで「編集」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7088b450-8e72-0257-b89d-fa394406c16a.png)

1. 「ポイントタイムリカバリの有効化」にチェックを入れて、「変更を保存」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ed8a86c0-9280-0d05-dfde-96b6f8463050.png)

1. 設定されました。
   - EarliestRestorableDateTime（最も早い復元ポイント）：2022/10/26 22:59:23
   - LatestRestorableDateTime（最も遅い復元ポイント）：2022/10/26 22:59:23
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/df8d2914-b54d-27f4-d400-4a1a9e80a435.png)

1. 時間を空けて確認する。LatestRestorableDateTimeが更新されています。
   - EarliestRestorableDateTime（最も早い復元ポイント）：2022/10/26 22:59:23
   - LatestRestorableDateTime（最も遅い復元ポイント）：2022/10/26 23:01:46
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/93bc6053-92a0-14ad-ebcf-80215e989c10.png)

### リストアする
リストアを確認したいので、データをもう一件登録してから戻します。

1. データを登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/9fc414c6-db88-8599-4e29-d2291736e20e.png)


1. 復元ポイントを確認します。
   - EarliestRestorableDateTime（最も早い復元ポイント）：2022/10/26 22:59:23
   - LatestRestorableDateTime（最も遅い復元ポイント）：2022/10/26 23:41:20
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f5908bfa-082f-f539-2197-6f3cf1a1ffa6.png)


1. 「復元」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/3189905f-d08c-ec6d-d923-01e7a4f5d658.png)

1. 以下を設定して、復元ボタンをクリックします。
    - 復元されたテーブル名：PITR_TABLE2
    - ポイントタイムリカバリ
        - 日時の指定：2022/10/26 23:00:00 **※最も早い復元ポイントに近い時間。(想定では、データが一件しかない状態) **
    - セカンダリーインデックス
        - なし
    - リージョン
        - 同一リージョン
    - 暗号化設定
        - DDB所有の暗号化キー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e5a15fa8-381f-9396-2372-46f7ef4d54f9.png)

1. しばらくするとアクティブになりました。（時間にして5分程度？）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e7382a67-cbd6-375b-41c6-f4498e92926a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e8772293-1ee8-3324-4b99-04cbc068d988.png)

1. データを確認します。一件だけ登録されているので想定どおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/40483d19-fc82-1265-19bd-fb6e9ec69e90.png)
※なお、元テーブルは二件登録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/206b3e65-3154-087b-702c-0568b92c9712.png)

## （オンデマンド）バックアップ〜リストアまで確認
### バックアップの作成
1. 「バックアップの作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/29558bb8-0409-a506-f319-bc4b7d205473.png)

1. 以下を設定し、「バックアップの作成」をクリックします。
    - バックアップ設定：設定をカスタマイズを選択
    - バックアップの管理：DDBを使用してバックアップ
    - バックアップ名：PITR_TABLE2を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ad4037e5-4d8f-e253-423e-869d529fbdfe.png)

1. すぐにバックアップが完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6507dde0-9d5a-ed7a-a250-7b00a42aa1ca.png)

### リストアの確認
1. 該当のバックアップを選択し、「復元」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f44afa79-8663-d609-c108-c1ba2af4bc4d.png)

1. 以下を設定し、「復元」ボタンをクリックします。
    - 復元されたテーブルの名前：PITR_TABLE3
    - セカンダリインデックス：セカンダリインデックスなしでテーブルの復元
    - 復元先リージョン：AWSリージョン
    - 保管中の暗号化の設定：DDBが所有
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/3062d472-09fb-5bba-b837-eae8f37b473c.png)

1. しばらくするとアクティブになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/63a9e583-66ea-6c87-de69-04e4ccf1a9aa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e73489cd-fa0d-801e-6982-43fae3336c2c.png)

1. データを確認します。PITR_TABLE2から復元したのでデータは一件です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6914e3ba-3b25-3f64-5487-3603790c1672.png)



## S3へのエクスポート〜インポートを確認
### エクスポート（DynamoDB JSON）
1. 該当テーブルで、「エクスポートおよびストリーム」タブで「S3へのエクスポート」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/409e401c-dfce-0694-547d-71ed599e1074.png)

1. 以下を指定して、「エクスポート」ボタンをクリックします。
    - 送信先S3バケット：作成したS3バケットを指定
    - S3バケット所有者：このAWSアカウントを指定
    - 特定の時点からのエクスポート：現在の時刻
    - エクスポートされたファイル形式：DynamoDB JSONを指定
    - 暗号化キータイプ：SSE-S3を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/dc6b9e59-8499-63d3-8d38-e6a5ece56f2a.png)

1. しばらくすると、エクスポート中から、完了になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fcce612d-1bf2-b5fa-5f5d-daa170292fb6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/22ee5037-716e-2d41-3090-bd1c16fed16e.png)

1. S3に出力されているファイルを確認します。
    - AWSDynamoDB/タイムスタンプ？の下に以下のファイル、フォルダが作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7f86357e-e409-1187-1361-f5ab1d1d9348.png)

1. ファイルを確認します。
```
$ aws s3 ls s3://XXXX/AWSDynamoDB/01666797594287-01966116/
                           PRE data/
2022-10-27 00:20:04          0 _started
2022-10-27 00:25:05        780 manifest-files.json
2022-10-27 00:25:05         24 manifest-files.md5
2022-10-27 00:25:05        595 manifest-summary.json
2022-10-27 00:25:05         24 manifest-summary.md5
$ 

# manifest-summary.json
# DDBのテーブルやS3バケット、エクスポートの時間などのメタ情報が含まれています。
$ aws s3 cp s3://XXXX/AWSDynamoDB/01666797594287-01966116/manifest-summary.json - | cat
{"version":"2020-06-30","exportArn":"arn:aws:dynamodb:eu-west-1:XXXXXXXX:table/PITR_TABLE/export/01666797594287-01966116","startTime":"2022-10-26T15:19:54.287Z","endTime":"2022-10-26T15:25:03.955Z","tableArn":"arn:aws:dynamodb:eu-west-1:XXXXXX:table/PITR_TABLE","tableId":"d9a39fca-e724-44e4-9189-7d5d45304728","exportTime":"2022-10-26T15:19:54.287Z","s3Bucket":"XXXXX","s3Prefix":null,"s3SseAlgorithm":"AES256","s3SseKmsKeyId":null,"manifestFilesS3Key":"AWSDynamoDB/01666797594287-01966116/manifest-files.json","billedSizeBytes":0,"itemCount":2,"outputFormat":"DYNAMODB_JSON"}%                                                                                                                           
$

# manifest-files.json 
# 各ファイルのメタ情報が含まれています。
$ aws s3 cp s3://XXXX/AWSDynamoDB/01666797594287-01966116/manifest-files.json - | cat
{"itemCount":0,"md5Checksum":"OXDoJgXH0Qm7NI/JTp7swA==","etag":"67c8121a4701556ecf2fa9dda42c0269-1","dataFileS3Key":"AWSDynamoDB/01666797594287-01966116/data/fnblvdmmk4z3bl6gg7corchca4.json.gz"}
{"itemCount":1,"md5Checksum":"4Rx5LCkCrXtah9HKl8jZhA==","etag":"d7abf64e60031299a99a8089884c000d-1","dataFileS3Key":"AWSDynamoDB/01666797594287-01966116/data/p3aan7gpcy7fxlnqhcffk7btoy.json.gz"}
{"itemCount":0,"md5Checksum":"OXDoJgXH0Qm7NI/JTp7swA==","etag":"67c8121a4701556ecf2fa9dda42c0269-1","dataFileS3Key":"AWSDynamoDB/01666797594287-01966116/data/b7q7562gxy665cqqnwtsrtvlki.json.gz"}
{"itemCount":1,"md5Checksum":"yUhjsDPrDjVH5HcTrF8h4Q==","etag":"f435bb6c65036af0ea9544c21437aab1-1","dataFileS3Key":"AWSDynamoDB/01666797594287-01966116/data/fhuco7s7heyhjp3h7xutorfofe.json.gz"}
$

# ファイルの一覧を確認
$ aws s3 ls s3://XXXX/AWSDynamoDB/01666797594287-01966116/data/                        
2022-10-27 00:24:47         20 b7q7562gxy665cqqnwtsrtvlki.json.gz
2022-10-27 00:24:33         67 fhuco7s7heyhjp3h7xutorfofe.json.gz
2022-10-27 00:24:17         20 fnblvdmmk4z3bl6gg7corchca4.json.gz
2022-10-27 00:23:51         55 p3aan7gpcy7fxlnqhcffk7btoy.json.gz
$ 

# ファイルの中身を確認-1
$ aws s3 cp s3://XXXX/AWSDynamoDB/01666797594287-01966116/data/fhuco7s7heyhjp3h7xutorfofe.json.gz - | gunzip | cat
{"Item":{"id":{"N":"1"},"time":{"N":"20221026225400"}}}
$

# ファイルの中身を確認-2
$ aws s3 cp s3://XXXX/AWSDynamoDB/01666797594287-01966116/data/p3aan7gpcy7fxlnqhcffk7btoy.json.gz - | gunzip | cat
{"Item":{"id":{"N":"2"},"time":{"N":"2022"}}}
$

```

### リストアの確認
1. S3からのインポート画面で「S3からインポート」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/91ec4044-1e2b-a927-a890-5606d3b84db5.png)

1. 以下を入力し、「次へ」をクリックします。
    - ソースS3パス：エクスポートしたファイルを指定
    - S3バケット所有者:このAWSアカウント
    - ファイル圧縮をインポート：「GZIP」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6b063518-c9a9-0630-b032-ce9088700212.png)


1. 以下を入力し「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2da5a60e-16c4-34c7-7921-f2178a0ec4c0.png)


1. 「インポート」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/121742a0-5ab7-6e3c-dbda-23768973ea27.png)


1. しばらくするとアクティブになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/a3cb688e-be34-1f6c-a1e8-22a38edfd2e6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f2cceaa2-8539-574b-c868-4462e5d4b984.png)

1. データを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/4dbc3c14-49eb-9172-5f1e-fa5dd88dcf8c.png)



### エクスポート（Ion）
:::note info
Ion形式のファイルフォーマットを確認するのが狙いです。リストアはしません。
:::
1. Ion形式を選択して「エクスポート」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b464069b-2ef9-5bd2-596e-1f201a33f442.png)

1. ファイルを確認します。
```
$ aws s3 ls s3://XXXX/ion/AWSDynamoDB/01666801666929-575fbad8/
                           PRE data/
2022-10-27 01:27:52          0 _started
2022-10-27 01:32:52        792 manifest-files.json
2022-10-27 01:32:52         24 manifest-files.md5
2022-10-27 01:32:52        590 manifest-summary.json
2022-10-27 01:32:52         24 manifest-summary.md5
$

$ aws s3 ls s3://XXXX/ion/AWSDynamoDB/01666801666929-575fbad8/data/
2022-10-27 01:32:15         64 22mgtokmku6jpjbgidajulhv5u.ion.gz
2022-10-27 01:32:28         55 5rhm7z5ewe3afabv2oame3mdea.ion.gz
2022-10-27 01:32:14         20 7dmjxzvbvuyh7dt6pv3kpn2lca.ion.gz
2022-10-27 01:32:34         20 gecqj3a36q42haohk4uf525lue.ion.gz
$

$ aws s3 cp s3://XXXX/ion/AWSDynamoDB/01666801666929-575fbad8/data/22mgtokmku6jpjbgidajulhv5u.ion.gz - | gunzip | cat
$ion_1_0 {Item:{id:1.,time:202210262254d2}}
$ 

$ aws s3 cp s3://XXXX/ion/AWSDynamoDB/01666801666929-575fbad8/data/5rhm7z5ewe3afabv2oame3mdea.ion.gz - | gunzip | cat
$ion_1_0 {Item:{id:2.,time:2022.}}
$ 
```


# 考察
- 今回は、バックアップとS3エクスポートを試しました。
- DDBの復旧には、PITRまたはオンデマンドバックが利用できます。
- 他システムで分析などに利用するには、S3エクスポートを利用します。

# 参考
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/PointInTimeRecovery.html

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/PointInTimeRecovery_Howitworks.html

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/PointInTimeRecovery.Tutorial.html

https://aws.amazon.com/jp/premiumsupport/knowledge-center/back-up-dynamodb-s3/

https://aws.amazon.com/blogs/aws/new-export-amazon-dynamodb-table-data-to-data-lake-amazon-s3/