Skip to content

distsql, kv: add query-level per-store cop request limiter - #69360

Open
solotzg wants to merge 23 commits into
pingcap:masterfrom
solotzg:enhance-query-limit
Open

distsql, kv: add query-level per-store cop request limiter#69360
solotzg wants to merge 23 commits into
pingcap:masterfrom
solotzg:enhance-query-limit

Conversation

@solotzg

@solotzg solotzg commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: close #69359

Problem Summary:

A large statement can issue many concurrent coprocessor RPC attempts to the same TiKV store. tidb_distsql_scan_concurrency limits worker concurrency for each DistSQL request, but it does not provide a statement-wide, per-store bound across multiple DistSQL requests or client-go retries. As a result, one statement can create uneven pressure on individual TiKV stores.

What changed and how does it work?

  • Add the global and session system variable tidb_query_cop_store_limit. It limits the number of in-flight TiKV coprocessor request attempts to each store within one statement. The default value is 15; setting it to 0 disables the limit.
  • Create one kv.QueryCopStoreLimiter for each statement when the variable is enabled. The limiter lazily creates one concrete *kv.CoprRequestLimiter for each TiKV store ID.
  • Use the tikvrpc.RequestAttemptAdmission hook introduced by tikv/client-go#2026. client-go invokes the hook after resolving the actual target store for every synchronous or asynchronous RPC attempt, including retries. Each admitted attempt releases its token exactly once when that attempt finishes, before another retry selects its store.
  • Give the statement-level per-store limiter precedence over the existing request-local limiter. When QueryCopStoreLimiter is enabled, the request-local limiter is not acquired. When it is disabled, the request-local limiter remains the fallback for existing paths such as merge-sort index lookup.
  • Replace the previous request-local *util.RateLimit plumbing with the concrete *kv.CoprRequestLimiter. Admission supports a non-blocking fast path and cancellation by the request context or iterator shutdown without leaking tokens.
  • Aggregate blocking admission wait time in LimiterWaitStats as TotalTime and MaxTime, and expose it in EXPLAIN ANALYZE cop task runtime statistics as limiter_wait:{total:..., max:...}. No admission count is collected or displayed.

This PR depends on tikv/client-go#2026. The TiDB go.mod dependency must be updated after that PR is merged.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Unit tests and checks:

make bazel_prepare
./tools/check/failpoint-go-test.sh pkg/kv -run 'TestCoprRequestLimiter|TestQueryCopStoreLimiter' -count=20
./tools/check/failpoint-go-test.sh pkg/kv -run 'TestCoprRequestLimiter|TestQueryCopStoreLimiter' -count=1 -race
./tools/check/failpoint-go-test.sh pkg/distsql -run '^(TestSelectAppliesQueryCopStoreLimiter|TestSelectResultRuntimeStats|TestUpdateCopRuntimeStats)$' -count=1
./tools/check/failpoint-go-test.sh pkg/store/copr -run '^TestRequestAttemptAdmissionLimiterPrecedence$' -count=1
./tools/check/failpoint-go-test.sh pkg/store/copr/copr_test -run '^(TestBuildCopIteratorWithSharedRequestLimiter|TestQueryCopStoreLimiterLimitsSameStoreCoprRequests|TestRequestLocalCoprLimiterLimitsConcurrentRequests)$' -count=1
./tools/check/failpoint-go-test.sh pkg/executor -run '^TestSetConcurrency$' -count=1
make lint

The related client-go PR includes synchronous and asynchronous retry tests that verify:

  • admission observes the store selected for every attempt;
  • a retry can be admitted by a different store limiter;
  • the previous attempt is released before the next retry is admitted;
  • cancellation and RPC errors release exactly once.

Manual verification used a TiDB and TiKV playground with a table split into multiple regions. The same EXPLAIN ANALYZE query was run with different tidb_query_cop_store_limit values:

tidb_query_cop_store_limit=16: limiter_wait total=0ms, max=0ms
tidb_query_cop_store_limit=1:  limiter_wait total≈426ms~439ms, max≈16ms~17ms

Summary:
low limit median total: 432.600ms
high limit median total: 0.000ms
low limit max wait: 17.100ms
high limit max wait: 0.000ms

PASS: limiter_wait indicates that the cop request limiter was exercised

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

Add the `tidb_query_cop_store_limit` system variable to limit the number of in-flight TiKV coprocessor request attempts to each TiKV store within a statement. The default value is `15`; setting it to `0` disables the limit.

@ti-chi-bot ti-chi-bot Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jun 22, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign cfzjywxk, terry1purcell for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces a CoprRequestLimiter interface and per-store QueryCopStoreLimiter for token-based cop request admission. Adds a tidb_query_cop_store_limit system variable that propagates through SessionVars → DistSQLContext → Select → TiKV requests. Rewrites the coprocessor send path to use Acquire/Release semantics with per-store limiter acquisition before RPC execution.

Changes

Per-store cop request concurrency limit within a query

Layer / File(s) Summary
CoprRequestLimiter interface and implementations
pkg/kv/kv.go, pkg/kv/BUILD.bazel
Defines CoprRequestLimiter interface with Capacity(), Acquire(done chan), and Release() methods. Fixed implementation uses in-flight counter and FIFO waiter queue with done-channel early exit and redundant-release panic guard. QueryCopStoreLimiter manages per-store limiters via sync.Map. Updates Request.CoprRequestRateLimit from *util.RateLimit to CoprRequestLimiter interface and adds Request.QueryCopStoreLimiter field.
CoprRequestLimiter and QueryCopStoreLimiter tests
pkg/kv/kv_test.go
Comprehensive test coverage for blocking/admission with Acquire/Release, done-channel cancellation, redundant-release panic, concurrent stress without deadlock, and per-store limiter independence.
System variable and SessionVars field
pkg/sessionctx/vardef/tidb_vars.go, pkg/sessionctx/variable/session.go, pkg/sessionctx/variable/sysvar.go, pkg/sessionctx/variable/setvar_affect.go
Adds TiDBQueryCopStoreLimit constant and DefTiDBQueryCopStoreLimit=0 default. Adds QueryCopStoreLimit int field to SessionVars with initialization. Registers variable with GLOBAL | SESSION scope, unsigned integer type, and session setter. Marks as hint-updatable.
System variable tests
pkg/executor/set_test.go
Tests verify @@tidb_query_cop_store_limit defaults to DefTiDBQueryCopStoreLimit, session variable vars.QueryCopStoreLimit matches default, and setting to 8 updates both the query result and in-session value.
DistSQLContext field and session initialization
pkg/distsql/context/context.go, pkg/distsql/context/context_test.go, pkg/session/session.go, pkg/util/mock/context.go
Adds QueryCopStoreLimiter *kv.QueryCopStoreLimiter field to DistSQLContext. Both GetDistSQLCtx in session and mock contexts conditionally create the limiter when vars.QueryCopStoreLimit > 0 and inject it. Context test extends ignore list for deep comparison.
Select propagates limiter to TiKV requests
pkg/distsql/distsql.go, pkg/distsql/request_builder.go, pkg/distsql/distsql_test.go, pkg/distsql/BUILD.bazel
Select assigns dctx.QueryCopStoreLimiter to kvReq.QueryCopStoreLimiter for TiKV requests when non-nil. SetCoprRequestRateLimit parameter type changes to kv.CoprRequestLimiter. Tests verify TiKV vs TiFlash limiter attachment, explicit limiter preservation, and nil states. Shard counts updated.
Executor and coprocessor send path integration
pkg/executor/distsql.go, pkg/store/copr/coprocessor.go, pkg/store/copr/copr_test/coprocessor_test.go, pkg/store/copr/copr_test/BUILD.bazel
Executor's merge-sort limiter migrates from tikvutil.NewRateLimit to kv.NewCoprRequestRateLimit. Coprocessor worker's requestRateLimit retypes to kv.CoprRequestLimiter. handleTaskOnce replaces GetToken/PutToken with Acquire(finishCh)/Release() with deferred cleanup. New acquireQueryCopStoreLimiter helper resolves RPC context, acquires per-store limiter, and returns release function. Coprocessor tests and BUILD updated.

Sequence Diagram(s)

sequenceDiagram
  participant Select
  participant DistSQLContext
  participant copIteratorWorker
  participant acquireQueryCopStoreLimiter
  participant QueryCopStoreLimiter
  participant CoprRequestLimiter
  participant TiKV

  Select->>DistSQLContext: read QueryCopStoreLimiter
  alt QueryCopStoreLimiter != nil for TiKV
    Select->>Select: kvReq.QueryCopStoreLimiter = dctx.QueryCopStoreLimiter
  end
  Select->>copIteratorWorker: dispatch kvReq

  loop for each region
    copIteratorWorker->>acquireQueryCopStoreLimiter: resolve RPC context + acquire per-store limiter
    acquireQueryCopStoreLimiter->>QueryCopStoreLimiter: GetStoreLimiter(storeID)
    QueryCopStoreLimiter-->>acquireQueryCopStoreLimiter: per-store CoprRequestLimiter
    acquireQueryCopStoreLimiter->>CoprRequestLimiter: Acquire(finishCh)
    alt per-store admission succeeds
      CoprRequestLimiter-->>copIteratorWorker: releaseFn
      copIteratorWorker->>CoprRequestLimiter: Acquire(finishCh) for request-rate
      copIteratorWorker->>TiKV: send cop request
      TiKV-->>copIteratorWorker: response
      copIteratorWorker->>CoprRequestLimiter: Release() request-rate
      copIteratorWorker->>releaseFn: call Release per-store
    else early exit or error
      copIteratorWorker-->>copIteratorWorker: return early
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • pingcap/tidb#68565: Both PRs modify coprocessor request rate-limiting wiring at the same points—pkg/distsql/request_builder.go's SetCoprRequestRateLimit and pkg/executor/distsql.go's merge-sort limiter setup—so changes to limiter types directly affect integration points.

Suggested labels

size/XL, release-note-none, ok-to-test, approved, lgtm

Suggested reviewers

  • gengliqi
  • windtalker
  • wshwsh12

Poem

🐇 Hop through the stores with tokens in paw,
Per-store concurrency bound by one law.
Acquire requests, Release sets free,
Each TiKV store gets its own decree.
tidb_query_cop_store_limit guards the way,
Fair admission for every query's day! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements all key requirements from #69359: CoprRequestLimiter abstraction, per-store query-level limiter, TiKV-only application, system variable (tidb_query_cop_store_limit), and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes directly support the stated objective of adding query-level per-store cop request limiting; no out-of-scope modifications detected.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a query-level per-store cop request limiter.
Description check ✅ Passed The description follows the template with issue link, problem summary, implementation details, checklist items, side effects, docs, and release note.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/kv/kv.go (1)

657-667: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Variable shadowing: c shadows the receiver.

The inner variable c := limiter.Capacity() shadows the receiver c *compositeCoprRequestLimiter. Consider renaming to cap for clarity.

Suggested fix
 func (c *compositeCoprRequestLimiter) Capacity() int {
 	capacity := 0
 	for _, limiter := range c.limiters {
-		c := limiter.Capacity()
-		if capacity == 0 || c < capacity {
-			capacity = c
+		cap := limiter.Capacity()
+		if capacity == 0 || cap < capacity {
+			capacity = cap
 		}
 	}
 	return capacity
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/kv/kv.go` around lines 657 - 667, In the Capacity method of the
compositeCoprRequestLimiter receiver, the inner loop variable `c :=
limiter.Capacity()` is shadowing the receiver `c *compositeCoprRequestLimiter`,
creating confusion and potential bugs. Rename the inner variable from `c` to
`cap` and update all references to this variable within the loop (including the
comparison `c < capacity`) to use the new name instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/kv/kv_test.go`:
- Around line 210-213: Replace the time.Sleep call with a deterministic
synchronization mechanism to ensure the precondition is met before proceeding.
Instead of relying on a fixed sleep duration to assume Acquire has taken
limiter1 and is blocked on limiter2, use a channel-based signal to confirm that
the token has actually been acquired from limiter1 before closing the done
channel. This ensures the test validates the rollback path reliably without
depending on scheduler timing.

---

Nitpick comments:
In `@pkg/kv/kv.go`:
- Around line 657-667: In the Capacity method of the compositeCoprRequestLimiter
receiver, the inner loop variable `c := limiter.Capacity()` is shadowing the
receiver `c *compositeCoprRequestLimiter`, creating confusion and potential
bugs. Rename the inner variable from `c` to `cap` and update all references to
this variable within the loop (including the comparison `c < capacity`) to use
the new name instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c3bec8a8-f539-4ec2-a2ec-7117fecd8272

📥 Commits

Reviewing files that changed from the base of the PR and between e7b15cd and ddb836b.

📒 Files selected for processing (20)
  • pkg/distsql/BUILD.bazel
  • pkg/distsql/context/context.go
  • pkg/distsql/context/context_test.go
  • pkg/distsql/distsql.go
  • pkg/distsql/distsql_test.go
  • pkg/distsql/request_builder.go
  • pkg/executor/distsql.go
  • pkg/executor/set_test.go
  • pkg/kv/BUILD.bazel
  • pkg/kv/kv.go
  • pkg/kv/kv_test.go
  • pkg/session/session.go
  • pkg/sessionctx/vardef/tidb_vars.go
  • pkg/sessionctx/variable/session.go
  • pkg/sessionctx/variable/setvar_affect.go
  • pkg/sessionctx/variable/sysvar.go
  • pkg/store/copr/copr_test/BUILD.bazel
  • pkg/store/copr/copr_test/coprocessor_test.go
  • pkg/store/copr/coprocessor.go
  • pkg/util/mock/context.go
💤 Files with no reviewable changes (1)
  • pkg/store/copr/copr_test/BUILD.bazel

Comment thread pkg/kv/kv_test.go Outdated
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.80247% with 104 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.9114%. Comparing base (2d30398) to head (69110b3).

⚠️ Current head 69110b3 differs from pull request most recent head 629ab78

Please upload reports for the commit 629ab78 to get more accurate results.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69360        +/-   ##
================================================
- Coverage   76.3242%   73.9114%   -2.4129%     
================================================
  Files          2041       2058        +17     
  Lines        559285     579135     +19850     
================================================
+ Hits         426870     428047      +1177     
- Misses       131515     150735     +19220     
+ Partials        900        353       -547     
Flag Coverage Δ
integration 40.6999% <35.8024%> (+1.0420%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 60.4471% <ø> (+0.5663%) ⬆️
parser ∅ <ø> (∅)
br 47.4060% <ø> (-15.2866%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/store/copr/coprocessor.go (1)

1806-1835: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Acquire the per-store limiter before taking the request-local token.

Line 1806 takes the aggregate request-local token before acquireQueryCopStoreLimiter, so a task blocked behind a hot store still consumes a request-local slot and can throttle unrelated stores without an in-flight send. Move the request-local acquire after the store limiter and keep the new pre-resolution error on the same derr.ToTiDBErr path as SendReqCtx errors.

Proposed fix
-	acquiredRequestRateLimit := false
-	if worker.requestRateLimit != nil {
-		if worker.requestRateLimit.Acquire(worker.finishCh) {
-			return nil, nil
-		}
-		acquiredRequestRateLimit = true
-	}
 	releaseQueryCopStoreLimiter, exit, err := worker.acquireQueryCopStoreLimiter(bo, task, ops)
 	if err != nil {
-		if acquiredRequestRateLimit {
-			worker.requestRateLimit.Release()
-		}
-		return nil, errors.Trace(err)
+		return nil, errors.Trace(derr.ToTiDBErr(err))
 	}
 	if exit {
-		if acquiredRequestRateLimit {
-			worker.requestRateLimit.Release()
-		}
 		return nil, nil
 	}
+	acquiredRequestRateLimit := false
+	if worker.requestRateLimit != nil {
+		if worker.requestRateLimit.Acquire(worker.finishCh) {
+			if releaseQueryCopStoreLimiter != nil {
+				releaseQueryCopStoreLimiter()
+			}
+			return nil, nil
+		}
+		acquiredRequestRateLimit = true
+	}
 	// Keep the request-rate token and send attempt in a small scope so the
 	// token is released immediately after the send attempt returns, while
 	// still remaining panic-safe.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/store/copr/coprocessor.go` around lines 1806 - 1835, The request-local
token from worker.requestRateLimit is being acquired before the per-store
limiter via acquireQueryCopStoreLimiter, which allows tasks blocked on hot
stores to still consume request-local slots and throttle unrelated stores.
Reorder the acquisition logic so that acquireQueryCopStoreLimiter is called
first, then only acquire worker.requestRateLimit after successfully acquiring
the store limiter. Update the error handling paths to release the request-local
token only when it has been acquired, and ensure any pre-resolution errors
follow the same derr.ToTiDBErr path as SendReqCtx errors.
🧹 Nitpick comments (1)
pkg/store/copr/coprocessor.go (1)

1896-1904: 🧹 Nitpick | 🔵 Trivial

Track the best-effort store-selection caveat.

The comment says SendReqCtx may send to a different store than the pre-resolved rpcCtx, so the limiter can charge the wrong per-store bucket during retries, stale cache, or leader changes. Please link a tracking issue or add a targeted test documenting that this sysvar is intentionally best-effort until the acquisition moves into the client-go send path.

Do you want me to help draft the follow-up issue or a focused test case for this caveat?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/store/copr/coprocessor.go` around lines 1896 - 1904, The comment block
discussing the pre-resolution caveat in SendReqCtx needs to document the
intentional best-effort nature of this store-selection approach. Either add a
reference to an existing tracking issue that addresses moving the per-store
limiter acquisition into the client-go send path, or add a targeted test case
that explicitly documents and validates this best-effort behavior when the
actual store differs from the pre-resolved rpcCtx during retries, stale cache
lookups, leader changes, or store unavailability. This ensures the caveat is
tracked and not accidentally "fixed" without proper coordination.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/store/copr/coprocessor.go`:
- Around line 1806-1835: The request-local token from worker.requestRateLimit is
being acquired before the per-store limiter via acquireQueryCopStoreLimiter,
which allows tasks blocked on hot stores to still consume request-local slots
and throttle unrelated stores. Reorder the acquisition logic so that
acquireQueryCopStoreLimiter is called first, then only acquire
worker.requestRateLimit after successfully acquiring the store limiter. Update
the error handling paths to release the request-local token only when it has
been acquired, and ensure any pre-resolution errors follow the same
derr.ToTiDBErr path as SendReqCtx errors.

---

Nitpick comments:
In `@pkg/store/copr/coprocessor.go`:
- Around line 1896-1904: The comment block discussing the pre-resolution caveat
in SendReqCtx needs to document the intentional best-effort nature of this
store-selection approach. Either add a reference to an existing tracking issue
that addresses moving the per-store limiter acquisition into the client-go send
path, or add a targeted test case that explicitly documents and validates this
best-effort behavior when the actual store differs from the pre-resolved rpcCtx
during retries, stale cache lookups, leader changes, or store unavailability.
This ensures the caveat is tracked and not accidentally "fixed" without proper
coordination.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 165647d7-b814-4cdd-b686-74ac9358880f

📥 Commits

Reviewing files that changed from the base of the PR and between ddb836b and aedd638.

📒 Files selected for processing (15)
  • pkg/distsql/context/context.go
  • pkg/distsql/context/context_test.go
  • pkg/distsql/distsql.go
  • pkg/distsql/distsql_test.go
  • pkg/executor/set_test.go
  • pkg/kv/BUILD.bazel
  • pkg/kv/kv.go
  • pkg/kv/kv_test.go
  • pkg/session/session.go
  • pkg/sessionctx/vardef/tidb_vars.go
  • pkg/sessionctx/variable/session.go
  • pkg/sessionctx/variable/setvar_affect.go
  • pkg/sessionctx/variable/sysvar.go
  • pkg/store/copr/coprocessor.go
  • pkg/util/mock/context.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/sessionctx/variable/setvar_affect.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/kv/BUILD.bazel
  • pkg/distsql/context/context_test.go

@solotzg solotzg changed the title executor, kv: add query-level cop request limit distsql, kv: add query-level per-store cop request limiter Jun 23, 2026
@ti-chi-bot ti-chi-bot Bot added do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. and removed release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Jun 23, 2026
@solotzg
solotzg force-pushed the enhance-query-limit branch from c0482d1 to a065cb6 Compare June 23, 2026 09:27
@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Jun 23, 2026
solotzg added 2 commits June 23, 2026 20:02
…rrency

- Added QueryCopStoreLimiter to limit the number of in-flight cop requests per TiKV store within a single query.
- Updated DistSQLContext to include QueryCopStoreLimiter.
- Modified Select function to apply the QueryCopStoreLimiter when sending requests to TiKV.
- Enhanced tests to validate the behavior of the new limiter, ensuring it correctly manages concurrent requests.
- Adjusted related variables and configurations to support the new functionality.

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…CoprRequestRateLimit directly

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
@solotzg
solotzg force-pushed the enhance-query-limit branch from 36db0ab to a8e8f3c Compare June 23, 2026 12:45
…stency

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
@solotzg
solotzg force-pushed the enhance-query-limit branch from 890ae70 to b1f3a99 Compare June 24, 2026 02:18
@solotzg

solotzg commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

/cc @windtalker

@ti-chi-bot
ti-chi-bot Bot requested a review from windtalker June 24, 2026 02:18
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
@ti-chi-bot ti-chi-bot Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Jun 24, 2026
@solotzg

solotzg commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

/cc @gengliqi

@ti-chi-bot
ti-chi-bot Bot requested a review from gengliqi June 25, 2026 07:12
solotzg added 5 commits July 7, 2026 12:04
…acquisition logic

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…used test code

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
solotzg added 2 commits July 21, 2026 19:34
…r consistency

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
# Conflicts:
#	pkg/sessionctx/vardef/tidb_vars.go
Comment thread pkg/distsql/distsql.go Outdated
Comment thread pkg/kv/kv.go
Comment thread pkg/session/session.go
Comment thread pkg/store/copr/coprocessor.go Outdated
Comment thread pkg/store/copr/coprocessor.go Outdated
// the region/store selection work done inside SendReqCtx, and the selected
// store can still change there because of retries, stale cache, leader changes,
// or unavailable stores.
// TODO: Move query per-store limiter acquisition into the client-go send path

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.

How about move it to client-go at this time

@solotzg solotzg Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK. This PR shoudl be merged after tikv/client-go#2026

solotzg added 2 commits July 22, 2026 13:01
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…elect test

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
solotzg added 8 commits July 22, 2026 17:37
…structure

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…imits

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…s handling

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
…g in tests

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
# Conflicts:
#	DEPS.bzl
#	go.sum
#	pkg/distsql/select_result.go
solotzg added 2 commits July 29, 2026 20:40
…cument

Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
Signed-off-by: Zhigao TONG <tongzhigao@pingcap.com>
@ti-chi-bot

ti-chi-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

@solotzg: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
idc-jenkins-ci-tidb/check_dev 629ab78 link true /test check-dev
pull-build-next-gen 629ab78 link true /test pull-build-next-gen
idc-jenkins-ci-tidb/build 629ab78 link true /test build
pull-unit-test-next-gen 629ab78 link true /test pull-unit-test-next-gen
idc-jenkins-ci-tidb/unit-test 629ab78 link true /test unit-test

Full PR test history. Your PR dashboard.

Details

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. I understand the commands that are listed here.

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

Labels

release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

executor: add query-level cop request concurrency limit

2 participants