Skip to content

eventservice: split large scanned transactions#5511

Draft
asddongmen wants to merge 12 commits into
pingcap:masterfrom
asddongmen:0626-split-big-txn
Draft

eventservice: split large scanned transactions#5511
asddongmen wants to merge 12 commits into
pingcap:masterfrom
asddongmen:0626-split-big-txn

Conversation

@asddongmen

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Issue Number: close #xxx

EventBroker currently scans a whole large upstream transaction into memory before it can send DML to the event collector. Very large transactions can therefore cause OOM, especially when UK-changing updates cache deferred insert rows in memory.

What is changed and how it works?

This PR adds row-level eventstore scan resume tokens and uses them in EventBroker scanning so transaction-atomicity=none can emit bounded fragments from one large transaction without sending resolved-ts for that commit-ts early.

It also spills deferred insert halves of UK-changing updates to local disk, drains them after the original delete phase, and cleans spill state on reset/remove. EventCollector reset semantics remain checkpoint-ts based.

Check List

Tests

  • Unit test

Questions

Will it cause performance regression or break compatibility?

No compatibility break is expected. The split path is only enabled when transaction atomicity allows splitting. It reduces EventBroker peak memory for large transactions, with local spill I/O for UK-changing update insert halves.

Do you need to update user documentation, design documentation or monitoring documentation?

No user documentation update is required for this internal scan behavior change.

Release note

Support splitting large transactions during EventBroker DML scanning to reduce OOM risk.

@ti-chi-bot

ti-chi-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ed31e2ac-5e8d-409b-9c09-08fe272715a1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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.

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 26, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces support for row-level resume tokens and large transaction spilling in the event service. It adds a new EventIteratorWithScanPosition interface, updates the event store iterator to track and return opaque scan positions, and implements disk-based spilling for large transactions via largeTxnInsertSpill and largeTxnScanState. Review feedback identifies two key issues in large_txn_spill.go: a potential resource leak where a failed Close() in Cleanup() skips deleting the temporary file, and a loose record length check that could lead to OOM panics if the spill file is corrupted.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +104 to +119
if err := s.Close(); err != nil {
return err
}
if s.cleaned {
return nil
}
s.cleaned = true
if s.path == "" {
return nil
}

err := os.Remove(s.path)
if err != nil && !os.IsNotExist(err) {
return errors.Trace(err)
}
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.

medium

If s.Close() returns an error, Cleanup() will return early and skip the execution of os.Remove(s.path). This will cause the temporary spill file to be leaked on disk. We should ensure that os.Remove is always attempted even if s.Close() fails, and that s.cleaned is set to true to prevent future cleanup attempts.

	closeErr := s.Close()
	if s.cleaned {
		if closeErr != nil {
			return errors.Trace(closeErr)
		}
		return nil
	}
	s.cleaned = true
	if s.path == "" {
		if closeErr != nil {
			return errors.Trace(closeErr)
		}
		return nil
	}
	removeErr := os.Remove(s.path)
	if removeErr != nil && !os.IsNotExist(removeErr) {
		if closeErr != nil {
			return errors.Trace(closeErr)
		}
		return errors.Trace(removeErr)
	}
	if closeErr != nil {
		return errors.Trace(closeErr)
	}
	return nil

Comment on lines +145 to +147
if recordLen > uint64(int(^uint(0)>>1)) {
return nil, errors.Errorf("large txn spill record is too large: %d", recordLen)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

Enforcing a limit of math.MaxInt is extremely loose and can still lead to out-of-memory (OOM) panics when allocating memory for data (e.g., make([]byte, int(recordLen))) if the spill file is corrupted or contains invalid data. Since a single KV entry size in TiKV is typically limited to a few megabytes (and at most 128MB), we should enforce a much safer and more reasonable upper bound (e.g., 128MB) to prevent OOM vulnerabilities.

Suggested change
if recordLen > uint64(int(^uint(0)>>1)) {
return nil, errors.Errorf("large txn spill record is too large: %d", recordLen)
}
const maxRecordLen = 128 * 1024 * 1024 // 128MB
if recordLen > maxRecordLen {
return nil, errors.Errorf("large txn spill record is too large: %d", recordLen)
}

@ti-chi-bot

ti-chi-bot Bot commented Jun 29, 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 lidezhu 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

@ti-chi-bot

ti-chi-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown

[FORMAT CHECKER NOTIFICATION]

Notice: To remove the do-not-merge/needs-linked-issue label, please provide the linked issue number on one line in the PR body, for example: Issue Number: close #123 or Issue Number: ref #456.

📖 For more info, you can check the "Contribute Code" section in the development guide.

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

Labels

do-not-merge/needs-linked-issue do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. 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.

1 participant