预算的周期开始操作

您可以将预算配置为在预算周期重新启动时自动调用存储过程。当支出在预算的月度周期开始时重置为 0,周期将重新开始。这使您可以在每个预算期开始时运行自动化操作,例如重新启用仓库或发送有关新周期的通知。

周期开始操作对于清理或退回上一个预算周期内由 自定义操作 触发的操作特别有用。

定义周期开始操作时,指定要调用的存储过程以及要传递给它的实参。每次预算周期重新启动时,存储过程都会自动执行。

存储过程要求

周期开始操作调用的存储过程必须满足以下要求:

创建符合这些要求的存储过程后,必须向 SNOWFLAKE 应用程序授予对过程及其父数据库/架构的 USAGE 权限。例如,如果存储过程的完全限定名称是 code_db.sch1.reset_resources,则运行以下命令:

GRANT USAGE ON DATABASE code_db TO APPLICATION SNOWFLAKE;
GRANT USAGE ON SCHEMA code_db.sch1 TO APPLICATION SNOWFLAKE;
GRANT USAGE ON PROCEDURE code_db.sch1.reset_resources(STRING, STRING) TO APPLICATION SNOWFLAKE;

备注

如果在将存储过程添加到周期开始操作后更新存储过程,则必须重新授予 SNOWFLAKE 应用程序对该过程的 USAGE 权限。

为预算设置周期开始操作

您可以为每个预算(账户预算或自定义预算)设置一个周期开始操作。周期开始操作由以下组件组成:

  • 存储过程:对预算周期重新开始时要调用的过程的引用。

  • Argument:要传递给存储过程的实参数组。

要为预算设置周期开始操作,请为预算实例调用 SET_CYCLE_START_ACTION 方法。例如,以下代码设置了一个周期开始操作,该操作调用预算周期重新开始时的 reset_resources 存储过程:

CALL budget_db.sch1.my_budget!SET_CYCLE_START_ACTION(
  SYSTEM$REFERENCE('PROCEDURE', 'code_db.sch1.reset_resources(STRING, STRING, STRING, STRING)'),
  ARRAY_CONSTRUCT('my_int', 'admin@example.com', 'Budget Alert', 'New budget cycle started'));

有关包括创建由周期开始操作调用的存储过程的端到端示例,请参阅 扩展示例

从预算中移除周期开始操作

要从预算中移除周期开始操作,请为预算实例调用 REMOVE_CYCLE_START_ACTION 方法。

CALL budget_db.sch1.my_budget!REMOVE_CYCLE_START_ACTION();

扩展示例

以下示例演示了如何编写由周期开始操作调用的存储过程,授予对该过程的必要权限,然后将周期开始操作添加到预算。

  1. 创建一个 符合所有要求 的存储过程:

    CREATE OR REPLACE PROCEDURE code_db.sch1.reset_resources(
        integration_name STRING,
        email_list STRING,
        email_subject STRING,
        email_content STRING)
    RETURNS STRING
    LANGUAGE JAVASCRIPT
    EXECUTE AS OWNER
    AS
    $$
        // Re-enable warehouses or reset configurations here
        var enable_wh = "ALTER WAREHOUSE my_warehouse RESUME;";
        var statement1 = snowflake.createStatement({sqlText: enable_wh});
        statement1.execute();
    
        // Send notification about new cycle
        var sql_command = "CALL SYSTEM$SEND_EMAIL('" + INTEGRATION_NAME + "', " +
                                                "'" + EMAIL_LIST + "', " +
                                                "'" + EMAIL_SUBJECT + "'," +
                                                "'" + EMAIL_CONTENT + "'" + ");";
        var statement2 = snowflake.createStatement({sqlText: sql_command});
        statement2.execute();
        return "Resources reset for new budget cycle";
    $$;
    
  2. 将对该存储过程的权限授予 SNOWFLAKE 应用程序:

    GRANT USAGE ON DATABASE code_db TO APPLICATION SNOWFLAKE;
    GRANT USAGE ON SCHEMA code_db.sch1 TO APPLICATION SNOWFLAKE;
    GRANT USAGE ON PROCEDURE code_db.sch1.reset_resources(STRING, STRING, STRING, STRING)
      TO APPLICATION SNOWFLAKE;
    
  3. 设置预算的周期开始操作:

    CALL budget_db.sch1.my_budget!SET_CYCLE_START_ACTION(
      SYSTEM$REFERENCE('PROCEDURE', 'code_db.sch1.reset_resources(STRING, STRING, STRING, STRING)'),
      ARRAY_CONSTRUCT('my_int', 'admin@example.com', 'Budget Cycle Restarted', 'New budget cycle has begun'));
    

周期开始操作故障排除

如果周期开始操作未按预期运行,请使用以下方法诊断问题。

监控周期开始操作执行情况

Snowflake 使用任务来执行周期开始操作。此任务的名称为 _budget_cycle_start_task。要检查预算实例的所有周期开始操作任务的执行状态,请运行以下查询:用预算名称替换 budget_name

SELECT th.*, ci.name AS budget_name
  FROM SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY th
  JOIN SNOWFLAKE.ACCOUNT_USAGE.CLASS_INSTANCES ci
    ON th.instance_id = ci.id
  WHERE ci.class_name = 'BUDGET'
    AND th.name ILIKE '_budget_cycle_start_task'
    AND ci.name = '<budget_name>'
  ORDER BY th.completed_time DESC
  LIMIT 10;

对未触发的操作进行故障排除

如果周期开始操作未按预期触发,请检查以下常见问题。假设您的自定义预算是 budget_db.sch1.my_budget

存储过程或权限已更改

验证周期开始操作调用的存储过程是否仍然有效,以及 SNOWFLAKE 应用程序是否仍具有必要的权限。您可以通过运行以下命令来验证权限:

SHOW GRANTS ON PROCEDURE code_db.sch1.reset_resources(STRING, STRING, STRING, STRING);

预算未激活

仅适用于账户预算,通过调用 GET_CONFIG 方法并检查 is_active 字段来验证预算是否激活。

CALL budget_db.sch1.my_budget!GET_CONFIG();

未配置周期开始操作

验证是否为预算配置了周期开始操作:

CALL budget_db.sch1.my_budget!GET_CYCLE_START_ACTION();

预算周期尚未重新开始

仅当预算周期重新开始时,周期开始操作才会触发。检查当前周期何时开始以及何时结束,以确定下一次触发何时发生。