Skip to content

Conversation

@xiaoxmeng
Copy link
Contributor

Summary:
Here is the race condition can cause memory leak in race between async direct coalesce load and early task failure:
T1. file reader triggers stripe load which does coalesce prefetch
T2. coalesce prefetch kicks off and pass the cancellation check
T3. coalesce load does the memory allocations and do read from storage
T4. before table scan do on-demand load, the task fails or prefetch data is skipped by filtering and task finishes.
T5. task destruction frees the memory pool hits the memory leak check failure.
T6. if we disable the memory leak check failure (with memory leak metric reporting in Meta production), then
the buffer free will throw with bad memory pool pointer.

Verified the fix with unit test that reproduce the race condition. This is exposed by pyspark use case.

Differential Revision: D71529929

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 20, 2025
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D71529929

@netlify
Copy link

netlify bot commented Mar 20, 2025

Deploy Preview for meta-velox canceled.

Name Link
🔨 Latest commit ebd682c
🔍 Latest deploy log https://app.netlify.com/sites/meta-velox/deploys/67dbba86f0e6c600085bfe1d

xiaoxmeng added a commit to xiaoxmeng/velox that referenced this pull request Mar 20, 2025
…task failure in pyspark (facebookincubator#12729)

Summary:

Here is the race condition can cause memory leak in race between async direct coalesce load and early task failure:
T1. file reader triggers stripe load which does coalesce prefetch
T2. coalesce prefetch kicks off and pass the cancellation check
T3. coalesce load does the memory allocations and do read from storage
T4. before table scan do on-demand load, the task fails or prefetch data is skipped by filtering and task finishes.
T5. task destruction frees the memory pool hits the memory leak check failure.
T6. if we disable the memory leak check failure (with memory leak metric reporting in Meta production), then
the buffer free will throw with bad memory pool pointer.

Verified the fix with unit test that reproduce the race condition. This is exposed by pyspark use case.

Differential Revision: D71529929
…task failure in pyspark (facebookincubator#12729)

Summary:
Pull Request resolved: facebookincubator#12729

Here is the race condition can cause memory leak in race between async direct coalesce load and early task failure:
T1. file reader triggers stripe load which does coalesce prefetch
T2. coalesce prefetch kicks off and pass the cancellation check
T3. coalesce load does the memory allocations and do read from storage
T4. before table scan do on-demand load, the task fails or prefetch data is skipped by filtering and task finishes.
T5. task destruction frees the memory pool hits the memory leak check failure.
T6. if we disable the memory leak check failure (with memory leak metric reporting in Meta production), then
the buffer free will throw with bad memory pool pointer.

Verified the fix with unit test that reproduce the race condition. This is exposed by pyspark use case.

Differential Revision: D71529929
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D71529929

Copy link
Contributor

@tanjialiang tanjialiang left a comment

Choose a reason for hiding this comment

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

Thanks for the quick fix

@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 48b9803.

@conbench-facebook
Copy link

Conbench analyzed the 1 benchmark run on commit 48b98030.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details.

jinchengchenghh pushed a commit to jinchengchenghh/velox that referenced this pull request Apr 4, 2025
…task failure in pyspark (facebookincubator#12729)

Summary:
Pull Request resolved: facebookincubator#12729

Here is the race condition can cause memory leak in race between async direct coalesce load and early task failure:
T1. file reader triggers stripe load which does coalesce prefetch
T2. coalesce prefetch kicks off and pass the cancellation check
T3. coalesce load does the memory allocations and do read from storage
T4. before table scan do on-demand load, the task fails or prefetch data is skipped by filtering and task finishes.
T5. task destruction frees the memory pool hits the memory leak check failure.
T6. if we disable the memory leak check failure (with memory leak metric reporting in Meta production), then
the buffer free will throw with bad memory pool pointer.

Verified the fix with unit test that reproduce the race condition. This is exposed by pyspark use case.

Reviewed By: tanjialiang, oerling

Differential Revision: D71529929

fbshipit-source-id: de1c545c48dc23602a79238b878020ce2f29c4f4
@fzhedu
Copy link

fzhedu commented Jul 25, 2025

@xiaoxmeng
why not let the main thread wait all IO threads to be finished? one possible case happen that the main thread ~memoryManager, but the scan pool is still held by the IO threads, causing core dump.

  ~DirectBufferedInput() override {
    std::vector<folly::Future<bool>> futures;
    for (auto& load : coalescedLoads_) {
      load->cancel();
      futures.push_back(load->getCompletionFuture());
    }
    if (!futures.empty()) {
      LOG(WARNING) << "wait " << futures.size() << " loads to be completed";
      folly::collectAll(futures).wait();
    }

@j7nhai
Copy link

j7nhai commented Sep 4, 2025

@xiaoxmeng why not let the main thread wait all IO threads to be finished? one possible case happen that the main thread ~memoryManager, but the scan pool is still held by the IO threads, causing core dump.

  ~DirectBufferedInput() override {
    std::vector<folly::Future<bool>> futures;
    for (auto& load : coalescedLoads_) {
      load->cancel();
      futures.push_back(load->getCompletionFuture());
    }
    if (!futures.empty()) {
      LOG(WARNING) << "wait " << futures.size() << " loads to be completed";
      folly::collectAll(futures).wait();
    }

Actually, the core dump is caused by memory leak. refer to my PR fix: #14722

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants