Amazon Redshift『Auto Vacuum Delete』の動作を確認してみました

Auto Vacuum DeleteはVACUUM DELETEがバックグラウンドで自動実行するサービスです。本日は実際の動作を確認してみました。
2019.01.28

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

はじめに

Auto Vacuum DeleteはVACUUM DELETEがバックグラウンドで自動実行するサービスです。本日は実際の動作を確認してみました。

Auto Vacuum Deleteとは

RedshiftはテーブルのレコードをDELETEやUPDATEすると元のデータ領域を論理削除します。VACUUMはこの論理削除したデータ領域の開放とデータをソートして、データブロックを再編成します。これまでVACUUMはRedshiftの管理者もしくはテーブルの管理者がVACUUMコマンドを実行しなければなりませんでした。

Auto Vacuum Deleteは、論理削除したデータ領域を開放して、データブロックの再編成を自動的に実行する機能です。(データのソートは従来通りVACUUMコマンドを別途実行する必要があります。)

執筆時点では、VACUUMの日本語マニュアルが更新されていませんので、英語マニュアルを御覧ください。

Auto Vacuum Delete の特長

RedshiftはVACUUMコマンドを実行せずにテーブルの追加・更新・削除を繰り返すとストレージは開放されず、いずれはディスク領域不足に陥ってしまいます。Auto Vacuum Deleteによって、この問題が回避できるようになりました。

また、データブロックをコンパクトに再編成することで、論理削除した領域のスキャンせずに済むため、スキャンの効率化によってパフォーマンスが向上します。

以降では、実際にAuto Vacuum Deleteの動作を確認します。

検証

レコードを全件DELETE

では、実際に検証テーブルのレコードを全件削除して、論理削除した領域を開放するまでの時間やクラスタの負荷状況を確認します。(sysdateの時間はUTCなので+9時間してください)

  • (コンパウンド)ソートキーを指定したテーブル
  • 26.5GB/約6億レコードの全件DELETE
cmdb=# select database, schema, "table", size, tbl_rows from svv_table_info where schema = 'cm_test' and "table" = 'lineorder';
database | schema | table | size | tbl_rows
----------+--------------------+-----------+-------+-----------
cmdb | cm_test | lineorder | 27219 | 600037902
(1 row)

cmdb=# delete lineorder;
DELETE 600037902
cmdb=# select sysdate;
timestamp
----------------------------
2019-01-24 15:07:10.395176
(1 row)

ディスクが開放されることを確認

下記の緑色の部分に着目してください。1/25 AM:03:34からAM:03:35の間にAuto Vacuum Deleteが実行され、1分の間にディスク空き容量(Percentage disk space used)が減少しています。その間、CPU使用率の著しい上昇も見られません。メトリクスでは、Auto Vacuum Delete(Space reclaimed by auto vacuum delete (in MB))の実行時間が長く見えますが、これはCloudwatchが測定値を設定する間隔が大きく、プロットが粗いためであり、実際の処理時間は1〜2秒程度です。

気になるストレージに対する負荷ですが、2つのコンピュートノードがそれぞれ2分間上昇していましたが、ほとんど負荷が発生していませんでした。

Auto Vacuum Delete 実行後の確認

論理削除されていたストレージが開放されたことが確認できました。(sysdateの時間はUTCなので+9時間してください)

cmdb=# select database, schema, "table", size, tbl_rows from svv_table_info where schema = 'cm_test' and "table" = 'lineorder';
database | schema | table | size | tbl_rows
----------+--------+-------+------+----------
(0 rows)

cmdb=# select count(*) from cm_test.lineorder;
count
-------
0
(1 row)

cmdb=# select sysdate;
timestamp
----------------------------
2019-01-25 23:40:09.213231
(1 row)

インターリーブドソートキーではどうか?

同じようにVACUUM DELETEが機能しました。つまり、論理削除した領域はAuto Vacuum Delete によって確実にデータ開放が実施されると考えて良いでしょう。

Auto Vacuum Delete が実行されるタイミングは?

初回のAuto Vacuum Delete の検証では、10時間近く待たされて実行されましたが、2回目以降は数時間で自動実行されています。Space reclaimed by auto vacuum delete (in MB)のプロットされている間隔も定期的ではないようです。この2つの値は過去の auto vacuum deleteの実行状況によって変動するのかもしれません。いずれにしても、この検証をしている間は数時間で自動実行してくれましたので、vacuum delete が頻繁に動く環境では問題がないのではないかと考えられます。

また、この機能の紹介記事の中に

VACUUM DELETE の実行スケジュールは、クエリ負荷とテーブル内の削除済み行数に基づいて設定されます。例えば、ユーザーやクエリへの影響を抑えるため、負荷の高い期間には VACUUM DELETE の実行頻度が下がります。VACUUM DELETE の実行は、入力されたクエリの負荷が高いときには自動的に一時停止し、しばらくたってから再開されます。Amazon Redshift ではバキューム処理が不要なテーブルについては処理がスキップされるため、定期実行がスケジュールされた VACUUM DELETE ジョブを変更する必要はありません。

と解説があります。Auto Vacuum Deleteの自動実行をユーザーの設定で変更することはできませんが、実行そのものがが運用の妨げになることはないと考えて良いでしょう。

データのソートは忘れないでください!

Auto Vacuum Delete は論理削除した領域の開放のみなので、ソートキーを設定したテーブルは従来通りVACUUMを実行することを忘れないでください。

コンパウンドソートキーの場合

VACUUM [FULL | SORT ONLY] <テーブル名>;

インターリーブドソートキーの場合

VACUUM REINDEX <テーブル名>;

最後に

ちょっと前のアップデートになりますがブログにまとめました。「RedshiftはVACUUMが必須なので悩ましい」という方は多いので、今回のアップデートは待ちに待ったものでした。

久しぶりに色々なバリエーションのテーブルを作成して、VACUUMを片っ端に実行しましたが想像以上にパフォーマンスが改善しています。考え方を変えると、VACUUMのパフォーマンスが著しく改善した結果、自動実行できるようになったと考えるのが自然なのかもしれません。

でも、データのソートをする目的のVACUUMは従来通り忘れないでください!