Skip to content

GH-46224: [C++][Acero] Fix the hang in asof join - #46300

Merged
zanmato1984 merged 9 commits into
apache:mainfrom
zanmato1984:fix/gh-46224
May 14, 2025
Merged

GH-46224: [C++][Acero] Fix the hang in asof join#46300
zanmato1984 merged 9 commits into
apache:mainfrom
zanmato1984:fix/gh-46224

Conversation

@zanmato1984

@zanmato1984zanmato1984 commented May 3, 2025

Copy link
Copy Markdown
Contributor

Rationale for this change

A hang of asof join is reported in #46224 . To explain the cause of the hang, I shall first brief the basic processing of asof join.

There is an outstanding processing thread for the asof join, whose lifespan is bound to the asof node. This thread will wait on a command queue. Once a command is pushed into the queue, the thread pops it and do one round of processing. The command is issued as the batches are received from either left or right side input of the asof join node. Each round of processing will advance the accumulated left and right inputs as much as possible to see if it is sufficient to output a batch (if yes, i.e., either side of the asof join can be concluded by the latest input timestamp, then emit it, otherwise adjust the internal state according to the latest input timestamp).

Notably, the processing is by design to advance the inputs "as much as possible". However there is a bug (seemingly since day 1) when advancing the right side input in a tricky condition: if all right side rows are at the times before the least time of the left rows, then advancing the right side input won't cross batches in one round of processing. This is OK (i.e., no hang) as long as there are enough commands issued into the queue to trigger enough rounds of processing. However if lucky enough, say, the left input batches come late, then the processing with consume some commands issued by the right side input but advance nothing (because the left side input is empty), resulting in insufficient commands to fully advance both the input.

What changes are included in this PR?

Fix the issue that advancing the right side input won't cross batches when the minimal left time is bigger than all the right times.

Are these changes tested?

Yes, added a dedicated case.

Are there any user-facing changes?

None.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #46224has been automatically assigned in GitHub to PR creator.

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

@github-actions crossbow submit -g cpp -g r

@github-actions

Copy link
Copy Markdown

Revision: aa5a9be

Submitted crossbow builds: ursacomputing/crossbow @ actions-d733af0ab3

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
r-binary-packagesGitHub Actions
r-recheck-mostGitHub Actions
test-alpine-linux-cppGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-mesonGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-cuda-cpp-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-debian-12-cpp-amd64GitHub Actions
test-debian-12-cpp-i386GitHub Actions
test-fedora-39-cppGitHub Actions
test-r-arrow-backwards-compatibilityGitHub Actions
test-r-clang-sanitizerGitHub Actions
test-r-depsource-bundledAzure
test-r-depsource-systemGitHub Actions
test-r-dev-duckdbGitHub Actions
test-r-devdocsGitHub Actions
test-r-extra-packagesGitHub Actions
test-r-gcc-11GitHub Actions
test-r-gcc-12GitHub Actions
test-r-install-localGitHub Actions
test-r-install-local-minsizerelGitHub Actions
test-r-linux-as-cranGitHub Actions
test-r-linux-rchkGitHub Actions
test-r-linux-sanitizerGitHub Actions
test-r-linux-valgrindGitHub Actions
test-r-macos-as-cranGitHub Actions
test-r-minimal-buildAzure
test-r-offline-maximalGitHub Actions
test-r-offline-minimalAzure
test-r-rhub-debian-gcc-devel-lto-latestAzure
test-r-rhub-debian-gcc-release-custom-ccacheAzure
test-r-rhub-ubuntu-release-latestAzure
test-r-rocker-r-ver-latestAzure
test-r-rstudio-r-base-4.1-opensuse155Azure
test-r-rstudio-r-base-4.2-focalAzure
test-r-ubuntu-22.04GitHub Actions
test-r-versionsGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-20GitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

@github-actions crossbow submit -g cpp -g r

@github-actions

Copy link
Copy Markdown

Revision: 6ea4624a8ec7c27ab7c57bdcacf295995d0e12a5

Submitted crossbow builds: ursacomputing/crossbow @ actions-a2fa793a58

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
r-binary-packagesGitHub Actions
r-recheck-mostGitHub Actions
test-alpine-linux-cppGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-mesonGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-cuda-cpp-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-debian-12-cpp-amd64GitHub Actions
test-debian-12-cpp-i386GitHub Actions
test-fedora-39-cppGitHub Actions
test-r-arrow-backwards-compatibilityGitHub Actions
test-r-clang-sanitizerGitHub Actions
test-r-depsource-bundledAzure
test-r-depsource-systemGitHub Actions
test-r-dev-duckdbGitHub Actions
test-r-devdocsGitHub Actions
test-r-extra-packagesGitHub Actions
test-r-gcc-11GitHub Actions
test-r-gcc-12GitHub Actions
test-r-install-localGitHub Actions
test-r-install-local-minsizerelGitHub Actions
test-r-linux-as-cranGitHub Actions
test-r-linux-rchkGitHub Actions
test-r-linux-sanitizerGitHub Actions
test-r-linux-valgrindGitHub Actions
test-r-macos-as-cranGitHub Actions
test-r-minimal-buildAzure
test-r-offline-maximalGitHub Actions
test-r-offline-minimalAzure
test-r-rhub-debian-gcc-devel-lto-latestAzure
test-r-rhub-debian-gcc-release-custom-ccacheAzure
test-r-rhub-ubuntu-release-latestAzure
test-r-rocker-r-ver-latestAzure
test-r-rstudio-r-base-4.1-opensuse155Azure
test-r-rstudio-r-base-4.2-focalAzure
test-r-ubuntu-22.04GitHub Actions
test-r-versionsGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-20GitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

IMO this code is apparently NOT doing what it is supposed to do: by here the have_active_batch must be true, meaning queue_ must be non-empty. Then popping the queue always gets a valid std::optional and effectively setting have_active_batch to false. The if branch below won't be executed.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I noticed there are two fixes made before in the following if branch #36094 and #36499. Given that this have_active_batch &= !queue_.TryPop() exists since #13028 where it was introduced, and the lack of corresponding tests, I'm not sure how they fixed anything and what the bugs even were. So I just remove them.

@zanmato1984
zanmato1984 marked this pull request as ready for review May 6, 2025 23:14
@github-actionsgithub-actionsBot added awaiting committer review Awaiting committer review and removed awaiting review Awaiting review labels May 6, 2025
@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

Hi, @westonpace@icexelloss@pitrou would you help to review? Thanks.

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

@github-actions crossbow submit -g cpp -g python -g r

@github-actions

Copy link
Copy Markdown

Revision: af70071

Submitted crossbow builds: ursacomputing/crossbow @ actions-ccf7708cfd

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
example-python-minimal-build-fedora-condaGitHub Actions
example-python-minimal-build-ubuntu-venvGitHub Actions
r-binary-packagesGitHub Actions
r-recheck-mostGitHub Actions
test-alpine-linux-cppGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-mesonGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-conda-python-3.10GitHub Actions
test-conda-python-3.10-hdfs-2.9.2GitHub Actions
test-conda-python-3.10-hdfs-3.2.1GitHub Actions
test-conda-python-3.10-pandas-latest-numpy-latestGitHub Actions
test-conda-python-3.11GitHub Actions
test-conda-python-3.11-dask-latestGitHub Actions
test-conda-python-3.11-dask-upstream_develGitHub Actions
test-conda-python-3.11-hypothesisGitHub Actions
test-conda-python-3.11-pandas-latest-numpy-1.26GitHub Actions
test-conda-python-3.11-pandas-latest-numpy-latestGitHub Actions
test-conda-python-3.11-pandas-nightly-numpy-nightlyGitHub Actions
test-conda-python-3.11-pandas-upstream_devel-numpy-nightlyGitHub Actions
test-conda-python-3.11-spark-masterGitHub Actions
test-conda-python-3.12GitHub Actions
test-conda-python-3.12-cpython-debugGitHub Actions
test-conda-python-3.13GitHub Actions
test-conda-python-3.9GitHub Actions
test-conda-python-3.9-pandas-1.1.3-numpy-1.19.5GitHub Actions
test-conda-python-emscriptenGitHub Actions
test-cuda-cpp-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-cuda-python-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-debian-12-cpp-amd64GitHub Actions
test-debian-12-cpp-i386GitHub Actions
test-debian-12-python-3-amd64GitHub Actions
test-debian-12-python-3-i386GitHub Actions
test-fedora-39-cppGitHub Actions
test-fedora-39-python-3GitHub Actions
test-r-arrow-backwards-compatibilityGitHub Actions
test-r-clang-asanGitHub Actions
test-r-clang-ubsanGitHub Actions
test-r-depsource-bundledAzure
test-r-depsource-systemGitHub Actions
test-r-dev-duckdbGitHub Actions
test-r-devdocsGitHub Actions
test-r-extra-packagesGitHub Actions
test-r-gcc-11GitHub Actions
test-r-gcc-12GitHub Actions
test-r-install-localGitHub Actions
test-r-install-local-minsizerelGitHub Actions
test-r-linux-as-cranGitHub Actions
test-r-linux-rchkGitHub Actions
test-r-linux-sanitizerGitHub Actions
test-r-linux-valgrindGitHub Actions
test-r-m1-sanGitHub Actions
test-r-macos-as-cranGitHub Actions
test-r-minimal-buildAzure
test-r-offline-maximalGitHub Actions
test-r-offline-minimalAzure
test-r-rhub-debian-gcc-devel-lto-latestAzure
test-r-rhub-debian-gcc-release-custom-ccacheAzure
test-r-rhub-ubuntu-release-latestAzure
test-r-rocker-r-ver-latestAzure
test-r-rstudio-r-base-4.1-opensuse155Azure
test-r-rstudio-r-base-4.2-focalAzure
test-r-ubuntu-22.04GitHub Actions
test-r-versionsGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-20GitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-22.04-python-3GitHub Actions
test-ubuntu-22.04-python-313-freethreadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions
test-ubuntu-24.04-python-3GitHub Actions

Comment threadcpp/src/arrow/acero/asof_join_node.cc Outdated
Comment threadcpp/src/arrow/acero/asof_join_node_test.cc
@pitrou

Copy link
Copy Markdown
Member

I'm curious, this does only happen when the right side is concerned? The update logic is not symmetric?

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

I'm curious, this does only happen when the right side is concerned? The update logic is not symmetric?

Right, not symmetric as one might would naturally expect (the same situation for hash join as well - right side to build the hash table and left side to probe the hash table).

The left VS. right differs in the following aspects:

  1. There is only one left side input but possibly multiple right side inputs. The right side inputs are flattened and equally iterated during the whole processing (as opposed to traversed in a tree-like fashion).
  2. Several processing logic, and in addition some methods are right side inputs only, e.g.:
    Result<RhsUpdateState> UpdateRhs() {

    and
    rhs.AdvanceAndMemoize(lhs_latest_time, rhs_empty));

So it's normal that some issues are right side only.

But it does remind me that the method I was fixing, namely ‎InputState::Advance, also applies to the left side input, so I think I should see if the issue exists for the left side as well, probably by adding a symmetric case you suggested.

Thanks for the question!

Co-authored-by: Antoine Pitrou <pitrou@free.fr>
@zanmato1984

zanmato1984 commented May 7, 2025

Copy link
Copy Markdown
ContributorAuthor

Hi @pitrou , comments all addressed. Would you take a look again? Thanks.

Comment threadcpp/src/arrow/acero/asof_join_node_test.cc
@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

@github-actions crossbow submit -g cpp

@github-actions

Copy link
Copy Markdown

Revision: dd7a66b

Submitted crossbow builds: ursacomputing/crossbow @ actions-7d095c8a25

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
test-alpine-linux-cppGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-mesonGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-cuda-cpp-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-debian-12-cpp-amd64GitHub Actions
test-debian-12-cpp-i386GitHub Actions
test-fedora-39-cppGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-20GitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

@github-actions crossbow submit -g cpp

@github-actions

Copy link
Copy Markdown

Revision: 5f5b895

Submitted crossbow builds: ursacomputing/crossbow @ actions-973e5e92ed

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
test-alpine-linux-cppGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-mesonGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-cuda-cpp-ubuntu-22.04-cuda-11.7.1GitHub Actions
test-debian-12-cpp-amd64GitHub Actions
test-debian-12-cpp-i386GitHub Actions
test-fedora-39-cppGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-20GitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

@zanmato1984

Copy link
Copy Markdown
ContributorAuthor

Thanks @pitrou for reviewing. Is there anything else to address?

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@zanmato1984
zanmato1984 merged commit fe29b7d into apache:mainMay 14, 2025
@zanmato1984zanmato1984 removed the awaiting committer review Awaiting committer review label May 14, 2025
@conbench-apache-arrow

Copy link
Copy Markdown

After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit fe29b7d.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details. It also includes information about 19 possible false positives for unstable benchmarks that are known to sometimes produce them.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@zanmato1984@pitrou