Fix race condition in ExternalTsFileQueryResource reference counting - #18371
Merged
Conversation
When multiple FragmentInstances share an ExternalTsFileQueryResource, a race condition can cause the resource to be closed prematurely: 1. Fragment A initializes (retain, count=1) and finishes quickly, releasing its reference (count=0) which triggers close(). 2. Fragment B is still in the scheduling queue and has not called retain() yet. When it eventually calls retain(), it fails with 'ExternalTsFileQueryResource has been closed'. Another path: QueryExecution cleanup runs while no FragmentInstance has initialized yet (count=0), closing the resource before scheduled FIs start. Fix: introduce a two-phase close mechanism. - closeByFragmentInstance(): only decrements the usage count. It no longer closes the resource on its own — it must wait for the QueryExecution signal. - closeByQueryExecution(): sets a wantsClose flag and closes only when the usage count is zero. - QueryExecution state listener: now calls releaseExternalTsFileQueryResources() for all terminal states (including FINISHED), not just error states, ensuring the resource is always eventually closed.
|
JackieTien97
approved these changes
Jul 31, 2026
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #18371 +/- ##
============================================
- Coverage 43.45% 43.28% -0.17%
Complexity 374 374
============================================
Files 5364 5364
Lines 383165 383167 +2
Branches 49849 49850 +1
============================================
- Hits 166516 165866 -650
- Misses 216649 217301 +652 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ColinLeeo
self-requested a review
July 31, 2026 09:06
ColinLeeo
approved these changes
Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Problem
When multiple FragmentInstances share an
ExternalTsFileQueryResource, a race condition can cause the resource to be closed prematurely, resulting in"ExternalTsFileQueryResource has been closed"exceptions.Trigger conditions:
read_tsfile(...), multiple Fragments share oneExternalTsFileQueryResourcePARTITION BY timeseries_id)retain()retainFragmentInstanceUsage()→ throws"ExternalTsFileQueryResource has been closed"Another path:
QueryExecutioncleanup runs while no FragmentInstance has initialized yet (count=0), closing the resource before scheduled FIs start.Easier to trigger with:
Fix
Introduce a two-phase close mechanism:
closeByFragmentInstance(): only decrements the usage count. It no longer closes the resource on its own — it waits for the QueryExecution signal.closeByQueryExecution(): sets awantsCloseflag and closes only when the usage count reaches zero.QueryExecutionstate listener: now callsreleaseExternalTsFileQueryResources()for all terminal states (includingFINISHED), not just error states, ensuring the resource is always eventually closed.Changes:
ExternalTsFileQueryResource.javaqueryExecutionWantsToCloseflag; modifycloseByFragmentInstanceandcloseByQueryExecutionclose conditionsQueryExecution.javareleaseExternalTsFileQueryResources()for all terminal statesWhy this approach:
retain()don't affect the count, unlike a total-count approachcloseByQEis idempotent on repeated calls