はじめに
2024/08/22更新
speakerdeckに内容を追加しました
https://speakerdeck.com/naonana777/redshiftnosatipasunohuo-yong
24時間稼働しているWebサービスの場合、DBデータの一括置き換えのような時間のかかるデータメンテナンス時にもユーザがデータにアクセスできない状態を避ける必要があります。
これに対応するため、Amazon Redshiftで使えるサーチパスを使用したDBの更新手順の案を記載しました。
この記事では手順の説明のために手動更新のような書き方になっていますが、これら一連の処理をStepFunctionsの各ステップで実装しておけばバッチ処理でも画面影響なくデータ更新を行うことが可能です。
使うAWSサービス
・Amazon Redshift
サーチパスとは
・データベースのテーブルに対してSQLを使ったクエリを発行するとき、スキーマを指定せずクエリを発行するとサーチパスの順番に従ってテーブルを探して最初に見つかったテーブルにクエリが実行されます。
参考:https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_search_path.html
更新手順
1.通常稼働時設定
・2つのスキーマを用意しておきます
・画面はサーチパスのスキーマの優先度順にテーブルを参照します。テーブルはどちらか一方にしかなくてもアクセスできますが、両方にある場合はより優先度の高いほうのテーブルが参照されます
・基本的に両方のスキーマに同じ定義のテーブルがあることが理想ですが、以下のような条件のテーブルであればどちらか一方にしか定義しないことも良いと思います
<一方のスキーマしか定義しなくてよい条件>
→画面からしか更新されないようなデータを管理するテーブル
→削除を伴わない更新が行われるテーブル
→上記の条件に加えてテーブル定義が今後変わらないテーブル
2.データメンテナンス①データメンテナンス用スキーマを更新する
・メンテナンス用スキーマのテーブルを更新します
・この時、画面側は同じテーブルがメインスキーマにあればそちらを見るので、メンテナンス作業で仮にメンテナンス用スキーマが空になっても画面に影響はありません
・そのため、画面影響なくデータのメンテナンスができます
3.データメンテナンス②Redshiftのサーチパスをメンテナンス用スキーマ優先に変更
・メンテナンス用スキーマからメインスキーマにテーブルのデータを入れ替えますが、その前にサーチパスをメンテナンス用スキーマ優先に変えておきます
・これは入れ替え中にメインスキーマのデータが空になっても画面に影響が出ないようにするためです
・優先度が高いほうのテーブルを見るため、メンテナンス済みのテーブルを優先してみておけば、画面影響なくメインスキーマのデータ入れ替えが可能です
<実行するSQLの例>
(構文)
ALTER USER [ユーザ名] SET search_path TO [スキーマ名];
(例)
ALTER USER USER_A SET search_path TO メンテナンス,メイン;
4.データメンテナンス③メンテナンス用スキーマからメインスキーマにメンテナンス結果反映
・メンテナンススキーマのメンテナンス済みのテーブルデータをメインスキーマのテーブルに投入します
・投入方法はメンテナンス内容によって異なりますが、前述のようにサーチパスはメンテナンススキーマ優先になっているのでテーブル定義がメンテナンススキーマにあるテーブルであればテーブルのDROPやTRUNCATEを行っても画面に影響はありません
5.データメンテナンス④Redshiftのサーチパスをメインスキーマ優先に変更
・メインスキーマへのデータ移行が完了したら、最後にサーチパスをメインスキーマ優先の元の状態に戻します
・これでユーザ影響なくDBメンテナンスができました
<実行するSQLの例>
(構文)
ALTER USER [ユーザ名] SET search_path TO [スキーマ名];
(例)
ALTER USER USER_A SET search_path TO メイン,メンテナンス;
さいごに
データのメンテナンスは場合によってはユーザ影響を考え、エンジニアが深夜作業を行ったりと負担が大きいです。
しかし、今回のサーチパスを利用したような更新手順のように、手順の工夫をするだけで実現できるユーザ影響もメンテナンス作業者の負担も減らせる作業方法を見つけていきたい。