session: route LOAD DATA LOCAL to the pessimistic txn provider#68317
session: route LOAD DATA LOCAL to the pessimistic txn provider#68317joechenrh wants to merge 3 commits into
Conversation
LOAD DATA LOCAL streams the file from the client as one-shot data — once the client has sent the terminating empty packet, the MySQL protocol gives the server no way to request the file again. Today, default-configured TiDB (tidb_txn_mode=PESSIMISTIC + autocommit=ON) routes auto-committed DML to the optimistic provider via decideTxnMode(), which leaves LOAD DATA exposed to the session-level optimistic retry path (doCommitWithRetry -> s.retry). When commit hits a retryable error such as kv:8022 (TxnLockNotFound), the retry path re-executes the statement and calls LoadDataReaderBuilder.Build a second time. The new Build asks the client to re-send the file, but the client has already finished sending and is waiting for the response packet. The new read returns EOF and surfaces as [ERROR] [conn.go:2144] "drain connection failed in load data" [error=EOF] masking the real commit error from the user. Carve LOAD DATA LOCAL out of the optimistic-by-default rule in decideTxnMode so it runs on the pessimistic provider, alongside the existing pessimistic-auto-commit carve-out. The retry guard at doCommitWithRetry short-circuits on pessimistic txns, so the original commit error reaches the client unchanged and the user can decide how to re-run the LOAD DATA. Includes a regression test that observes TxnCtx.IsPessimistic during the LOAD DATA file read. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@joechenrh I've received your pull request and will start the review. I'll conduct a thorough review covering code quality, potential issues, and implementation details. ⏳ This process typically takes 10-30 minutes depending on the complexity of the changes. ℹ️ Learn more details on Pantheon AI. |
|
[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 Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR forces autocommitted ChangesLOAD Data Transaction Mode Enforcement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
Hi @joechenrh. 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. |
Address review feedback to keep the inline comment to the essential invariant; the full rationale lives in the PR description and the linked issue (pingcap#68316). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per CLAUDE.local.md, unit test functions (TestXxx) should not carry docstring comments unless explicitly requested. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@joechenrh: The following tests failed, say
Full PR test history. Your PR dashboard. 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. I understand the commands that are listed here. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #68317 +/- ##
================================================
- Coverage 77.7059% 77.0190% -0.6870%
================================================
Files 1991 1973 -18
Lines 552094 552848 +754
================================================
- Hits 429010 425798 -3212
- Misses 122164 127047 +4883
+ Partials 920 3 -917
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
What problem does this PR solve?
Issue Number: close #68316
Problem Summary:
LOAD DATA LOCAL streams the file from the client as one-shot data. Once the client has sent the terminating empty packet, the MySQL protocol gives the server no way to request the file again.
decideTxnMode(pkg/session/session.go:4910) chooses the txn provider for an auto-committed statement. The fall-through path returnsast.OptimisticunlessshouldUsePessimisticAutoCommit(stmt)is true, and that function ultimately delegates toisDMLStatement, which intentionally excludes LOAD DATA and IMPORT (session.go:4984):The combined effect:
pessimistic-auto-commitdefaultINSERT/UPDATE/DELETELOAD DATAfalsetrueisDMLStatement)Running on the optimistic provider exposes LOAD DATA to the session-level retry path in
doCommitWithRetry -> s.retry. When commit hits a retryable error such askv:8022 TxnLockNotFound, the retry path re-executes the statement and callsLoadDataReaderBuilder.Builda second time. The newBuildasks the already-finished client to re-send the file; the read returnsEOFand surfaces as:masking the real commit error from the user.
What changed and how does it work?
Carve LOAD DATA LOCAL out of the optimistic-by-default rule in
decideTxnMode, alongside the existingpessimistic-auto-commitcarve-out:Placing the carve-out in
decideTxnModerather thanisDMLStatementis deliberate: it forces LOAD DATA onto the pessimistic provider regardless ofpessimistic-auto-commit, so the fix covers both classic builds (wherepessimistic-auto-commit=falsewould otherwise still route LOAD DATA to optimistic) and nextgen builds. The retry guard atdoCommitWithRetry(session.go:873) short-circuits on pessimistic txns, so the original commit error reaches the client unchanged and the user can decide how to re-run the LOAD DATA.This mirrors the design intent of the existing
!s.sessionVars.BatchInsertguard atsession.go:873, which was added to prevent the same class of "re-execute a non-replayable statement" hazard for theBatchInsertpath.A regression test (
TestLoadDataLocalUsesPessimisticTxn) observesTxnCtx.IsPessimisticduring the LOAD DATA file read. Verified fail-before / pass-after on stock master.Check List
Tests
Side effects
Documentation
Release note
Summary by CodeRabbit
Bug Fixes
Tests
Chores