Skip to content

AQE: handle executor failure on the adaptive execution path #1986

Open

Description

@andygrove

Is your feature request related to a problem or challenge?

The adaptive execution path (AdaptiveExecutionGraph / AdaptivePlanner) currently covers the happy path only and "does not cover executor failure". When AQE is enabled, the scheduler builds the stage DAG incrementally and re-optimizes the remaining plan as each shuffle stage completes. If an executor is lost, the runtime statistics and shuffle output that adaptive decisions were based on may no longer be available, and the AQE path has no recovery logic equivalent to the static StaticExecutionGraph path.

Describe the solution you'd like

Support executor-failure recovery on the AQE path: detect lost shuffle output for stages the adaptive planner has already resolved/consumed, re-run the affected stage(s), and re-drive adaptive re-optimization consistently after recovery.

Additional context

Related general failure-handling issues (not AQE-path specific): #1795, #1908.

Context

This is one of the documented limitations of the experimental Adaptive Query Execution (AQE) path, listed in docs/source/user-guide/tuning-guide.md under "Current limitations" and in the doc comment on AdaptiveExecutionGraph (ballista/scheduler/src/state/aqe/mod.rs). Filing a discrete tracking issue so the gap is visible outside the doc.

Parent epic: #1359

Activity

  1. andygrove commented on Oct 14, 2026

    @andygrove
    MemberAuthor

    Some specifics from reading AdaptiveExecutionGraph::update_task_status side by side with the static graph, at commit ea1126c, that are relevant here:

    • The reset-running-stages path is dead code on the AQE graph. reset_running_stages is declared as an immutable empty map (aqe/mod.rs#L817), so the reset loop at L1106-L1130 never runs and the !reset_running_stages.contains_key(&stage_id) check at L1013 is always true. In the static graph the same map is mut and is populated by the late fetch-failure handling.
    • The late fetch-failure path for UnResolved stages is missing. StaticExecutionGraph::update_task_status handles fetch failures reported for stages that are still UnResolved (execution_graph.rs#L1016-L1088); the AQE copy has no equivalent, which is the main source of the dead code above.
    • The max-task-failures message is less useful on AQE. The AQE copy reports only the internal task slot id (aqe/mod.rs#L942-L948), while the static copy reports the partitions that exceeded the limit (execution_graph.rs#L910-L937).

    These are all consequences of the two update_task_status implementations being separate copies. #2595 tracks sharing the execution-graph code between the static and adaptive graphs, which would let the recovery logic here be implemented once. A related AQE-only bug where a stage is dropped from the graph on a failed conversion is #2594.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions