アプリの新しいバージョンを開発する

このトピックでは、アプリを新しいバージョンやパッチにアップデートする際の情報とベストプラクティスを提供します。

新しいバージョンやパッチを開発する際のベストプラクティス

プロバイダーは、アプリの新しいバージョンやパッチを開発する際に、以下のベストプラクティスを考慮する必要があります。

自動セキュリティ・スキャンを開始する前に、アプリを完全にテストします。

以下のアクションにより、自動セキュリティスキャンを開始できます。

  • アプリケーションのバージョンが存在する場合、アプリケーションパッケージの DISTRIBUTION プロパティを EXTERNAL にセットします。

  • DISTRIBUTION プロパティが EXTERNAL にセットされているアプリケーション・パッケージに、新しいバージョンやパッチを追加します。

Snowflake では、セキュリティスキャンを開始する前に、アプリの新しいバージョンまたはパッチをローカルで完全にテストすることを推奨しています。

バージョン間の互換性の確保

プロバイダーは、新しいバージョンが以前のバージョンのアプリと互換性があることを確認する必要があります。例えば、あるアプリにバージョンv1とv2がある場合、v2はv1と互換性がなければなりません。バージョンv3が追加された場合、バージョンv2と互換性がなければなりません。しかし、アプリは一度に2つのバージョンしか存在できないため、バージョンv3はバージョンv1と互換性がある必要はありません。

旧バージョンで実行されているコードは、新バージョンで導入された状態の変更を処理しなければなりません。状態のないオブジェクトを扱うには、プロバイダーはバージョン・スキーマを使用して、アップグレードが正しく処理されるようにする必要があります。詳細については、 バージョンスキーマを使用して、バージョン間でアプリ・オブジェクトを管理 をご参照ください。

パッチの状態変化を最小化

プロバイダーは、新しいパッチが以前の同じバージョンのパッチと異なる状態の変更を導入しないようにしなければなりません。プロバイダーはパッチを開発する際、テーブルや列の追加や変更といった状態の変更を最小限に抑えなければなりません。テーブルと列は、すべてのバージョンとパッチで互換性を保たなければなりません。パッチは、状態の変更を伴わないバグフィックスやマイナーな機能追加に重点を置くべきです。

状態の変更は、アプリのバージョンを更新するときにのみ行われるべきです。

セットアップ・スクリプトからオブジェクトを作成する際は、安全な方法を使用してください。

セットアップスクリプトからオブジェクトを作成する場合は、以下のベストプラクティスを考慮してください。

  • 次を使用します。 CREATE IF NOT EXISTS:

    テーブル、ビュー、関数、プロシージャなどのデータベース・オブジェクトを作成する場合は、常に CREATE OR REPLACE、 CREATE IF NOT EXISTS、または CREATE OR ALTER のいずれかを使用する必要があります。これにより、アップグレード中にすでに存在するオブジェクトを作成しようとしたときのエラーを防ぐことができます。

    Snowflake では、関数やプロシージャなどのステートレスなオブジェクトにのみ CREATE OR REPLACE を使用し、テーブルなどのステートフルなオブジェクトには使用しないことを推奨しています。

  • 各アプリのセットアップスクリプトが自己完結していること

    アプリの各バージョンは完全で独立したものでなければなりません。例えば、あるテーブルがバージョンv2.0で CREATE TABLE IF NOT EXISTS a(int c)を使用して作成され、バージョンv3.0に ALTER TABLE A(...)が含まれている場合、バージョンv3.0に CREATE TABLE と ALTER TABLE ステートメントの両方が存在することを確認してください。これにより、後のバージョンからアプリをインストールするユーザーには、必要なスキーマとオブジェクトがすべて提供されます。

  • セットアップ・スクリプトでは、べき等な変更のみを使用します。

    CREATE、 ALTER ステートメントは、エラーや意図しない副作用なしに複数回実行できるように、べき等の構造になっています。インストール中にセットアップスクリプトが失敗した場合、Snowflakeはセットアップスクリプトを最初から再実行します。バージョン管理されたスキーマがこのバージョン用に既に作成されている場合、そのスキーマは再作成も削除もされません。このためプロバイダーは、 CREATE コマンドの CREATE IF NOT EXISTS バージョンを使用してください。

    例:

    • ALTER TABLE ADD COLUMN IF NOT EXISTS を使用して、列がまだ存在しない場合にのみ列が追加されるようにします。

    • 行を挿入する際には、アップグレードが何度も再試行される可能性があるため、意図しない重複行が発生しないように安全策を講じてください。

アプリケーション・ロールを作成または削除する場合は注意してください。

バージョンまたはパッチでアプリケーション・ロールを作成または削除する場合は注意してください。アプリケーションロールはバージョン管理されません。アプリケーションのロールを削除したり、オブジェクトのグラントをあるバージョンから別のバージョンに取り消したりすると、アプリが動作しなくなったり、コンシューマーがアプリにアクセスできなくなったりする可能性があります。

CREATE OR REPLACE APPLICATION ROLE の使用は避けてください。代わりに、 CREATEAPPLICATION ROLE IF NOT EXISTS を使用してください。OR REPLACE 句はロールを削除して再作成します。以前のバージョンでアプリケーション・ロールに付与されたアカウントレベルのロールを再度付与する必要があるため、権限に関する問題が発生します。

コンテナーを使って新しいパッチやアプリのバージョンを開発する際のベストプラクティス

プロバイダーは、コンテナーを使用するアプリの新しいバージョンやパッチを開発する際に、以下のベストプラクティスを考慮する必要があります。

  • SYSTEM$WAIT_FOR_SERVICES システム関数のタイムアウト値をセットする際はご注意ください。

    この値を長すぎる値に設定すると、アプリの他の部分がサービスが利用可能であることを期待している場合に失敗する可能性があります。詳細については、 セットアップスクリプトの実行を一時停止する をご参照ください。

  • Snowflake では、バージョン管理スキーマ内にバージョン初期化ストアドプロシージャを作成することを推奨しています。バージョン・イニシャライザーがバージョン管理されたスキーマ内で作成されない場合、バージョン・イニシャライザーは、あるバージョンから次のバージョンへ存在しない可能性があります。

  • アプリがバージョンイニシャライザを指定する場合、Snowflakeは、セットアップスクリプトではなく、バージョンイニシャライザ内でサービスの開始またはアップグレードを試みることを推奨します。これにより、アップグレードに失敗した場合でも、正しいバージョンのサービスが実行されていることが保証されます。

  • バージョン初期化機能はアプリケーション・ロールに付与する必要はありません。

コンテナーを使用したアプリのアップデートに関する追加情報については、 コンテナーによるアプリの更新 をご参照ください。

コンテナーによるアプリの更新

コンテナーを使用するアプリを新しいバージョンに更新すると、アップグレード中に考慮すべきことが増えます。コンテナを使用したアプリをアップグレードするプロセスには、主に2つのステージがあります。

  • アプリが管理するコンテナ内のサービスをアップグレードします。

    他の Snowpark コンテナーサービスと同様に、コンテナーアプリは ALTER SERVICE コマンドを使用して、新しいバージョンのサービス仕様ファイルに基づいてサービスを変更します。このコマンドは非同期で実行されます。

  • アプリ内の他のオブジェクトをアップグレードします。

    サービスが正常にアップグレードされると、アプリ内の他のオブジェクトもアップグレードされます。これは通常の Snowflake Native App アップグレードプロセスと同様です。詳細については、 アプリのアップグレードについて をご参照ください。

Snowflake Native App Framework では、メジャーバージョンアップの際にもユーザーはアプリを使い続けることができ、通常のアプリのダウンタイムは発生しません。しかし、コンテナーを使用するアプリでは、 CREATE SERVICEALTER SERVICE の両方が非同期です。つまり、アップグレードが終了しても、新しいバージョンのサービスがすぐに利用できるとは限りません。

コンテナーを使ってアプリをアップグレードするときに起こりうる問題は、 ALTER SERVICE コマンドが非同期で実行されることです。このコマンドで ALTER SERVICE をセットアップスクリプトに直接追加すると、サービスのアップグレードが進行中でもセットアップスクリプトが実行され続けます。

プロバイダーは、サービスのアップグレードがまだ完了していない可能性を想定してセットアップスクリプトを記述するか、 SYSTEM$WAIT_FOR_SERVICESバージョンイニシャライザーを使用して、サービスのアップグレードを管理します。、サービスの正しいバージョンが使用可能であることを保証する必要があります。

サービスのアップグレードを適切に処理するために、 Snowflake Native App Framework はアプリで次のことを可能にする機能を提供します。

  • サービスのアップグレードが成功または失敗するまで、セットアップスクリプトの実行を一時停止します。プロバイダーは、セットアップスクリプトが想定される状況に対処できることを確認する必要があります。詳細については、 セットアップスクリプトの実行を一時停止する をご参照ください。

  • バージョン初期化関数を使用して、アップグレードに失敗した場合にサービスのアップグレードを以前のバージョンにロールバックします。詳細については、 サービスをアップグレードする際の考慮事項 をご参照ください。

セットアップスクリプトの実行を一時停止する

ダウンタイムを最小限に抑え、サービスが準備できていることを確認するには、サービスを作成または変更した後、セットアップスクリプトで SYSTEM$WAIT_FOR_SERVICES システム関数を使用します。

SELECT SYSTEM$WAIT_FOR_SERVICES(600, 'services.web_ui', 'services.worker', 'services.aggregation');
Copy

このコマンドにより、セットアップスクリプトは次のいずれかが発生するまで一時停止します。

  • システム関数に渡されるすべての名前付きサービスには READY ステータスがあります。

  • 指定されたサービスのいずれかが FAILED ステータスになっています。

  • 600秒が経過しました。

このシステム関数は、アプリのインストールまたはアップグレードが、サービスが利用可能になるまで、または障害が発生するまで待機し、サービスの状態がバージョンアップと同期していることを保証します。

サービスをアップグレードする際の考慮事項

Snowflake Native App Framework はバージョン初期化コールバック関数を提供し、プロバイダーがサービスのアップグレードと残りのアップグレードプロシージャの同期をとることを可能にします。

基本アプリのアップグレード中、セットアップスクリプトは、バージョン管理されたスキーマ内のオブジェクトを修正することで、アプリを新しいバージョンにアップグレードします。アップグレード中にエラーが発生した場合、バージョン管理されたスキーマ内のオブジェクトはアプリの以前のバージョンに戻ります。

コンテナーを使用するアプリの大文字と小文字の場合、セットアップスクリプトの CREATE SERVICE または ALTER SERVICE コマンドを実行して作成または変更されたサービスは、新しいバージョンのサービス仕様ファイルを使用します。

サービスはバージョン管理されたスキーマ内では作成されないため、 CREATE SERVICE または ALTER SERVICE コマンドが正常に実行されると、サービスはすぐにアップグレードされます。たとえば、セットアップスクリプトの後半で障害が発生した場合、バージョン管理されたスキーマのオブジェクトは以前のバージョンに戻されますが、変更されたサービスは新しいバージョンのサービスになります。

バージョンイニシャライザーを使用して、サービスのアップグレードを管理します。

Snowflake Native App Framework はバージョンイニシャライザを提供し、サービスやその他の関連プロセス(タスクなど)の起動やアップグレードに使用されます。バージョン初期化子は、マニフェストファイルで指定されるコールバックストアドプロシージャです。

バージョン・イニシャライザーは、以下のコンテキストで呼び出されます。

  • インストール中、アプリのセットアップスクリプトがエラーなしで終了するとすぐに、バージョン初期化子が呼び出されます。

  • アップグレードの際、バージョン・イニシャライザーが呼び出されるシナリオは2つ考えられます:

    • 新バージョンのセットアップスクリプトが成功すると、新バージョンのアプリのバージョンイニシャライザーが呼び出されます。

    • セットアップスクリプトまたは新バージョンのバージョンイニシャライザーが失敗した場合、アプリの旧バージョンのバージョンイニシャライザーが呼び出されます。これにより、以前のバージョンのバージョン初期化子は ALTER SERVICE を使用してサービスを以前のバージョンに戻すことができます。

アプリにバージョンイニシャライザーを追加

バージョン初期化子として使用するストアドプロシージャを指定するには、 manifest.yml ファイルに次のコードを追加します。

lifecycle_callback:
  version_initializer: callback.version_init
Copy

この例では、 version_initializer プロパティは、 callback というスキーマ内の version_init というストアドプロシージャに設定されています。

セットアップスクリプト内で、次の例に示すように、バージョン管理されたスキーマ内でプロバイダーはこのプロシージャを定義できます。

CREATE OR ALTER VERSIONED SCHEMA callback;

CREATE OR REPLACE PROCEDURE callback.version_init()
  ...
  -- body of the version_init() procedure
  ...
Copy