---
title: 【Snowflake】失敗したタスクの手動再実行が行えるようになりました！「EXECUTE TASK … RETRY LAST」
description: Snowflakeの新機能「EXECUTE TASK RETRY LAST」で失敗したタスクを手動再実行できるようになりました。バッチ更新処理の効率化に役立つ機能をご紹介します。
---

[Snowflake Knowledge - INSIGHT LAB](https://knowledge.insight-lab.co.jp/snowflake)

# [【Snowflake】失敗したタスクの手動再実行が行えるようになりました！「EXECUTE TASK … RETRY LAST」](https://knowledge.insight-lab.co.jp/snowflake/execute-task-retry-last)

 作成者: [uta](https://knowledge.insight-lab.co.jp/snowflake/author/uta)｜2024年3月01日

 

## この記事で分かること

- タスクの手動再実行「RETRY LAST」の使い方

- 従来の運用との違い

- RETRY LASTを考慮したタスクの注意点

 

## はじめに

2024年1月29日～30日のアップデートで、タスクの実行コマンドに「**EXECUTE TASK … RETRY LAST**」が追加されました。  
[https://docs.snowflake.com/en/release-notes/2024/8\_04#automatic-task-graph-retry-general-availability](https://docs.snowflake.com/en/release-notes/2024/8_04#automatic-task-graph-retry-general-availability)

このコマンドは、直近で失敗したルートタスクに対して**失敗したタスク**と**その後続タスク**のみ手動で再実行することができます。

普段Snowflakeのタスク機能を使用していないユーザにとっては「何が嬉しいの？」という機能ですが、タスクでデータパイプラインを構築しているユーザにとっては画期的な機能です。

※dbtだと「Rerun from Failure」が近い

 

## タスクのおさらい

Snowflakeでは、タスクと呼ばれるスキーマオブジェクトを作成し、クエリやプロシージャを登録することができます。

タスクが実行されると登録したSQLステートメントが実行され、データ分析基盤におけるバッチ更新処理を定時に行ったり、Snowflake運用上の定期的な作業を自動化することができます。

Snowflakeのタスクの基本的な使い方については以下の記事をご覧ください。  
[https://knowledge.insight-lab.co.jp/snowflake/create\_task](https://knowledge.insight-lab.co.jp/snowflake/create_task)

 

### バッチ更新処理

新しいコマンドを検証するため、TABLEA～TABLE\_Dの4テーブルを更新するタスクパイプラインを構築します。

このバッチ処理では、TASK\_Aを**ルートタスク**となり、TASK\_Aの正常終了をトリガーとし、TASK\_BとTASK\_Cが起動します。そしてTASK\_Cの正常終了をトリガーとし、TASK\_Dが起動します。

※通常タスクでバッチ更新処理を構成する場合は、冪等性を保証した処理をプロシージャに登録して、タスクからプロシージャをCALLするのが一般的です。

 

### 実装

テーブルの作成

> create or replace table table\_a (id varchar);  
> create or replace table table\_b (id varchar);  
> create or replace table table\_c (id number); -- ※データ型エラーを発生させる  
> create or replace table table\_d (id varchar);

タスクの作成

> create or replace task task\_a  
>     warehouse = wh\_survey\_xs  
> as  
>     insert into table\_a (id) select to\_char(current\_date(), 'yyyymmdd') || '\_a'  
> ;
> 
> create or replace task task\_b  
>     warehouse = wh\_survey\_xs  
>     after task\_a  
> as  
>     insert into table\_b (id) select to\_char(current\_date(), 'yyyymmdd') || '\_b'  
> ;
> 
> create or replace task task\_c  
>     warehouse = wh\_survey\_xs  
>     after task\_a  
> as  
>     insert into table\_c (id) select to\_char(current\_date(), 'yyyymmdd') || '\_c'  
> ;
> 
> create or replace task task\_d  
>     warehouse = wh\_survey\_xs  
>     after task\_c  
> as  
>     insert into table\_d (id) select to\_char(current\_date(), 'yyyymmdd') || '\_d'  
> ;

 

子タスクの起動

> alter task task\_b resume;  
> alter task task\_c resume;  
> alter task task\_d resume;

 

※SCHEDULE、AFTERおよびFINALIZEが設定されたタスクがトリガー条件を満たしたとき実行されるようにalter task … resumeを実行する必要があります。

タスクの状況

> show tasks in database ... ;

タスクを実行

> execute task task\_a;

TASK\_Cでデータ型不一致によるエラーが発生し、TASK\_Dはスキップされます。

 

## 従来の運用

データやロジック起因でエラーが発生した場合、タスクを手動実行して再処理を行います。しかし、従来は手動で実行できるタスクは「ルートタスクのみ」でした。

つまり、エラー原因解消後に再処理を行うにも、**TASK\_Cのみを手動実行することができず**以下の方法を取る必要がありました。

 

### リカバリ

1. TASK\_Aを手動実行し全てのタスクを再実行

1. TASK\_CとTASK\_Dに登録されているSQLステートメントをワークシートから手動実行

> -- エラー原因解消  
> create or replace table table\_c (id varchar);
> 
> -- タスク実行  
> execute task task\_a;

 

しかし、上記の方法にはいくつか問題点があります。　

 

### 問題点

1. TASK\_Aを手動実行
   
   処理によっては重複が発生※
   
   不要な実行によるウェアハウスコスト↑
2. TASK\_CとTASK\_Dに登録されているSQLステートメント自体をワークシートから実行
   
    
   
   リカバリにかかる時間↑
   
   運用ミスによるヒューマンエラーのリスク↑

※今回のタスク処理はINSERTのみのため、TASK\_Aが二度実行されるとデータが重複します。

 

## RETRY LAST

タスクDAG内で正常に終了しているタスクを除いて再実行を行える機能が「RETRY LAST」によるタスクの再実行です。

> execute task {task\_name} retry last;

 

再度エラーを発生させエラー原因を解消した後、リトライ実行を行います。

> -- テーブルを作り直す  
> create or replace table table\_a (id varchar);  
> create or replace table table\_b (id varchar);  
> create or replace table table\_c (id number); -- ※データ型エラーを発生させる  
> create or replace table table\_d (id varchar);
> 
> -- タスク実行  
> execute task task\_a;
> 
> -- エラー原因解消  
> create or replace table table\_c (id varchar);
> 
> -- 失敗しタスクのみ再実行  
> execute task task\_a retry last;

 

履歴を下から見ると、最初の実行で**TASK\_A=成功**、**TASK\_B=成功**、**TASK\_C=失敗**となった後、リトライ実行を行うと**失敗したTASK\_Cから実行**されます。その後TASK\_Dが実行されタスクが終了します。

 

また、TASK\_Aは一度しか実行されていないため、重複は発生していません。

 

## 使用条件

このRETRY LAST実行にはいくつか使用条件があります。

 

### 1. 最後の DAG 実行は状態が FAILED か CANCELED である

直近のタスクが正常終了していると、リトライ実行はエラーとなります。

 

### 2. DAG が最後に実行されてから変更されていない

エラー後、タスクに何らかの変更が加えられた場合、リトライ実行はエラーとなります。

変更とみなされるコマンド

- create or replace task …
- alter task …

| 💡タスクにはSQLではなくプロシージャを呼び出すCALL文を設定しよう   エラーがロジック起因の場合、TASKに直接SQLを設定していると**ロジック変更がタスク変更とみなされ**リトライ実行が行えなくなってしまいます。 直接SQLを設定せず、プロシージャ—にSQLを設定しタスクからプロシージャをCALLするのがベターです。 |
| --- |

 

### 3. DAG は過去14日以内に実行または再試行されている

14日を過ぎるとリトライ実行を行うことができません。

 

## おわりに

本記事では、新しく追加されたタスクのリトライ実行機能「**EXECUTE TASK … RETRY LAST**」を検証しました。

この機能により、バッチ更新処理の途中でエラーが発生しても、失敗したDAGから再実行を行うことが可能になります。

※snowsightのタスク履歴上でのリトライ実行は、通常実行とリトライ実行が合わせて表示されるようです

 

## 余談

リトライ実行にはタスク変更が許されていないため、TASKに直接SQLを設定せず、プロシージャにSQLを設定しタスクからCALLする構成。ロジックに問題があった場合はプロシージャを変更するような形が良いと思います。

プロシージャの作成例

> create or replace procedure proc\_task\_c()  
> returns varchar not null  
> language sql  
> as  
> begin  
>   insert into table\_c (id) select to\_char(current\_date(), 'yyyymmdd') || '\_c';  
>   return 'Done.';  
> end;

タスク作成例（プロシージャ呼び出し型）

> create or replace task task\_c  
>     warehouse = wh\_survey\_xs  
>     after task\_a  
> as  
>     call proc\_task\_c();  
> ;

⇒ プロシージャのSQLを修正してもタスクの変更とみなされず「RETRY LAST」が使用可能

 

また、データ分析基盤を運用するにあたり、データ更新処理を何度実行しても同じ結果となる冪等性を担保したログ・処理設計ができると運用が楽になります。

 

[完全な記事を表示](https://knowledge.insight-lab.co.jp/snowflake/execute-task-retry-last)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "uta"
  },
  "dateModified" : "2024-03-01T08:00:01.455Z",
  "datePublished" : "2024-03-01T08:00:00Z",
  "headline" : "【Snowflake】失敗したタスクの手動再実行が行えるようになりました！「EXECUTE TASK … RETRY LAST」",
  "image" : {
    "@type" : "ImageObject",
    "height" : 402,
    "url" : "https://download.insight-lab.co.jp/hubfs/rerun_retry_last.png",
    "width" : 1009
  },
  "mainEntityOfPage" : "https://knowledge.insight-lab.co.jp/snowflake/execute-task-retry-last",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "snowflakeナレッジ"
  }
}
```