Skip to content

[fix](pipeline) Make fragment cancellation idempotent - #67236

Open
HappenLee wants to merge 1 commit into
apache:masterfrom
HappenLee:fix-pipeline-fragment-cancel-log-storm
Open

[fix](pipeline) Make fragment cancellation idempotent#67236
HappenLee wants to merge 1 commit into
apache:masterfrom
HappenLee:fix-pipeline-fragment-cancel-log-storm

Conversation

@HappenLee

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary:

When a query is cancelled, every pending pipeline task can be awakened and closed with the same error. TaskScheduler::close_task() calls PipelineFragmentContext::cancel() before incrementing the fragment closed-task count, so each task can repeat the fragment-wide timeout dump, instance logs, query cancellation, stream cancellation, and dependency unblocking. For a fragment with many tasks, the full task dump is therefore amplified roughly quadratically.

This change adds an atomic one-shot gate after notify_close(). The first active cancellation retains all existing behavior; later calls return before fragment-level logging and side effects. Keeping notify_close() before the gate preserves recursive CTE close handling and the already-closed removal path.

Release note

Prevent repeated BE pipeline timeout dumps when a query is cancelled.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
      • GLIBC_COMPATIBILITY=OFF ./run-be-ut.sh -j 48 --run --filter=PipelineTaskTest.TEST_FRAGMENT_CANCEL_IS_IDEMPOTENT
    • Manual test
    • No need to test or manual test.
  • Behavior changed:

    • No.
    • Yes. Duplicate fragment cancellation diagnostics and side effects are suppressed; the first cancellation is unchanged.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

A query timeout can wake every pending pipeline task. Each task then closes with the same timeout status and calls PipelineFragmentContext::cancel() before the fragment closed-task count is incremented. This repeats the full task dump and instance logs for every task, producing quadratic log amplification.

Add an atomic fragment-level gate after notify_close() so cancellation side effects run only once while preserving recursive CTE close handling. Add a unit test that verifies repeated timeout cancellation emits each fragment-level diagnostic once.

Issue Number: None

Test: GLIBC_COMPATIBILITY=OFF ./run-be-ut.sh -j 48 --run --filter=PipelineTaskTest.TEST_FRAGMENT_CANCEL_IS_IDEMPOTENT
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

std::atomic<int> _total_tasks = 0;
// Multiple tasks can observe the same query cancellation and call cancel concurrently.
// Run fragment-level cancellation side effects only once.
std::atomic_bool _cancelled = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要增加这种标记位
一个fragment的status 是由atomic status 这种来标记的。
单独的标记位,会引入问题,比如is cancelld,然后,后面可能还会增加一个string 来存储reason 这种东东

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants