Skip to content

fix(logtail): stream-publish txn tails to remove batch-wide wait (#24325)#24383

Open
ck89119 wants to merge 3 commits into
matrixorigin:4.0-devfrom
ck89119:cherry-pick-24326-to-4.0-dev
Open

fix(logtail): stream-publish txn tails to remove batch-wide wait (#24325)#24383
ck89119 wants to merge 3 commits into
matrixorigin:4.0-devfrom
ck89119:cherry-pick-24326-to-4.0-dev

Conversation

@ck89119
Copy link
Copy Markdown
Contributor

@ck89119 ck89119 commented May 13, 2026

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #24325

What this PR does / why we need it:

Cherry-pick #24326 to 4.0-dev.

…rixorigin#24325) (matrixorigin#24326)

### Background

PR matrixorigin#22475 refactored `Manager.onTxnLogTails` in
`pkg/vm/engine/tae/logtail/mgr.go` so that a batch of txns are
collected in parallel and then published after a batch-wide
`collectWg.Wait()`:

```go
for i, item := range items {
mgr.collectWg.Add(1)
mgr.collectPool.Submit(func() {
defer mgr.collectWg.Done()
txn.GetStore().WaitEvent(txnif.WalPreparing)
...
state := txn.GetTxnState(true)
mgr.orderedList[i] = txnTail
})
}
mgr.collectWg.Wait()                 // ← blocks on slowest txn
for i := range items {
mgr.generateLogtailWithTxn(...)  // serial push AFTER all ready
}
```

Batch size is 100. Under high-concurrency short-tx workloads (e.g.
sysbench oltp_delete t=32), the batch regularly fills up and a single
slow txn defers logtail publish for all others. CN observes this
through `txnOperator.unlock → timestampWaiter.GetTimestamp` waiting on
`NotifyLatestCommitTS`, which in RC isolation gates commit return,
inflating per-txn latency.

This causes issue matrixorigin#24325: sysbench oltp_delete t=32 standalone TPS
drops ~28% at the exact commit that merged matrixorigin#22475, and ~17% on main
HEAD vs 3.0-dev (which does not carry matrixorigin#22475).

### Fix

Replace the batch-wide wait with per-slot buffered channels + a serial
publisher that reads slot 0, 1, 2, ... in order:

- each submit goroutine signals its own `chan *txnWithLogtails` on completion
- the publisher loops through slots in index order, `<-ch` per slot
- a slow txn only blocks the publisher up to its slot; it does not
delay the collection of later txns nor the publishing of earlier
already-ready txns

All other matrixorigin#22475 changes (single `logtailQueue`, `collectPool`,
`WaitEvent(WalPreparing)` event) are preserved.

Monotonicity of `previousSaveTS` inside `generateLogtailWithTxn` is
preserved since publish still happens in index (PrepareTS) order.

### Benchmark

`sysbench oltp_delete.lua` on standalone MO, Apple Silicon arm64,
GOMAXPROCS=10, 10 tables × 1M rows, threads=32, time=60s,
db-ps-mode=disable, skip_trx=on, 3 independent runs (fresh prepare +
cleanup + mo-service restart per run), mean of 30-60s steady window:

| Version                          | Steady TPS | timestampWaiter per-txn |
|----------------------------------|-----------:|------------------------:|
| main before this PR              |       7970 |                  585 μs |
| **main + this fix**              |   **9402** |              **334 μs** |
| 3.0-dev (no matrixorigin#22475)              |       9326 |                  127 μs |
| 8b3700a (commit before matrixorigin#22475) |      10487 |                  123 μs |

TPS recovers **+17.9% over current main** and passes 3.0-dev. The
remaining tw gap vs 3.0-dev (334 μs → 127 μs) is secondary and does
not materially affect TPS at t=32; it can be pursued separately if
needed.

### Ablation (confirming the hotspot is exactly this function)

Each candidate fix applied in isolation on main HEAD, 3-run mean:

| Candidate fix                                           | Steady TPS | tw per-txn |
|---------------------------------------------------------|-----------:|-----------:|
| main baseline                                           |       7970 |     585 μs |
| parallelize `LogEntryWriter.Finish()` marshal           |       8283 |     592 μs |
| synchronous marshal in `cmdmgr.ApplyTxnRecord`          |       8280 |     599 μs |
| **this PR (stream-publish in `onTxnLogTails`)**         |   **9402** |     334 μs |

Only touching `onTxnLogTails` produces the recovery; marshal-path
rewrites do not, which rules out marshal deferral itself as the
regression source.

Approved by: @XuPeng-SH
@ck89119 ck89119 requested a review from XuPeng-SH as a code owner May 13, 2026 10:48
@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Copy link
Copy Markdown
Contributor

@XuPeng-SH XuPeng-SH left a comment

Choose a reason for hiding this comment

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

Clean cherry-pick of #24326 (already merged to main) to 4.0-dev. Diffs are identical. LGTM.

@aptend
Copy link
Copy Markdown
Contributor

aptend commented May 13, 2026

@Mergifyio refresh

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 13, 2026

refresh

✅ Pull request refreshed

@mergify mergify Bot added the queued label May 14, 2026
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 14, 2026

Merge Queue Status

  • Entered queue2026-05-14 03:07 UTC · Rule: release-4.0
  • Checks started · in-place
  • 🚫 Left the queue2026-05-14 04:10 UTC · at 02e6f055c66bf87067a14c4f136178b1cb3c5c93

This pull request spent 1 hour 3 minutes 34 seconds in the queue, with no time running CI.

Waiting for any of
  • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
  • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
  • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
All conditions
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
  • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
  • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-decision = APPROVED [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / SCA Test on Ubuntu/x86
    • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
    • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Utils CI / Coverage
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86

Reason

The merge conditions cannot be satisfied due to failing checks

Hint

You may have to fix your CI before adding the pull request to the queue again.
If you update this pull request, to fix the CI, it will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue instead, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

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

Labels

dequeued kind/bug Something isn't working size/L Denotes a PR that changes [500,999] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants