开发应用程序的新版本
本主题提供将应用程序更新到新版本或补丁时的信息和最佳实践。
开发新版本或补丁时的最佳实践
在开发应用程序新版本或补丁时,提供商应考虑以下最佳实践。
启动自动安全扫描前,全面测试应用程序
以下操作可以启动自动安全扫描:
- Setting the DISTRIBUTION property of the application package to EXTERNAL if a version of the app exists
- Adding a new version or patch to an application package that has the DISTRIBUTION property set to EXTERNAL
Snowflake 建议您在启动安全扫描前,在本地对应用程序的新版本或补丁进行全面测试,以避免扫描失败时产生延迟和多次重复扫描。
确保各版本之间的兼容性
提供商必须确保应用程序的新版本与旧版本兼容。例如,如果应用程序有版本 v1 和 v2,那么 v2 必须与 v1 兼容。添加 v3 版本时,v3 版本必须与 v2 版本兼容。不过,由于一个应用程序同一时间只能存在两个版本,因此 v3 版本不必与 v1 版本兼容。
Code running in the previous version must handle state changes introduced in the new version. To handle stateless objects, providers should use versioned schemas to ensure that upgrades are handled correctly. See Use versioned schema to manage app objects across versions for more information.
尽量减少补丁中的状态变化
提供商必须确保新补丁不会引入与相同版本的之前补丁不同的状态变化。提供商在开发补丁时,必须尽量减少状态变化,如添加或更改表或列。表和列必须在所有版本和补丁中兼容。补丁应侧重于错误修复或小功能添加,不涉及状态修改。
状态变化只能在更新应用程序版本时进行。
从安装脚本创建对象时,请遵循安全实践
从安装脚本创建对象时,请考虑以下最佳实践:
- 使用 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 IF NOT EXISTS 版本的 CREATE 命令。
例如:
- 使用 ALTER TABLE ADD COLUMN IF NOT EXISTS 可确保仅在列不存在的情况下添加列。
- When inserting rows, implement safeguards to prevent duplicate rows if unintended, as upgrades may be retried multiple times.
创建或删除应用程序角色时应谨慎
在版本或补丁中创建或删除应用程序角色时要谨慎。应用程序角色没有版本控制。从一个版本到另一个版本时,删除应用程序角色或撤销对象上的授权可能会导致应用程序停止工作或阻止使用者访问应用程序。
避免使用 CREATE OR REPLACE APPLICATION ROLE。相反,请使用 CREATE APPLICATION ROLE IF NOT EXISTS。OR REPLACE 子句将删除并重新创建角色,这会导致权限问题,因为需要重新授予之前版本中授予应用程序角色的账户级角色。
使用容器开发应用程序的新补丁或新版本时的最佳实践
使用容器开发应用程序新版本或补丁时,提供商应考虑以下最佳实践:
-
Use caution when setting the timeout value for the SYSTEM$WAIT_FOR_SERVICES system function.
Setting this value to value that is too long may cause other part of the app to fail if they are expecting a service to be available. See 暂停执行安装脚本 for more information.
-
Snowflake recommends creating the version initializer stored procedure within a versioned schema. If the version initializer is not created within a versioned schema, the version initializer may not exist from one version to the next.
-
If an app specifies a version initializer, Snowflake recommends that the app attempts to start or upgrade services within the version initializer instead of the setup script. This ensures that the correct version of the service is running if an upgrade attempt fails.
-
版本初始化程序无需授予应用程序角色。
See 使用容器更新应用程序 for additional information on updating an app with containers.
使用容器更新应用程序
使用容器将应用程序更新到新版本时,升级过程中会有额外的注意事项。使用容器升级应用程序的过程主要分为两个阶段:
-
升级应用程序管理的容器中的服务。
Like other Snowpark Container Services, container apps use the ALTER SERVICE command to modify a service based on a service specification file for the new version. This command runs asynchronously.
-
升级应用程序中的其他对象。
After the services are successfully upgraded, other object within the app are upgraded. This is similar to the normal Snowflake Native App upgrade process. See About app upgrades for more information.
The Snowflake Native App Framework allows users to continue using an app even during major version upgrades, ensuring no downtime for a normal app. However, for apps with containers, as both CREATE SERVICE and ALTER SERVICE are asynchronous. This means that even after the upgrade finishes, the new version of the service may not be immediately available.
The potential issue when upgrading an app with containers is that the ALTER SERVICE command runs asynchronously. If this command adds the ALTER SERVICE directly to the setup script, the setup script continues to run while the service upgrade is in progress.
Providers should write their setup script assuming that service upgrades may not yet be complete or they should use SYSTEM$WAIT_FOR_SERVICES and 使用版本初始化程序管理服务升级 to guarantee the correct version of the service is ready for use.
To handle service upgrades correctly, the Snowflake Native App Framework provides features that allow the app to:
- Pause the execution of the setup script until the services upgrade successfully or fail. Providers should ensure that the setup script can handle possible situations. See 暂停执行安装脚本 for more information.
- Use the version initializer function to rollback service upgrades to the previous version if the upgrade fails. See 升级服务时的注意事项 for more information.
暂停执行安装脚本
To minimize downtime and ensure services are ready, use the SYSTEM$WAIT_FOR_SERVICES system function in the setup script after creating or altering a service:
此命令会暂停安装脚本,直到出现下列情况之一:
- 所有传递给系统函数的命名服务都具有 READY 状态。
- 任何命名的服务都有 FAILED 状态。
- 600 秒已过。
该系统函数可确保应用程序的安装或升级等到服务可用或发生故障,从而保障服务状态与版本升级同步。
升级服务时的注意事项
The Snowflake Native App Framework provides the version initializer callback function that allows providers to synchronize upgrading services with the rest of the upgrade procedure.
在基本应用程序升级的过程中,安装脚本会通过修改版本化架构中的对象来升级到新版本的应用程序。如果升级过程中发生错误,版本化架构中的对象会恢复到上一版本的应用程序。
In the case of an app with containers, services that are created or modified by running the CREATE SERVICE or ALTER SERVICE commands in the setup script use a service specification file for the new version.
Because services are not created within versioned schemas, a service is upgraded as soon as the CREATE SERVICE or ALTER SERVICE command run successfully. If there is a failure later in the setup script, for example, the objects in versioned schemas are reverted back to the previous version, but the modified services are the services of the new version.
使用版本初始化程序管理服务升级
The Snowflake Native App Framework provides a version initializer that is used to start or upgrade services or other related processes, for example tasks. The version initializer is a callback stored procedure that is specified in the manifest file.
系统会在以下情况下调用版本初始化程序:
- During installation, the version initializer is called as soon as the setup script of the app finishes without errors.
- 升级过程中,有两种可能的情况会调用版本初始化程序:
- If the setup script of the new version succeeds, then the version initializer of the new version of the app is called.
- If the setup script or the version initializer of the new version fails, then the version initializer of the previous version of the app is called. This allows the version initializer of the previous version to use the ALTER SERVICE to revert the services to the previous version.
为应用程序添加版本初始化程序
To specify the stored procedure used as the version initializer, add the following to the manifest file:
In this example, the version_initializer property is set to a stored procedure named
version_init within a schema named callback.
在安装脚本中,提供商可在版本化架构中定义该过程,如下例所示: