Skip to content

eventservice: split large scanned transactions#5511

Open
asddongmen wants to merge 39 commits into
pingcap:masterfrom
asddongmen:0626-split-big-txn
Open

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

Conversation

@asddongmen

@asddongmen asddongmen commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Issue Number: close #5596

EventBroker scans a whole large transaction, which can OOM CDC.

What is changed and how it works?

This PR adds row-level EventStore resume positions so transaction-atomicity=none emits bounded fragments without advancing resolved-ts early. Deferred insert halves of unique-key updates are spilled to disk and drained or cleaned across reset/remove.

TiUP E2E comparison

Runs used one CDC limited to 32 GiB, upstream/downstream TiDB, and the same workload.

Workload This PR master
100 consecutive 1 GiB transactions Synced without OOM Repeated OOM/restart; could not finish syncing
One realtime 20 GiB transaction OOMed once during ingestion; after restart, replayed as an incremental scan; checksum 33/33 Never reached it: six earlier OOMs; no checksum

The 20 GiB OOM is caused mainly by realtime logpuller txnMatcher PREWRITE caching and overlapping ingestion buffers, before EventBroker scan splitting applies. asddongmen/tigate#2 fixes this matcher pressure and passed a separate 20 GiB no-OOM test; whether to merge it will be evaluated separately.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (results above)

The integration-test suite covers all changed workflows: row resume, interruption, unique-key spill/drain, CMEK spill encryption, dispatcher reset, and end-to-end consistency. Focused unit tests cover edge cases.

Questions

Will it cause performance regression or break compatibility?

No compatibility break is expected. Splitting applies only when transaction atomicity permits it; unique-key updates may add local spill I/O.

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

An internal design document is included; no user-facing update is required.

Release note

Support splitting large transactions during EventBroker 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

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

This PR adds row-level scan resumption and spill-backed large-transaction processing across eventstore and eventservice. It also adds progress metrics, cleanup paths, integration coverage, a dispatcher-reset failpoint, and a dependency declaration update.

Changes

Large Transaction Split & Spill

Layer / File(s) Summary
Scan contracts and configuration
logservice/eventstore/scan_request.go, pkg/common/table_span.go, pkg/config/*, pkg/errors/error.go
Adds opaque scan cursors, immutable scan progress, a 1 MB large-transaction threshold, and spill-file error handling.
EventStore row-level resumption
logservice/eventstore/event_store.go, logservice/eventstore/format.go, logservice/eventstore/*_test.go
Extends iterator APIs and Pebble bounds to resume from row-level positions.
Spill storage and transaction state
pkg/spill/*, pkg/eventservice/large_txn_*
Adds length-prefixed record files, encrypted insert spills, drain phases, retry handling, and cleanup.
Scanner, broker, and metrics
pkg/eventservice/event_scanner.go, txn_scan_strategy.go, dispatcher_stat.go, event_broker.go, metrics*
Threads scan requests and progress through scanning, splits and drains large transactions, persists row cursors, cleans dispatcher state, and records metrics.
Integration workflow
tests/integration_tests/large_txn_split/*, tests/integration_tests/run_light_it_in_ci.sh
Adds large-transaction workload configuration and CI execution.

Dispatcher batch-reset failpoint

Layer / File(s) Summary
Failpoint-triggered dispatcher reset
downstreamadapter/eventcollector/dispatcher_stat*
Tracks forwarded DML and conditionally resets the current event service after batch handling.

Dependency declaration

Layer / File(s) Summary
Prometheus dependency declaration
go.mod
Moves the existing Prometheus client model dependency to the direct require block.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EventBroker
  participant DispatcherStat
  participant EventScanner
  participant EventStore
  participant SpillFile

  EventBroker->>DispatcherStat: request scan cursor
  DispatcherStat-->>EventBroker: range and resume position
  EventBroker->>EventScanner: scan request
  EventScanner->>EventStore: iterate with cursor
  EventStore-->>EventScanner: event and scan position
  EventScanner->>SpillFile: append large-transaction inserts
  EventScanner-->>EventBroker: events and scan progress
  EventBroker->>DispatcherStat: persist scan progress
Loading

Possibly related PRs

  • pingcap/ticdc#4953: Both changes modify event-store key encoding and iterator bound construction.
  • pingcap/ticdc#4985: Both changes modify EventStore.GetIterator and scanner iterator integration.
  • pingcap/ticdc#5643: Both changes modify event_broker.go, including doScan control flow.

Suggested labels: lgtm, approved

Suggested reviewers: hongyunyan, flowbehappy, 3aceshowhand

Poem

A rabbit split a transaction wide,
And kept each row’s position beside.
Spills were read, then cleaned away,
While dispatchers reset in play.
🐇📦

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.99% 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 addresses #5596 by preventing whole-transaction in-memory scans with row-level resume tokens and spill to disk for deferred inserts.
Out of Scope Changes check ✅ Passed The changes stay focused on large-transaction splitting, scan resume, spill cleanup, metrics, and tests; no unrelated scope stands out.
Title check ✅ Passed The title is concise and accurately summarizes the main change: splitting large scanned transactions in eventservice.
Description check ✅ Passed The description matches the template well, including issue number, changes, tests, questions, 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.

@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 thread pkg/eventservice/large_txn_spill.go Outdated
Comment thread pkg/eventservice/large_txn_spill.go Outdated
Signed-off-by: dongmen <414110582@qq.com>
# Conflicts:
#	pkg/eventservice/event_scanner.go
Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
Introduce pkg/spill as a shared temp-file record store with chunked append, handle reads, sequential reads, and cleanup. Refactor eventservice large transaction insert spill to reuse it while keeping RawKVEntry encoding local.
@lidezhu

lidezhu commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

One thing to note: may be we need respect CMEK for the spill file?

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/eventservice/large_txn_spill.go (1)

104-109: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Thread the scan context through spill encryption Append and Next pass context.Background() into EncryptData/DecryptData; on cache miss those calls can block on TiKV metadata fetch or KMS decrypt, so the spill path ignores cancellation when the dispatcher is removed or the scan aborts. Pass the caller’s context instead.

🤖 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/eventservice/large_txn_spill.go` around lines 104 - 109, Update the spill
encryption flow in Append and Next to pass each method’s caller-provided context
to EncryptData and DecryptData instead of context.Background(). Preserve the
existing encryption/decryption and error propagation behavior while ensuring
cancellation reaches metadata and KMS operations.
🤖 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/eventservice/txn_scan_strategy.go`:
- Around line 453-456: Update getOrCreateLargeTxnState to return the appropriate
predefined repository error for a missing dispatcherStat instead of constructing
a new errors.New value. Reuse the existing error symbol used for this invariant,
following the repository’s established error-handling conventions and preserving
the current failure path.

---

Nitpick comments:
In `@pkg/eventservice/large_txn_spill.go`:
- Around line 104-109: Update the spill encryption flow in Append and Next to
pass each method’s caller-provided context to EncryptData and DecryptData
instead of context.Background(). Preserve the existing encryption/decryption and
error propagation behavior while ensuring cancellation reaches metadata and KMS
operations.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d38fda9a-5d90-40b8-bc12-e75838a11eab

📥 Commits

Reviewing files that changed from the base of the PR and between b758366 and 8a9646d.

📒 Files selected for processing (19)
  • logservice/eventstore/event_store.go
  • logservice/eventstore/event_store_test.go
  • logservice/eventstore/format.go
  • logservice/eventstore/pebble_test.go
  • logservice/eventstore/scan_request.go
  • pkg/common/table_span.go
  • pkg/eventservice/dispatcher_stat.go
  • pkg/eventservice/dispatcher_stat_test.go
  • pkg/eventservice/event_broker.go
  • pkg/eventservice/event_broker_test.go
  • pkg/eventservice/event_scanner.go
  • pkg/eventservice/event_scanner_benchmark_test.go
  • pkg/eventservice/event_scanner_test.go
  • pkg/eventservice/event_service_test.go
  • pkg/eventservice/large_txn_spill.go
  • pkg/eventservice/large_txn_spill_test.go
  • pkg/eventservice/large_txn_state.go
  • pkg/eventservice/scan_progress.go
  • pkg/eventservice/txn_scan_strategy.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • logservice/eventstore/format.go
  • logservice/eventstore/pebble_test.go
  • pkg/eventservice/large_txn_state.go
  • pkg/eventservice/event_broker.go
  • pkg/eventservice/event_scanner_test.go

Comment thread pkg/eventservice/txn_scan_strategy.go
Signed-off-by: dongmen <414110582@qq.com>

# Conflicts:
#	pkg/eventservice/event_broker.go
Signed-off-by: dongmen <414110582@qq.com>
@ti-chi-bot ti-chi-bot Bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Jul 21, 2026
Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
@asddongmen

Copy link
Copy Markdown
Collaborator Author

/test all

Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
Document scan progress and transaction scan strategies, and simplify the spill insert drain control flow without changing its behavior.

Signed-off-by: dongmen <414110582@qq.com>
@asddongmen asddongmen added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 24, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lidezhu, wk989898

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

The pull request process is described 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 added lgtm approved and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jul 24, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-07-21 08:42:24.945768569 +0000 UTC m=+1307930.981863625: ☑️ agreed by wk989898.
  • 2026-07-24 14:12:35.980524919 +0000 UTC m=+1586942.016619975: ☑️ agreed by lidezhu.

@asddongmen

Copy link
Copy Markdown
Collaborator Author

One thing to note: may be we need respect CMEK for the spill file?

Yes, thank you. I have added that part.

Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
Signed-off-by: dongmen <414110582@qq.com>
@asddongmen

Copy link
Copy Markdown
Collaborator Author

/test pull-cdc-mysql-integration-heavy-next-gen

Signed-off-by: dongmen <414110582@qq.com>
@asddongmen

Copy link
Copy Markdown
Collaborator Author

/test pull-cdc-mysql-integration-heavy-next-gen

@ti-chi-bot

ti-chi-bot Bot commented Jul 25, 2026

Copy link
Copy Markdown

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

Test name Commit Details Required Rerun command
pull-cdc-mysql-integration-heavy-next-gen 4932b7e link false /test pull-cdc-mysql-integration-heavy-next-gen

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

approved do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. lgtm 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.

eventservice: EventBroker can OOM when syncing large transactions

3 participants