-
Notifications
You must be signed in to change notification settings - Fork 6.1k
planner: support cluster-level binding reload command #65509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Hi @qw4990. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #65509 +/- ##
================================================
+ Coverage 77.8398% 79.5705% +1.7307%
================================================
Files 1971 1895 -76
Lines 540836 528806 -12030
================================================
- Hits 420986 420774 -212
+ Misses 118190 106599 -11591
+ Partials 1660 1433 -227
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
/test unit-test |
|
@qw4990: Cannot trigger testing until a trusted user reviews the PR and leaves an DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
/test check-dev2 |
|
@qw4990: Cannot trigger testing until a trusted user reviews the PR and leaves an DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
AilinKid
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rest LGTM
pkg/planner/core/common_plans.go
Outdated
| } | ||
|
|
||
| sum = p.BasePhysicalPlan.MemoryUsage() + p.Inner.MemoryUsage() | ||
| sum = p.BasePhysicalPlan.MemoryUsage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base.Plan don't have the memory usage interface, should we care?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that base.Plan doesn't have a MemoryUsage function. And if we want to add MemoryUsage to base.Plan, then we have to implement this function for all LogicalPlan, which is very complex... So to make the code simple, I guess the best way is to just ignore it here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add a comment here to notify that this may cause the memory usage to be inaccurate. And explain why it is acceptable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the other hand, I believe we can still try to reuse the simple here. We just need to add SimpleExec.executeAdmin to accomplish this. Then, we won't need to hard-code the handling of this specific admin command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Offline discussed, thanks!
| bindingLogger().Info("load bindings", zap.Bool("fullLoad", fullLoad), | ||
| zap.Bool("cacheSizeChange", cacheSizeChange), zap.Bool("hasNewBinding", hasNewBinding), | ||
| zap.Int64("cacheCapacity", u.GetMemCapacity()), zap.Int64("cacheUsage", u.GetMemUsage()), | ||
| zap.Int64("cachedBindingNum", int64(u.Size())), zap.Duration("duration", time.Since(begin)), zap.Error(err)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we don't unit test literally, we should have one more test for
two instance, one has mem-quota= small, the other one has memo-quota big
then trigger the admin reload clusters bindings, if one can not load them all, better show some log or warnings, cause it will cause some in-consistence behavior even after this strong synchronization command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg/bindinfo/binding_cache.go
Outdated
| if u.GetMemCapacity() != vardef.MemQuotaBindingCache.Load() { | ||
| cacheSizeChange = true | ||
| u.SetMemCapacity(vardef.MemQuotaBindingCache.Load()) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Between the comparison and SetMemCapacity(), another goroutine could modify the global variable. Should we cache the loaded value in a local variable first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I've updated it.
| type PhysicalSimpleWrapper struct { | ||
| physicalop.BasePhysicalPlan | ||
| Inner Simple | ||
| Inner base.Plan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of PhysicalSimpleWrapper is to wrap Simple (which is actually a LogicalPlan) to a PhysicalPlan. Now I want to also use it to wrap Admin to a PhysicalPlan, so I just modify its type from Simple to base.Plan.
And I renamed this structure from PhysicalSimpleWarpper to PhysicalPlanWrapper, which means it can wrap any kind of plan to a PhysicalPlan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I am a bit confused. How do you distinguish between the admin SQL from remote and the user? I think you should rely on IsFromRemote to make that distinction. Also, please include a manual test in your PR to ensure it works well with multiple instances.
| return | ||
| } | ||
|
|
||
| sum = s.SimpleSchemaProducer.MemoryUsage() + size.SizeOfInterface + size.SizeOfBool + size.SizeOfUint64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the prior implementation is not complete, and it's not used any longer, so we can just remove it.
offline discussed |
0xPoe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
pkg/executor/show.go
Outdated
| return cmpResult > 0 | ||
| }) | ||
| for _, hint := range bindings { | ||
| if hint == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to add some comments explaining when this will happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated!
pkg/planner/core/pb_to_plan.go
Outdated
| if innerPlan == nil { | ||
| errors.Errorf("unexpected statement %s in broadcast query", *e.BroadcastQuery.Query) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this one can be in the default branch. And it seems the error is not used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
fixdb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: AilinKid, fixdb 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 |

What problem does this PR solve?
Issue Number: close #65378
Problem Summary: planner: support cluster-level binding reload command
What changed and how does it work?
Currently, the
ADMIN RELOAD BINDINGScommand only reloads SQL bindings on the TiDB node where the command is executed. In a cluster environment with multiple TiDB nodes, users need to manually execute the command on each node to reload bindings across the entire cluster. This is inconvenient and error-prone, especially when bindings are modified and need to be synchronized across all nodes.This PR introduces a new
ADMIN RELOAD CLUSTER BINDINGScommand that reloads SQL bindings across all TiDB nodes in the cluster with a single command execution.Key changes:
Parser support: Added
AdminReloadClusterBindingsAST node type and parsing support for the newADMIN RELOAD CLUSTER BINDINGScommand inpkg/parser/ast/andpkg/parser/.Plan builder: Added
OpReloadClusterBindingsoperation type inpkg/planner/core/common_plans.goand handled the new command inpkg/planner/core/planbuilder.go.Executor implementation: Implemented
reloadClusterBindings()method inpkg/executor/bind.gothat uses the existingbroadcast()function to send the reload command to all TiDB nodes in the cluster, including the current node.Logging enhancement: Added logging to
bindingCacheUpdater.LoadFromStorageToCache()inpkg/bindinfo/binding_cache.goto track the number of bindings loaded, cache size, and duration during full load operations.How it works:
When a user executes
ADMIN RELOAD CLUSTER BINDINGS, the command is broadcast to all TiDB nodes in the cluster using the coprocessor framework's broadcast mechanism (similar to howREFRESH STATS CLUSTERworks). Each TiDB node receives the broadcast and executesADMIN RELOAD BINDINGSlocally, which triggersLoadFromStorageToCache(true)to reload all bindings from storage into the local cache.The broadcast mechanism ensures that:
Test:
Since the test of this PR requires an entire cluster environment and some interaction between different TiDB nodes, so it's hard to write a UT for it. Then I just tested it manually, please see the picture below:
Check List
Tests
Side effects
Documentation
Release note
Please refer to Release Notes Language Style Guide to write a quality release note.