❄️

Snowflakeのバージョン管理とバージョンアップ通知を受け取る方法

2022/12/02に公開

この記事はSnowflake Advent Calendar 2022 Part2 2日目の記事です。

前提

Snowflakeの現在のバージョンはCURRENT_VERSION()にて確認することができます。ドットによって3パートに分かれています。
<major_version>.<minor_version>.<patch_version>
3つ目がパッチバージョンです。1つ目のメジャーバージョンと2つ目のマイナーバージョンを区別して考える意味はあまりなく、ひと続きのバージョンとみなしておいて運用上問題ありません。(実際には暦年で<major_version>は上がっているようで2023年は7です。)

そしてこちらに3種類のリリースが説明されています。
https://docs.snowflake.com/ja/user-guide/intro-releases.html#release-types
が、これは以下のように考えた方がわかりやすいと思います。

  • 総合リリース: <major_version>.<minor_version>が上がる
    - Behavior Change Bundleを含まない
    - 動作変更リリース(Behavior Change Bundleを含む)
  • パッチリリース: <patch_version>のみが上がる

動作変更リリース(Behavior Change Bundleを含む)

Snowflakeにおいてはバージョンアップは透過的であり、サービスの中断を伴わないため、基本的にはユーザが意識する必要はありません。ただし、今までと動作が変わる場合は、動作変更リリースとして一連の動作変更(動作変更バンドル)がデフォルトでは無効化された形でリリースが行われます。これらの変更は一定期間任意のタイミングでユーザが有効化したり無効化したりすることができます。

デフォルト ユーザによる無効化・有効化 期間
テスト期間 無効 最低4週間
オプトアウト期間 有効 最低4週間
リリース済み 有効 不可 -

動作変更リリースは原則4週間に1回リリースされます(それより間隔があくことはあっても短くなることはありません)。各動作変更リリースは、新しい動作変更バンドルをデフォルト無効の状態で導入するとともに、テスト期間中の動作変更バンドルのデフォルトを有効に変更し、オプトアウト期間の動作変更バンドルをリリース済みの状態に変更します。動作変更バンドルはYYYY_MMというフォーマットで命名されており、各動作変更リリースでは新規の動作変更バンドルが導入されるとともに既存の動作変更バンドルの状態がひとつずつずれていく形になります。

6.29 6.32 6.35
テスト期間 2022_06 2022_07 2022_08
オプトアウト期間 2022_05 2022_06 2022_07
リリース済み 2022_04 2022_05 2022_06

ユーザは任意に有効化・無効化が可能な計8週間のあいだ(次の次の動作変更リリースまで)に動作変更に備えることになります。
テスト期間中に明示的に無効化したバンドルはオプトアウト期間に入った後も無効化されたままです[1]。ただし、オプトアウト期間が終了すると自動的に有効化されるため、それより前に明示的に有効化すべきでしょう。
知っておくべきシステム関数は以下4つです。

select SYSTEM$SHOW_ACTIVE_BEHAVIOR_CHANGE_BUNDLES(); //テスト期間・オプトアウト期間のバンドルとその状態をJSONで返却
select SYSTEM$BEHAVIOR_CHANGE_BUNDLE_STATUS('YYYY_MM'); //指定したバンドルの状態を確認
select SYSTEM$ENABLE_BEHAVIOR_CHANGE_BUNDLE('YYYY_MM'); //指定したバンドルの有効化
select SYSTEM$DISABLE_BEHAVIOR_CHANGE_BUNDLE('YYYY_MM'); //指定したバンドルの無効化

なお、Behavior Change Bundleを含むリリースが適用された場合、以下のメールアドレスに通知されます。

  • Snowflakeコミュニティから、あるいは、Snowsightからサポートケースが登録可能なユーザのメールアドレス
  • Snowsightの Admin → Contacts で Product notifications に登録されたメールアドレス

おまけ:テスト環境において、新しい Behavior Change Bundle を自動的に有効化する

特にお勧めするものではございませんが、テスト環境では新しいバンドルを自動的に有効化したいのであればこの方法が使えます。ただ、いつの間にか適用されていた、というだけではあまり意味がないので、有効化後に管理者に通知、自動で一連のテスト処理を実施、といった対応と組み合わせて実施するべきでしょう。

(動作変更を伴わない)総合リリース

動作変更を伴わない総合リリースには、新機能の導入や既存機能の強化、不具合の修正が含まれています。アプリケーションからは透過的なため、このリリースについてはメールでの通知はありません。
リリースは全てのSnowflakeアカウントに同時に行われる訳ではなく段階的に行われます。このリリース順序を意識すれば、本番Snowflakeアカウントにリリースされる前に新しいバージョンを確認することができます。

  1. 早期アクセス - Enterprise Edition以上の指定されたアカウント
  2. 通常アクセス - Standard Editionのアカウント
  3. 最終 - (それ以外の)Enterprise Edition以上のアカウント

検証用のSnowflakeアカウントを早期アクセスに指定するよう、Snowflake社のアカウント担当者に依頼することができます。ただし、1.と3.の間の期間は最低12時間となっており、それほど長い時間が確保されている訳ではありません。

早期アクセスアカウントでバージョンアップ通知を受け取る

前述のように動作変更を伴わないバージョンアップは通知されません。もし早期アクセスのアカウントで何らかのテストを行いたい場合、通知が欲しいところです。以下はTASKおよび2023年8月にGAとなったSYSTEM$SEND_EMAIL()関数を用いて実装した例です。

-- バージョン確認のためのデータベースを作成
use role sysadmin;
create or replace database VERSION_CHECK;
use database VERSION_CHECK;

-- 現行バージョンを元に履歴テーブルを作成
create or replace table VERSION_HISTORY 
    (VERSION varchar, TS timestamp_ltz default current_timestamp());
insert into VERSION_HISTORY values
    (current_version(), current_timestamp());

-- メール通知インテグレーションを作成
use role accountadmin;
create or replace notification integration email_notification
TYPE=EMAIL
ENABLED=TRUE
ALLOWED_RECIPIENTS=('mail_test@example.com');

-- ストアドプロシージャを作成
create or replace procedure VERSION_CHECK_PROC()
    returns binary
    language SQL
    comment = 'Compare the latest version of VERSION_HISTORY table with the current version'
as
declare
    latest_ver string;
    current_ver string;
begin
    current_ver := current_version();
    select max_by(VERSION, TS) into :latest_ver from VERSION_HISTORY;
    if ( latest_ver != current_ver )
    then -- Different versions
        insert into VERSION_HISTORY values (:current_ver, current_timestamp());
        CALL SYSTEM$SEND_EMAIL(
            'email_notification',
            'mail_test@example.com',
            'Snowflake has been updated: ' || current_account() || ' - ' || current_region(),
             to_varchar(current_timestamp,'YYYY-MM-DD HH24:MI:SS TZHTZM') || '\n [Previous]'  || :latest_ver  || ' -> [Current]'|| :current_ver
        );        
        return true;
    else -- Same versions ... do nothing
        return false;
    end if;
end;

-- タスクの作成とレジューム
use role accountadmin; -- 実運用ではTASKADMINのようなロールを作ることが望ましい
create or replace task VERSION_CHECK_TASK
    user_task_managed_initial_warehouse_size = 'XSMALL'
    schedule = '10 minute'
    comment = '10分に1回バージョンをチェックする'
as
    call VERSION_CHECK.PUBLIC.VERSION_CHECK_PROC();

alter task VERSION_CHECK_TASK resume;

/*** 通知メールが送信されることをテストするためダミーのレコードをインサート
insert into version_history values ('test', current_timestamp());
***/

通知で受け取るメールはこんな感じです。

ちなみに10分に1回タスクを起動していますが、かかったクレジットは1ヶ月で0.38クレジットくらいでした。

バージョンアップ通知を受け取るだけではなく、バージョンアップしていたら自動でテストを実施し、その結果を通知するといった応用も可能でしょう。

(補足)通知先メールアドレスについて

メール通知インテグレーションで指定できるのはユーザと紐づいており、かつ、検証済みのメールアドレスです。

These must be email addresses of users in the current account. These email addresses must be verified.

ユーザと紐づいているというのはCREATE USERあるいはALTER USERでメールアドレスが指定されているということです。(もちろんGUIで作業しても構いません。)

create user mail_test 
password = 'mustBeChanged'
must_change_password = true
email = 'mail_test@example.com';

この後このメールアドレスが有効であることを検証する必要があります。当該ユーザでログインした後、下記画面に遷移します。

Resend Verification Emailを押すと宛先に以下のようなメールが送信されます。

VALLIDATE YOUR EMAILを押すと検証が完了します。

パッチリリース

パッチリリースが含むのは不具合修正のみであり、総合リリースのような段階的なリリースは行われません。上述のメール通知の仕組みを使用すれば、本番アカウントでパッチリリースが適用されたときに通知を得ることはできます。

脚注
  1. SYSTEM$DISABLE_BEHAVIOR_CHANGE_BUNDLEに以下の説明があります。
    このコマンドを使用してテスト期間中に動作変更バンドルを無効にした場合、バンドルを再度有効にするか、オプトアウト期間が終了するまで、バンドルは無効のままになります。バンドルがデフォルトで有効になる場合、オプトアウト期間の開始時にSnowflakeはこの設定を上書きしません。 ↩︎

Discussion