Skip to content

[A01] analyze/apply that loads 300+ CSV files per table hangs CheckAndFinalize until Step Functions execution timeout #1

@ogawsh

Description

@ogawsh

[A01] analyze/apply がテーブルごとに 300+ ファイルの CSV を読む時、CheckAndFinalize が無限ポーリングで SFn タイムアウトになる

再現条件

  • 1 プレフィックス配下に 同一ヘッダの CSV が 300 本以上(今回は 350 本、各 ~10GB / 合計 ~1TB 規模を想定)
  • Admin UI から analyzeapply
  • apply が裏で起動する Step Functions AdminBackendInitWorkflowStateMachine が TIMED_OUT

観測された挙動

  • Step Functions execution が 7200 秒ちょうどで TIMED_OUT
  • Admin UI は "Unknown error" としか表示しない
  • StartBuild Lambda は 140 秒で正常終了(DROP / CREATE / _execute_sql_async で COPY を 350 本発行し Data API から Id を受領)
  • CheckAndFinalize Lambda は 10 秒 Wait → 140ms で {all_done: false, completed_tables: 0} を返すループを ~700 回繰り返して 2 時間
  • Redshift Serverless の sys_query_history / sys_load_history を同時間帯で検索しても COPY 履歴は 0 件
  • 発行した statement_id を redshift-data describe-statement で直叩きすると ResourceNotFoundException: Query does not exist

原因(推定)

1. CheckAndFinalize に独自タイムアウト / 最大試行回数がない(致命的)

lambda/redshiftinitworkflow/handlers.pyhandle_check_and_finalize:

for table_name, stmt_ids in statement_ids.items():
    ...
    for stmt_id in stmt_ids:
        desc = redshift_data.describe_statement(Id=stmt_id)
        status = desc["Status"]
        ...
        elif status != "FINISHED":
            table_running = True
            break
    ...
if still_running:
    return {"all_done": False, ...}
  • still_running になったら 10 秒後にまた呼ばれて再評価するだけで、独自のタイムアウトや再試行上限がない
  • COPY が何らかの理由で Redshift に届かず Data API の SUBMITTED / PICKED で滞留した場合、このループから抜けられない
  • SFn の TimeoutSeconds 7200 が唯一の脱出口で、失敗時に意味のあるエラーを返せていない(→ UI「Unknown error」)

2. StartBuild が同時実行数制御なしに execute_statement を大量投入

  • _execute_sql_async は Data API に直列で 350 本投げるだけ
  • Redshift Serverless は同時実行数制限があり(RPU / ワークグループ設定依存)、Data API 側の Active Statement 制限(default 200)もある
  • 上限超えで SUBMITTED のまま滞留すると、Redshift 側で実行されず sys_query_history に記録されない
  • COPY ... MANIFEST を使って 1 テーブル = 1 COPY に集約する / 同時投入数に上限をつける等の保護が無い

3. 進捗の可視化がない

  • CheckAndFinalize はテーブル単位で「最初の非 FINISHED で break」するので、completed_statements / total_statements の粒度で進捗を返せない
  • UI 側は completed_tables しか受け取れず、3 時間進捗 0 のまま等の判別ができない

再現手順

  1. 任意の S3 プレフィックスに同一ヘッダの CSV を 300 本以上配置(1 ファイル数 GB 推奨)
  2. Admin UI から該当プレフィックスを指定して Agent を作成、analyze 実行
  3. 生成された DDL で apply 実行
  4. AdminBackendInitWorkflowStateMachine が 2 時間で TIMED_OUT することを観測

期待される挙動

  • ファイル数が多い場合でも合理的な時間内に完了するか、明示的に「ファイル数が多すぎる」「COPY が詰まっている」旨のエラーを返す
  • 具体的には以下のいずれか / 組み合わせ:
    • COPY を MANIFEST オプションで 1 テーブル = 1 COPY にまとめる
    • CheckAndFinalize に試行回数上限を設け、超過時は status: stuck で SFn を明示失敗させる
    • Data API の同時実行数制限を意識して execute_statement をバッチ投入する
    • Admin UI が SFn の ExecutionTimedOut / ExecutionFailed を受け取って具体的なメッセージを表示する

参考情報

  • 対象スタック: arn:aws:cloudformation:ap-northeast-1:411521242467:stack/devDwhAgentStack/6619ffe0-3f8b-11f1-a3dc-068ad41190bd
  • SFn execution ARN: arn:aws:states:ap-northeast-1:411521242467:execution:AdminBackendInitWorkflowStateMachine4193125B-ArEyUWKHNQd8:16479835-502e-4e6d-86a9-4ed68ba7b173
  • Redshift Serverless workgroup: Base 8 RPU / max 未設定
  • 関連ファイル: lambda/redshiftinitworkflow/handlers.py_execute_sql_async, handle_check_and_finalize

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions