DynamoDBはLSI変更の夢を見るか?
既存のDynamoDBテーブルのLocal Secondary Indexesを変更することはできるのか
LSIのドキュメントを確認する。
To create one or more local secondary indexes on a table, use the LocalSecondaryIndexes parameter of the CreateTable operation. Local secondary indexes on a table are created when the table is created. When you delete a table, any local secondary indexes on that table are also deleted.
LSIはテーブル作成時しか作成できませんよ、と。
つまり、LSIを変更したい時、新規のテーブルとして再作成するしかない。
そして既存のテーブルのデータを保持したい場合には、再作成したテーブルへのデータ移行が必要になる。
データ移行には以下の方法が考えられる。
- テーブルのバックアップを作成し、リストアをする
- データをS3にエクスポートし、インポートする
まず前者のバックアップを使用したリストアによるデータ移行。ドキュメントを確認する。
コンソールのキャプチャにもあるように
リストア時に
- Restore the entire table
- Restore the table without secondary indexes
を選択できるが、これは全インデックスをリストアする or 全インデックスをリストアしない の選択なので、バックアップ元のLSIがリストアされるだけであり、LSIの変更ができるわけではない。
ちなみにAWS BackupではなくDynamoDBのpoint-in-time recovery (PITR)でのバックアップであっても同様にLSIの変更はできない。
You restore a table without consuming any provisioned throughput on the table. You can do a full table restore using point-in-time recovery, or you can configure the destination table settings. You can change the following table settings on the restored table:
- Global secondary indexes (GSIs)
- Local secondary indexes (LSIs)
- Billing mode
- Provisioned read and write capacity
- Encryption settings
ドキュメントでは変更できるっぽい雰囲気で書いてあるが、同上でLSIの変更ができるわけではない。
続いて後者のデータのエクスポート、インポートによるデータ移行。ドキュメントはこちら。
S3へのインポート、エクスポートは便利である。
しかし、インポートは新規のテーブルにしか実行できない。
更に、インポート時の新規テーブル作成ではLSIを作成することができない。なお、GSIは自由に追加作成できる。
つまり、この方法でもLSIの変更はできないということ。
re:Postにも書いている人がいた。
で、結局LSIを変更したい場合はどうするのって話だけど簡単な方法は無さそうに見えた。
おそらく以下の3択になる。
- データ保持を諦めて、テーブルの再作成
- 開発段階での最終手段
- LSIの変更を諦めて、GSIで目的のインデックスを作成する
- アプリケーション側の利用インデックスの変更が必要になるが、まあ受け入れられるかも
- 自前で頑張ってデータ移行をする
- 移行用のコードを書いてBatchWriteItemをするなど
- https://repost.aws/knowledge-center/dynamodb-bulk-upload
- 試してはいないが、DataPipelineを使ったインポートでは既存のDynamoDBテーブルを指定するとドキュメントに書かれているので、その通り動くならこの方法が一番楽かもしれない。LSIを変更したテーブルを用意してインポートすれば良いので
もし自前のDataPipelineの方法がうまく動くのなら、後発のS3インポート機能でも既存のテーブルを指定できるようにして欲しかった。
DataPipelineはメンテナンスモードなので新規に使い始めるのは適して無さそうだった。
自前でのデータ移行で、S3にエクスポートしたデータを元にしてBatchWriteItemなどで移行する方法もあった。
結論として、どうしてもLSIを変更しつつデータを保持したい場合の現時点での最善策は以下となる。
- 対象のDynamoDBテーブルに対してS3エクスポートを実行する
- 期待するLSIを持った新規DynamoDBテーブルを作成する
- スクリプトなどを実装し、S3上のデータを読んで、作成したテーブルにBatchWriteItemなどでデータ移行をする
ノーコードでは無理そう。
以上。