Skip to content

server: limit accumulated COM_STMT_SEND_LONG_DATA size (#69694) - #70231

Open
ti-chi-bot wants to merge 1 commit into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-69694-to-release-8.5
Open

server: limit accumulated COM_STMT_SEND_LONG_DATA size (#69694)#70231
ti-chi-bot wants to merge 1 commit into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-69694-to-release-8.5

Conversation

@ti-chi-bot

@ti-chi-bot ti-chi-bot commented Jul 30, 2026

Copy link
Copy Markdown
Member

This is an automated cherry-pick of #69694

What problem does this PR solve?

Issue Number: close #69693

Problem Summary:

COM_STMT_SEND_LONG_DATA appends each payload chunk into the prepared statement's bound parameter buffers. Before this PR, TiDB did not check the cumulative size of those buffers, so an authenticated client could keep sending long-data chunks for a prepared statement and grow connection memory without executing the statement.

What changed and how does it work?

This PR tracks the total bytes accumulated by COM_STMT_SEND_LONG_DATA for each prepared statement. Before appending a new chunk, TiDB checks whether the statement-level accumulated long-data size would exceed the session max_allowed_packet. If it would exceed the limit, TiDB returns the existing ErrNetPacketTooLarge error and keeps the already buffered data unchanged.

COM_STMT_RESET clears both the buffered parameters and the byte counter.

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.

Tested locally:

  • git diff --check
  • go test ./pkg/server -run '^(TestStmtSendLongDataMaxAllowedPacket|TestCursorFetchSendLongData|TestCursorFetchSendLongDataReset)$' -count=1
  • go test --tags=intest ./pkg/server -run '^(TestStmtSendLongDataMaxAllowedPacket|TestCursorFetchSendLongData|TestCursorFetchSendLongDataReset)$' -count=1

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

TiDB now limits the accumulated `COM_STMT_SEND_LONG_DATA` size for a prepared statement by `max_allowed_packet`.

Summary by CodeRabbit

  • Bug Fixes
    • Improved validation for large data submitted through prepared statements.
    • Executions now return a packet-size error when accumulated parameter data exceeds the configured limit.
    • Oversized parameter data is cleared after an error, allowing subsequent statement executions to proceed normally.

Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@ti-chi-bot ti-chi-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels Jul 30, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member Author

@YangKeao This PR has conflicts, I have hold it.
Please resolve them or ask others to resolve them, then comment /unhold to remove the hold label.

@ti-chi-bot

ti-chi-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

@ti-chi-bot: ## If you want to know how to resolve it, please read the guide in TiDB Dev Guide.

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 ti-community-infra/tichi repository.

@ti-chi-bot

ti-chi-bot Bot commented Jul 30, 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 yangkeao 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 Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Prepared statements now limit accumulated COM_STMT_SEND_LONG_DATA payloads to MaxAllowedPacket, validate the limit before execution, and reset overflow state after failed execution.

Changes

Long-data validation

Layer / File(s) Summary
Track and reset long-data overflow
pkg/server/driver.go, pkg/server/driver_tidb.go
Adds the CheckLongDataSize contract, tracks oversized accumulated parameters, returns ErrNetPacketTooLarge, and clears the overflow flag during reset.
Execute guard and test coverage
pkg/server/conn_stmt.go, pkg/server/conn_stmt_test.go
Validates long-data size before binary parameter parsing and tests packet-limit errors, parameter cleanup, and state reset.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • pingcap/tidb#70083: Implements the same prepared-statement long-data validation and test coverage.
  • pingcap/tidb#70170: Adds the same execution guard and accumulated long-data limit.
  • pingcap/tidb#70172: Implements matching overflow tracking and packet-too-large behavior.

Poem

A rabbit packs chunks in a neat little row,
Till the packet says, “That’s as far as you go!”
The statement checks, then clears out the tray,
So fresh bounds can hop into action next day.
“No oversized carrots!” the bunny cries.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: limiting accumulated COM_STMT_SEND_LONG_DATA size.
Description check ✅ Passed The description follows the template with issue number, problem summary, change details, checklist items, side effects, and release note.
Linked Issues check ✅ Passed The code and tests implement the issue goal by rejecting accumulated long-data payloads over max_allowed_packet with the existing packet-too-large error.
Out of Scope Changes check ✅ Passed The changes are scoped to prepared-statement long-data limits and related tests, with no unrelated modifications apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
The command is terminated due to an 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.

❤️ 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: 2

🤖 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/server/conn_stmt_test.go`:
- Around line 26-30: Clean up the import block in conn_stmt_test.go by removing
the literal merge-conflict markers surrounding the resolve and servererr
imports. Preserve both required imports and ensure the resulting import
declaration is valid Go.

In `@pkg/server/driver_tidb.go`:
- Around line 111-135: The prepared statement currently checks packet size per
parameter instead of against one statement-wide byte budget. In
pkg/server/driver_tidb.go lines 111-135, update TiDBStatement’s long-data
handling and CheckLongDataSize to track cumulative bound bytes, reject additions
that exceed MaxAllowedPacket, and reset the accumulated count in Reset. In
pkg/server/conn_stmt_test.go lines 401-409, adjust the test to keep the combined
payload exactly at the limit, then append one byte and assert the overflow
error.
🪄 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 Plus

Run ID: 9b0c90a2-eb37-418d-86be-918c61b52c06

📥 Commits

Reviewing files that changed from the base of the PR and between 0d2e635 and f1b6f23.

📒 Files selected for processing (4)
  • pkg/server/conn_stmt.go
  • pkg/server/conn_stmt_test.go
  • pkg/server/driver.go
  • pkg/server/driver_tidb.go

Comment on lines +26 to +30
<<<<<<< HEAD
=======
"github.com/pingcap/tidb/pkg/planner/core/resolve"
servererr "github.com/pingcap/tidb/pkg/server/err"
>>>>>>> ed2376acc6e (server: limit accumulated COM_STMT_SEND_LONG_DATA size (#69694))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Resolve the merge-conflict markers before merging.

The import block still contains literal <<<<<<< HEAD, =======, and >>>>>>> ... lines, so this test file is not valid Go and the package cannot compile. Keep the required imports and remove all conflict markers.

🤖 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/server/conn_stmt_test.go` around lines 26 - 30, Clean up the import block
in conn_stmt_test.go by removing the literal merge-conflict markers surrounding
the resolve and servererr imports. Preserve both required imports and ensure the
resulting import declaration is valid Go.

Comment thread pkg/server/driver_tidb.go
Comment on lines +111 to +135
if uint64(len(ts.boundParams[paramID]))+uint64(len(data)) > ts.ctx.GetSessionVars().MaxAllowedPacket {
// MySQL reports the packet-too-large error on the following EXECUTE, not on SEND_LONG_DATA.
// Stop appending more bytes once the limit is exceeded so the statement cannot grow unboundedly.
ts.boundParamsTooLarge = true
return nil
}
ts.boundParams[paramID] = append(ts.boundParams[paramID], data...)
}
return nil
}

// CheckLongDataSize implements PreparedStatement CheckLongDataSize method.
func (ts *TiDBStatement) CheckLongDataSize() error {
if ts.boundParamsTooLarge {
return servererr.ErrNetPacketTooLarge
}
maxAllowedPacket := ts.ctx.GetSessionVars().MaxAllowedPacket
for _, boundParam := range ts.boundParams {
if uint64(len(boundParam)) > maxAllowedPacket {
return servererr.ErrNetPacketTooLarge
}
}
return nil
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Use one statement-wide byte budget in both implementation and test.

The implementation only enforces per-parameter lengths, and the test encodes that same incorrect behavior; together they allow and approve totals above MaxAllowedPacket.

  • pkg/server/driver_tidb.go#L111-L135: maintain and validate a prepared-statement-wide accumulated byte count, resetting it during Reset.
  • pkg/server/conn_stmt_test.go#L401-L409: keep the combined payload at the limit, then add one byte and assert the overflow behavior.
📍 Affects 2 files
  • pkg/server/driver_tidb.go#L111-L135 (this comment)
  • pkg/server/conn_stmt_test.go#L401-L409
🤖 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/server/driver_tidb.go` around lines 111 - 135, The prepared statement
currently checks packet size per parameter instead of against one statement-wide
byte budget. In pkg/server/driver_tidb.go lines 111-135, update TiDBStatement’s
long-data handling and CheckLongDataSize to track cumulative bound bytes, reject
additions that exceed MaxAllowedPacket, and reset the accumulated count in
Reset. In pkg/server/conn_stmt_test.go lines 401-409, adjust the test to keep
the combined payload exactly at the limit, then append one byte and assert the
overflow error.

@ti-chi-bot

ti-chi-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

@ti-chi-bot: 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_2 f1b6f23 link true /test check-dev2
idc-jenkins-ci-tidb/unit-test f1b6f23 link true /test unit-test
idc-jenkins-ci-tidb/mysql-test f1b6f23 link true /test mysql-test
idc-jenkins-ci-tidb/check_dev f1b6f23 link true /test check-dev
idc-jenkins-ci-tidb/build f1b6f23 link true /test build

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.

@ti-chi-bot ti-chi-bot Bot added cherry-pick-approved Cherry pick PR approved by release team. and removed do-not-merge/cherry-pick-not-approved labels Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cherry-pick-approved Cherry pick PR approved by release team. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants