planner: flaky test TestBatchDropBindings (#66559)#70013
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesBinding test stability
Estimated code review effort: 1 (Trivial) | ~2 minutes Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release-8.5 #70013 +/- ##
================================================
Coverage ? 55.1686%
================================================
Files ? 1849
Lines ? 666288
Branches ? 0
================================================
Hits ? 367582
Misses ? 271267
Partials ? 27439
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This is an automated cherry-pick of #66559
What problem does this PR solve?
Issue Number: close #66371
Problem Summary:
What changed and how does it work?
Decision was made here to fix the test rather than the underlying behavior. The test does expose a race condition - but the likelihood that a customer sees this as a critical issue, or that it has any significant impact to their operations - is arguably low.
The issue is - if the binding cache reload (which occurs every 3 seconds) had begun before the drop completed, then the dropped binding could be reloaded - and exist for 3 seconds longer than the user intended. The solution for that would be to add a mutex to the bindingCacheUpdater - but that would then be executed every 3 seconds. However, if a customer exposes this problem - then it may be necessary to add this fix.
Analysis of the issue:
Root Cause: Race Between Background Binding Loader and DROP
The test does not set bindinfo.Lease = 0, so the background goroutine globalBindHandleWorkerLoop (started in domain.go:1571) runs every 3 seconds, calling LoadFromStorageToCache(false, false). This races with the DropBinding operation's own deferred LoadFromStorageToCache call.
The Race in Detail
LoadFromStorageToCache (binding_cache.go:64) is not atomic — it first reads bindings from storage via SQL, then iterates over them updating the cache one-by-one. There is no mutex protecting the entire read-process cycle. Two concurrent calls can interleave.
Here's the problematic sequence:
Why the stale data persists
At step 4, the background goroutine also stores lastUpdateTime = T0 (from its stale snapshot), potentially overwriting the DROP's stored T1. This makes lastUpdateTime go backwards. The 10-second timeLagTolerance (binding_cache.go:94) means the next incremental load will likely catch the T1 deleted record again, but there's a transient window (up to the next 3-second tick) where the cache has stale data.
Key code locations
Evidence: other tests avoid this
TestGCBindRecord (bind_test.go:371-377) explicitly sets bindinfo.Lease = 0 before creating the mock store/domain, preventing the background goroutine from starting. TestBatchDropBindings does not.
Session bindings are not affected
removeAllBindings(tk, false) for session bindings uses DropSessionBinding (session_handle.go:90), which is a simple in-memory map delete with no background reload — no race possible there.
Summary
The flakiness is caused by the background globalBindHandleWorkerLoop goroutine's LoadFromStorageToCache interleaving with the DropBinding deferred LoadFromStorageToCache, re-adding stale (enabled) bindings to the cache after the DROP already removed them. The fix would be to set bindinfo.Lease = 0 at the start of the test (as TestGCBindRecord does), or to add mutual exclusion around LoadFromStorageToCache.
Check List
Tests
Side effects
Documentation
Release note
Please refer to Release Notes Language Style Guide to write a quality release note.
Summary by CodeRabbit