Skip to content

Allow disk use in MongoDbIO aggregations to avoid sort memory limit - #41222

Open
mxtymoshyk wants to merge 1 commit into
apache:masterfrom
mxtymoshyk:fix/mongodb-allow-disk-use
Open

mxtymoshyk wants to merge 1 commit into
apache:masterfrom
mxtymoshyk:fix/mongodb-allow-disk-use

Conversation

@mxtymoshyk

Copy link
Copy Markdown
Contributor

Fixes #26495

MongoDbIO.read().withBucketAuto(true) fails on large collections with:

Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.

To split the read, the connector runs a $bucketAuto aggregation over _id. That stage sorts the whole collection, and MongoDB limits an in-memory sort to 100 MB. Servers older than 6.0 only write the sort to disk when the request sets allowDiskUse, and the Java connector never set it. The Python connector already sets it, and the Go connector added it in #25013.

This PR sets allowDiskUse(true) in two places:

  • BoundedMongoDbSource.buildAutoBuckets, which computes the splits. Reads that use withQueryFn(AggregationQuery...) call it too, even without withBucketAuto.
  • AggregationQuery.apply, which runs the user's own pipeline. A large $sort or $group there hits the same limit.

MongoDB 6.0 and later allow disk use by default (allowDiskUseByDefault=true), so nothing changes on those servers unless an admin turned that default off. In that case Beam reads now spill to disk anyway, because the connector sets the flag on every aggregation, as the Python and Go connectors do. I can add a withAllowDiskUse(boolean) option if you'd rather let the server setting win.

Atlas Free and Flex clusters ignore allowDiskUse instead of rejecting it (Atlas docs), so reads there behave as before. The error stays on those tiers for large collections, because they cap in-memory sorts at 32 MB and never spill to disk.

Testing:

  • Two new tests in MongoDbIOTest record the commands the driver sends and check that the aggregate command carries allowDiskUse: true. Both fail without the fix. The server hardcodes the 100 MB limit for $bucketAuto, so a small test collection can't trigger the real error.
  • I ran the reporter's pipeline against mongo 4.4.17 with 150k documents (about 146 MB). It failed with the error above before the fix and read all 150,000 documents after it.
  • ./gradlew :sdks:java:io:mongodb:test passes.

MongoDbIO now sets allowDiskUse(true) on the $bucketAuto query that
computes splits and on AggregationQuery reads. Without it, servers
older than 6.0 fail on any collection whose sort needs more than
100 MB, with "Sort exceeded memory limit of 104857600 bytes, but did
not opt in to external sorting".

Fixes apache#26495
@github-actions github-actions Bot added java io mongodb size/s S: 10-49 lines changed labels Nov 11, 2026

@github-actions github-actions Bot left a comment

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.

📋 Review Summary

This PR updates MongoDbIO (both BoundedMongoDbSource.buildAutoBuckets and AggregationQuery.apply) to explicitly enable allowDiskUse(true) on MongoDB aggregation pipelines. This prevents reads using $bucketAuto or custom aggregation pipelines on large collections from failing with the 100 MB in-memory sort limit on MongoDB servers prior to 6.0, bringing the Java connector in line with the Python and Go connectors.

🔍 General Feedback

  • The implementation is clean, minimal, and directly addresses the issue in all relevant aggregation call sites.
  • The unit tests using a CommandListener to inspect the outgoing aggregate command are well-designed and reliably verify the behavior without requiring a 100+ MB dataset in tests.

💡 Tip: Comment /gemini review on this pull request to trigger a new Gemini code review.

@github-actions

Copy link
Copy Markdown
Contributor

Assigning reviewers:

R: @kennknowles for label java.
Backup reviewer: damccorm (if the main reviewer is unresponsive, you can escalate to them by tagging their username)

Note: If you would like to opt out of this review, comment assign to next reviewer.

Available commands:

  • stop reviewer notifications - opt out of the automated review tooling
  • remind me after tests pass - tag the comment author after tests pass
  • waiting on author - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)

The PR bot will only process comments in the main thread (not review comments).

Sign up for free to 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.

[Bug]: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.

1 participant