Amazon Redshift: 【新機能】スナップショットからのリストアがテーブル単位で可能になりました。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本日SNSで『Amazon Redshiftでテーブル単位でのスナップショットが可能になりました』という情報をキャッチしました。これは便利そうな機能だ!と思い早速内容を確認し、試してみました。

この機能が利用可能となるのは、Redshiftのクラスタのバージョンが1.0.1036以降のものが対象となります。管理コンソール上のクラスタプロパティの内容、もしくは以下の様にAWS CLIでバージョン番号が所定の数値以降のものになっているか確認してください。ドキュメントでは2016年3月10日にはアップグレードされていると記載があるのでお読み頂いている時点でほぼほぼ利用可能になっていると思われます。

$ sudo pip install --upgrade awscli
$ aws --version
aws-cli/1.10.12 Python/2.7.6 Darwin/14.4.0 botocore/1.4.3
$ aws redshift describe-clusters --cluster-identifier xxxxxxxxxx \
  | jq '.Clusters[] | .ClusterVersion, .ClusterRevisionNumber'
"1.0"
"1036"

概要

リストア作業はこれまでは『クラスタ全体』ででしか実施出来ませんでしたが、この機能を使う事によってテーブル単位でのリストアが可能となります。スナップショットからのリストア時に、以下の情報を指定する事でテーブルリストアを行なう形です。

  • リストア元:スナップショット、スキーマ、テーブル
  • リストア先:データベース、スキーマ、テーブル

リストア作業については以下の様な内容、挙動となります。

  • リストア先として指定するテーブル名は既存のテーブル名と重複させる事が出来ません(replaceが出来ません)。リストアする前に対象テーブルをDROP TABLEしておく必要があります。
  • リストア先のテーブルは、外部キー(FOREIGN KEY)を除いた形で、リストア元のテーブル属性や定義を元にしてリストアされます。依存関係による衝突を回避する為に、ターゲットとなるテーブルはソースとなるテーブルから外部キーの情報を引き継ぎませんので注意してください。
  • テーブルをリストアしたユーザーが、テーブルの所有者となります。
  • ソーステーブルに付与されたビューや権限等の依存関係についてはターゲット側のテーブルには適用されません。

制限

スナップショットからのテーブルリストア手順には以下のような制限があります。

  • 実行時時点でアクティブなクラスタが対象となり、またそのクラスタから作成されたスナップショットからのリストアが可能となります。
  • 一度にリストア出来るテーブルは1つだけです。
  • スナップショット作成時にpending状態、コミットされていないトランザクションにあったテーブルはリストア出来ません。
  • リサイズ実施前に取得されたクラスタスナップショットからのリストアは行えません。

実践:管理コンソールからのテーブル単位のリストア

今回の検証ではpubilcスキーマに作成したmlratingというテーブルを使いたいと思います。こちらは以前のエントリで作成していたものです。2000万件超のテーブルです。

# SELECT COUNT(*) FROM public.mlratings;
  count   
----------
 21622187
(1 row)

# \d public.mlratings;
                  Table "public.mlratings"
      Column      |            Type             | Modifiers 
------------------+-----------------------------+-----------
 user_id          | integer                     | not null
 movie_id         | integer                     | not null
 rating           | double precision            | 
 timestamp_bigint | bigint                      | 
 timestamp        | timestamp without time zone | 
Indexes:
    "mlratings_pkey" PRIMARY KEY, btree (movie_id)

一旦、このタイミングでスナップショットを取得しておきます。

redshift-restore-table-from-snapshot-01

管理コンソールのRedshiftメニューで所定のクラスタを選択。すると新しいタブ『Table restore』が表示されています。こちらのタブをクリック。

redshift-restore-table-from-snapshot-02

この時点ではリストア作業を行っていないのでまだ何もありません。[Restore Table]をクリック。

redshift-restore-table-from-snapshot-03

テーブルリストアに関するウィザードが表示されました。ここでは敢えて、リストア元とリストア先の情報を同じにして、どの様なエラーとなるかまずは見てみたいと思います。

redshift-restore-table-from-snapshot-04

リストア実行。暫くPENDINGのままで、1〜2分もすると以下の様にエラーが表示されました。

redshift-restore-table-from-snapshot-05

今度は正しい手順でちゃんとテーブルがリストアされるかどうかを確認してみます。

redshift-restore-table-from-snapshot-06

PENDING -> IN PROGRESSというステータス遷移を経て、数分後には以下の様な形でSUCCEEDEDとなりました。

redshift-restore-table-from-snapshot-07

テーブル名を指定して、内容を確認してみます。所定の内容でちゃんとリストア出来ている事が確認出来ました!

# \d public.mlratings_restored;
             Table "public.mlratings_restored"
      Column      |            Type             | Modifiers 
------------------+-----------------------------+-----------
 user_id          | integer                     | not null
 movie_id         | integer                     | not null
 rating           | double precision            | 
 timestamp_bigint | bigint                      | 
 timestamp        | timestamp without time zone | 
Indexes:
    "mlratings_restored_pkey" PRIMARY KEY, btree (movie_id)

# SELECT COUNT(*) FROM public.mlratings_restored;
  count   
----------
 21622187
(1 row)

実践:AWS CLI経由でのリストア

上記作業はAWS CLIでも実行が可能です。AWS CLIを最新バージョンにする事で、以下の様な形で実行する事が出来ます。

$ aws redshift restore-table-from-cluster-snapshot \
   --snapshot-identifier xxxxxxxxxx-snapshot-20160311-172051 \
   --cluster-identifier xxxxxxxxxx \
   --source-database-name zzzzzzzzzz \
   --source-schema-name public \
   --source-table-name mlratings \
   --target-database-name zzzzzzzzzz \
   --target-schema-name public \
   --new-table-name mlratings_awscli
{
    "TableRestoreStatus": {
        "Status": "PENDING", 
        "RequestTime": "2016-03-11T09:00:39.826Z", 
        "SourceSchemaName": "public", 
        "TargetDatabaseName": "zzzzzzzzzz", 
        "SourceTableName": "mlratings", 
        "TableRestoreRequestId": "c475d2bb-172b-49aa-acfe-810501b0aa38", 
        "NewTableName": "mlratings_awscli", 
        "TargetSchemaName": "public", 
        "ClusterIdentifier": "xxxxxxxxxx", 
        "SourceDatabaseName": "zzzzzzzzzz", 
        "SnapshotIdentifier": "xxxxxxxxxx-snapshot-20160311-172051"
    }
}

まとめ

以上、Amazon Redshiftにおける新機能『テーブル単位でのリストア』に関するご紹介でした。クラスタ全体のリストアとなると規模によっては数時間、十数時間?というような処理時間となってしまう場合もあるので、このような形で個別でテーブル単位のリストアが行えるというのは嬉しいですね。検証・テスト等で同じ内容のテーブルを用意したい、というような場合でも、任意のタイミングで取ったスナップショットから検証用スキーマやデータベースにテーブル単位で環境を整える事が出来るので使い勝手はかなり広がるのではないでしょうか。こちらからは以上です。