根据 Snowflake 中的数据设置警报

本主题解释如何根据 Snowflake 中的数据,设置在特定条件下定期执行操作的警报。

简介

在某些情况下,您可能希望在 Snowflake 中的数据满足某些条件时收到通知或采取措施。例如,您可能希望在以下情况下收到通知:

  • 仓库 credit 使用量按当前配额的指定百分比增加。

  • 管道、任务、物化视图等资源消耗超过了指定数量。

  • 您的数据不符合您设置的特定业务规则。

为此,您可以设置 Snowflake 警报。Snowflake 警报是一个架构级对象,可用于指定以下内容:

  • 触发警报的条件(例如,存在完成时间超过一秒的查询)。

  • 满足条件时要执行的操作(例如,发送电子邮件通知、获取表中的某些数据等)。

  • 评估条件的时间和频率(例如,每 24 小时、每周日午夜等)。

例如,假设您希望在仓库的 credit 使用量超过某个限值时发送电子邮件通知。假设您希望每 30 分钟检查一次。您可以创建具有以下属性的警报:

  • 条件:仓库的 credit 使用量( ACCOUNT_USAGE 架构中的 WAREHOUSE_METERING_HISTORY 视图内 credits_used 列的总和)超出了指定的限制。

  • 操作:向管理员发送电子邮件。

  • 频率/计划:每 30 分钟检查一次此条件。

为警报选择仓库

警报需要 仓库 才能执行。您可以使用 无服务器计算模型您指定的虚拟仓库

使用无服务器计算模型(无服务器警报)

使用无服务器计算模型的警报称为 无服务器警报。如果使用无服务器计算模型,Snowflake 会自动调整和缩放警报所需的计算资源。Snowflake 对同一警报近期运行的统计数据执行动态分析,并根据结果确定给定运行的计算资源的理想大小。无服务器警报运行的最大大小等于 XXLARGE 仓库的大小。您账户中的多个工作负载共享一组通用的计算资源。

计费类似于其他无服务器功能(如 Serverless Task)。请参阅 了解警报的成本

使用您指定的虚拟仓库

如果要指定虚拟仓库,则必须为警报执行的 SQL 操作选择大小合适的仓库。有关选择仓库的准则,请参阅 仓库注意事项

了解警报的成本

与运行警报以执行 SQL 代码相关的费用因警报所使用的计算资源而异:

  • 对于无服务器警报,Snowflake 根据计算资源的实际使用量向您的账户计费。费用根据资源的总使用量(包括云服务使用量)计算,衡量方式是 计算小时 Credit 使用量。计算小时的成本根据仓库规模和查询运行时而变化。有关更多信息,请参阅 无服务器 Credit 使用量

    要了解任务消耗了多少 credit,请参阅 Snowflake 服务使用表 中的“无服务器功能 credit 表”。

  • 对于使用您指定的虚拟仓库的警报,Snowflake 会根据警报运行时的仓库使用量向您的账户收取 Credit 使用量。这类似于在客户端或 Snowsight 中执行相同 SQL 语句的仓库使用量。每秒 Credit 计费和仓库自动暂停功能可以让您灵活地从规模较大的仓库开始,然后调整大小以匹配您的警报工作负载。

授予创建警报的权限

要创建警报,您必须使用具有以下权限的角色:

  • 账户的 EXECUTE ALERT 权限。

    备注

    此权限只能由具有 ACCOUNTADMIN 角色的用户授予。

  • 以下权限之一:

    • 账户的 EXECUTE MANAGED ALERT 权限(如果要创建无服务器警报)。

    • 用于执行警报的仓库的 USAGE 权限(如果要为警报指定虚拟仓库)。

  • 要在其中创建警报的架构的 USAGE 和 CREATE ALERT 权限。

  • 包含架构的数据库的 USAGE 权限。

要向角色授予这些权限,请使用 GRANT <privileges> 命令。

例如,假设您要创建一个名为 my_alert_role 的自定义角色,该角色具有在名为 my_schema 的架构中创建警报的权限。您希望警报使用仓库 my_warehouse

要这样做,请执行以下操作:

  1. 让具有 ACCOUNTADMIN 角色的用户执行以下操作:

    1. 创建自定义角色

      例如:

      USE ROLE ACCOUNTADMIN;
      
      CREATE ROLE my_alert_role;
      
      Copy
    2. 向该自定义角色授予 EXECUTE ALERT 全局权限。

      例如:

      GRANT EXECUTE ALERT ON ACCOUNT TO ROLE my_alert_role;
      
      Copy
    3. 如果要创建无服务器警报,请将 EXECUTE MANAGED ALERT 全局权限授予该自定义角色。

      例如:

      GRANT EXECUTE MANAGED ALERT ON ACCOUNT TO ROLE my_alert_role;
      
      Copy
    4. 向用户授予自定义角色。

      例如:

      GRANT ROLE my_alert_role TO USER my_user;
      
      Copy
  2. 让数据库、架构和仓库的所有者向自定义角色授予创建警报所需的权限:

    • 架构的所有者必须授予架构的 CREATE ALERT 和 USAGE 权限:

      GRANT CREATE ALERT ON SCHEMA my_schema TO ROLE my_alert_role;
      GRANT USAGE ON SCHEMA my_schema TO ROLE my_alert_role;
      
      Copy
    • 数据库的所有者必须授予数据库的 USAGE 权限:

      GRANT USAGE ON DATABASE my_database TO ROLE my_alert_role;
      
      Copy
    • 如果要为警报指定仓库,则该仓库的所有者必须对仓库授予 USAGE 权限:

      GRANT USAGE ON WAREHOUSE my_warehouse TO ROLE my_alert_role;
      
      Copy

创建警报

假设每当名为 gauge 的表中的一个或多个行的 gauge_value 列的值超过 200 时,您希望将当前时间戳插入到名为 gauge_value_exceeded_history 的表中。

您可以创建一个警报来执行以下操作:

  • 评估 gauge_value 超过 200 的条件。

  • 如果此条件评估结果为 true,则将时间戳插入到 gauge_value_exceeded_history 中。

要创建名为 my_alert 的警报,请执行以下操作:

  1. 验证您使用的角色具有 创建警报的权限

    如果您没有使用该角色,请执行 USE ROLE 命令以使用该角色。

  2. 验证您使用的是计划为其创建警报的数据库和架构。

    如果没有使用该数据库和架构,请执行 USE DATABASEUSE SCHEMA 命令以使用该数据库和架构。

  3. 执行 CREATE ALERT 命令,以创建警报:

    CREATE OR REPLACE ALERT my_alert
      WAREHOUSE = mywarehouse
      SCHEDULE = '1 minute'
      IF( EXISTS(
        SELECT gauge_value FROM gauge WHERE gauge_value>200))
      THEN
        INSERT INTO gauge_value_exceeded_history VALUES (current_timestamp());
    
    Copy

    如果要创建无服务器警报,请省略 WAREHOUSE 参数:

    CREATE OR REPLACE ALERT my_alert
      SCHEDULE = '1 minute'
      IF( EXISTS(
        SELECT gauge_value FROM gauge WHERE gauge_value>200))
      THEN
        INSERT INTO gauge_value_exceeded_history VALUES (current_timestamp());
    
    Copy

    有关 CREATE ALERT 命令的完整描述,请参阅 CREATE ALERT

    备注

    创建警报时,警报默认情况下处于暂停状态。必须恢复新创建的警报,警报才能执行。

  4. 通过执行 ALTER ALERT ...RESUME 命令来执行完全刷新。例如:

    ALTER ALERT my_alert RESUME;
    
    Copy

根据警报计划指定时间戳

在某些情况下,您可能需要根据警报计划定义条件或操作。

例如,假设一个表有一个时间戳列,表示添加一行的时间,并且如果在上次成功评估的警报和当前计划的警报之间添加了任何新行,则要发送警报。换句话说,您要评估以下内容:

<now> - <last_execution_of_the_alert>
Copy

如果使用 CURRENT_TIMESTAMP 和警报的计划时间来计算此时间范围,则计算得出的范围不会考虑计划警报的时间与实际评估警报条件的时间之间的延迟。

相反,当您需要当前计划警报的时间戳和上次成功评估警报的时间戳时,请使用以下函数:

这些函数在 SNOWFLAKE.ALERT 架构 中定义。要调用这些函数,您需要使用已被授予 SNOWFLAKE.ALERT_VIEWER 数据库角色 的角色。要将此角色授予另一个角色,请使用 GRANT DATABASE ROLE 命令。例如,要将此角色授予自定义角色 alert_role,请执行以下命令:

GRANT DATABASE ROLE SNOWFLAKE.ALERT_VIEWER TO ROLE alert_role;
Copy

如果在计划上次成功评估的警报的时间与计划当前警报的时间之间 my_table 添加了任何新行,则以下示例将发送电子邮件:

CREATE OR REPLACE ALERT alert_new_rows
  WAREHOUSE = my_warehouse
  SCHEDULE = '1 MINUTE'
  IF (EXISTS (
      SELECT *
      FROM my_table
      WHERE row_timestamp BETWEEN SNOWFLAKE.ALERT.LAST_SUCCESSFUL_SCHEDULED_TIME()
       AND SNOWFLAKE.ALERT.SCHEDULED_TIME()
  ))
  THEN CALL SYSTEM$SEND_EMAIL(...);
Copy

检查警报操作中条件的 SQL 语句结果

在警报操作中,如果需要检查条件 SQL 语句的结果,请执行以下操作:

  1. 调用 GET_CONDITION_QUERY_UUID 函数以获取条件 SQL 语句的 ID 查询。

  2. 将查询 ID 传递给 RESULT_SCAN 函数以获取该 SQL 语句的执行结果。

例如:

CREATE ALERT my_alert
  WAREHOUSE = my_warehouse
  SCHEDULE = '1 MINUTE'
  IF (EXISTS (
    SELECT * FROM my_source_table))
  THEN
    BEGIN
      LET condition_result_set RESULTSET :=
        (SELECT * FROM TABLE(RESULT_SCAN(SNOWFLAKE.ALERT.GET_CONDITION_QUERY_UUID())));
      ...
    END;
Copy

手动执行警报

在某些情况下,您可能需要手动执行警报。例如:

  • 如果要创建新警报,您可能需要验证警报是否按预期工作。

  • 您可能希望在数据管道中的特定点执行警报。例如,您可能希望在存储过程调用结束时执行警报。

要手动执行警报,请运行以下 EXECUTE ALERT 命令:

EXECUTE ALERT my_alert;
Copy

EXECUTE ALERT 命令可手动触发警报的单次运行,与为警报定义的计划无关。

您可以交互方式执行此命令。您也可以从存储过程或 Snowflake Scripting 块中执行此命令。

有关运行此命令所需的权限以及此命令对暂停、正在运行和计划警报的影响的详细信息,请参阅 EXECUTE ALERT

暂停和恢复警报

如果需要暂时阻止警报执行,可以通过执行 ALTER ALERT...SUSPEND 命令来执行完全刷新。例如:

ALTER ALERT my_alert SUSPEND;
Copy

要恢复暂停的警报,请执行 ALTER ALERT ...RESUME 命令来执行完全刷新。例如:

ALTER ALERT my_alert RESUME;
Copy

备注

如果您不是警报的所有者,则必须具有警报的 OPERATE 权限才能暂停或恢复警报。

修改警报

要修改警报的属性,请执行 ALTER ALERT 命令。例如:

  • 要将名为 my_alert 的警报的仓库更改为 my_other_warehouse,请执行以下命令:

    ALTER ALERT my_alert SET WAREHOUSE = my_other_warehouse;
    
    Copy
  • 要将名为 my_alert 的警报的计划更改为每2 分钟评估一次,请执行以下命令:

    ALTER ALERT my_alert SET SCHEDULE = '2 minutes';
    
    Copy
  • 要更改名为 my_alert 的警报的条件,以便在名为 gauge 的表中的任何行的 gauge_value 列中的值大于 300 时发出警报,请执行以下命令:

    ALTER ALERT my_alert MODIFY CONDITION EXISTS (SELECT gauge_value FROM gauge WHERE gauge_value>300);
    
    Copy
  • 要将名为 my_alert 的警报的操作 更改为 CALL my_procedure(),请执行以下命令:

    ALTER ALERT my_alert MODIFY ACTION CALL my_procedure();
    
    Copy

备注

您必须是警报的所有者才能修改警报的属性。

弃用警报

要弃用警报,请执行 DROP ALERT 命令。例如:

DROP ALERT my_alert;
Copy

要弃用警报且当警报不存在时不引发错误,请执行以下命令:

DROP ALERT IF EXISTS my_alert;
Copy

备注

您必须是警报的所有者才能弃用警报。

查看有关警报的详细信息

要列出已在账户、数据库或架构中创建的警报,请执行 SHOW ALERTS 命令。例如,要列出在当前架构中创建的警报,请运行以下命令:

SHOW ALERTS;
Copy

此命令会列出您拥有的警报以及您对其具有 MONITOR 或 OPERATE 权限的警报。

要查看有关特定警报的详细信息,请执行 DESCRIBE ALERT 命令。例如:

DESC ALERT my_alert;
Copy

备注

如果您不是警报的所有者,则必须对警报具有 MONITOR 或 OPERATE 权限才能查看警报的详细信息。

克隆警报

您可以克隆警报(通过使用 CREATE ALERT ...CLONE 或通过克隆包含警报的数据库或架构)。

如果要克隆无服务器警报,则无需使用具有全局 EXECUTE MANAGED ALERT 权限的角色。但是,在拥有该警报的角色被授予 EXECUTE MANAGED ALERT 权限之前,您将无法恢复该警报。

监控警报的执行情况

要监控警报的执行情况,您可以执行以下操作:

  • 检查为警报指定的操作的结果。例如,如果操作将行插入到表中,则可以检查表中是否有新行。

  • 使用以下对象之一查看警报执行的历史记录:

    • INFORMATION_SCHEMA 架构中的 ALERT_HISTORY 表函数。

      例如,要查看过去一小时内警报的执行情况,请执行以下语句:

      SELECT *
      FROM
        TABLE(INFORMATION_SCHEMA.ALERT_HISTORY(
          SCHEDULED_TIME_RANGE_START
            =>dateadd('hour',-1,current_timestamp())))
      ORDER BY SCHEDULED_TIME DESC;
      
      Copy
    • 共享 SNOWFLAKE 数据库中 ACCOUNT_USAGE 架构中的 ALERT_HISTORY 视图。

在查询历史记录中,执行查询的用户名应为 SYSTEM。(警报由 系统服务 运行。)

查看无服务器警报的查询历史记录

要查看无服务器警报的查询历史记录,您必须是警报的所有者,或者您必须使用对警报本身具有 MONITOR 或 OPERATE 权限的角色。(这与使用您的一个仓库的警报不同,后者需要仓库具有 MONITOR 或 OPERATOR 权限。)

例如,假设您要在查看警报 my_alert 的查询历史记录时使用 my_alert_role 角色。如果 my_alert_role 不是 my_alert 的所有者,则您必须 授予 该角色对于该警报的 MONITOR 或 OPERATE 权限:

GRANT MONITOR ON ALERT my_alert TO ROLE my_alert_role;
Copy

授予角色此权限后,您可以使用该角色查看警报的查询历史记录:

USE ROLE my_alert_role;
Copy
SELECT query_text FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY())
  WHERE query_text LIKE '%Some condition%'
    OR query_text LIKE '%Some action%
  ORDER BY start_time DESC;
Copy
语言: 中文