Skip to content

feat(auto-increment): add transactional epoch fence#26027

Merged
XuPeng-SH merged 10 commits into
matrixorigin:mainfrom
VioletQwQ-0:codex/issue-23143-auto-increment-epoch-fence
Jul 22, 2026
Merged

feat(auto-increment): add transactional epoch fence#26027
XuPeng-SH merged 10 commits into
matrixorigin:mainfrom
VioletQwQ-0:codex/issue-23143-auto-increment-epoch-fence

Conversation

@VioletQwQ-0

Copy link
Copy Markdown
Collaborator

What type of PR is this?

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

Which issue(s) this PR fixes:

issue #23143

What this PR does / why we need it:

This is the first AUTO_INCREMENT-specific prerequisite split from the closed #25883. It does not expose ALTER TABLE ... AUTO_INCREMENT=N yet.

The invariant introduced here is: a CN write carries the AUTO_INCREMENT epoch observed when its values were allocated, and TN accepts the write only when that epoch matches the table epoch. Once a table enters a fenced epoch, legacy writers that cannot provide an epoch fail closed.

Correctness requirement Change in this PR
Preserve the allocator generation across the write path Persist the epoch in SchemaExtra / plan.TableDef, propagate it through disttae workspace, row and object writes, flush/compaction, RPC, and TN relations
Prevent stale cached values from committing after a reset Validate the known epoch at TN prepare/commit and require every epoch transition to be exactly current + 1
Keep the fence effective after restart Rebuild committed DML watermarks during replay and keep prepared replay transactions fenced until commit or rollback
Remain compatible before the feature is enabled Treat an unknown legacy epoch as zero only while the table epoch is zero; after the first reset, unknown writers are rejected

Additional guards reject epoch exhaustion before mutation and keep ordinary schema ALTER operations from advancing the AUTO_INCREMENT epoch.

Explicit non-goals

  • no allocator offset/cache reset API;
  • no COPY/CLONE allocator reconciliation;
  • no user-facing ALTER TABLE ... AUTO_INCREMENT=N planner or compile entry point;
  • no generic prepared/committing 2PC recovery redesign. The independent TN route/cancellation prerequisite was merged in fix(txn): restore recovery routes and cancellation #25956.

Diff size

  • handwritten code and tests: 23 files, +1283/-131;
  • generated protobuf code: 2 files, +1565/-1079;
  • total: 25 files. Proto sources and generated files are committed together.

Validation

  • go test ./pkg/vm/engine/disttae ./pkg/vm/engine/tae/catalog ./pkg/vm/engine/tae/rpc ./pkg/vm/engine/tae/txn/txnimpl ./pkg/vm/engine/tae/db/test
  • focused -race coverage for epoch transitions and replay commit/rollback lifecycle
  • protobuf regeneration stability check
  • git diff --check
  • mo-pr-preflight-review: PASS at exact head 4122a7add078c79757121a4add2d8771113c7980
  • mo-self-review: no open blocker

The PR is intentionally Draft while its full CI runs and while this prerequisite is reviewed independently.

@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 →

@XuPeng-SH XuPeng-SH 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.

Approved at exact head a7510bf.

Correctness review:

  • The dedicated epoch is persisted independently of ordinary schema version and TN enforces monotonic current+1 transitions with overflow rejection.
  • CN propagation is closed across in-memory writes, object writes, deletes, soft deletes, transfer, workspace flush, and CN-object compaction. Flush grouping includes table+epoch+known, so generations cannot be coalesced accidentally.
  • The live race is closed by TAE prepare ordering: DML prepared first publishes its prepare watermark before a later ALTER validates; ALTER prepared first publishes a committing schema node that later DML waits on and then rejects by epoch.
  • Legacy unknown writers map to epoch zero only, so they remain compatible before the first reset and fail closed afterward.
  • WAL replay obtains the real dirty-table set from the serialized TxnMemo; replayed prepared transactions fence the table until both commit and rollback terminal paths resolve them.

Unhappy-path review found no blocking leak, hang, stale-fence, or unbounded-growth path. The committed watermark is monotonic; prepared replay registrations have symmetric commit/rollback cleanup; schema waits terminate through the transaction state transition.

Fresh local validation at this exact head passed both normal and race-focused matrices for disttae, catalog, rpc, txnimpl, and TAE db tests. git diff --check also passed. Current GitHub CI is green.

Non-blocking requirements for the follow-up user-facing integration:

  1. The allocator reset/cache protocol must guarantee that the epoch attached to a write is the generation that actually allocated its values; merely reading a refreshed relation epoch after allocation would be insufficient.
  2. Enabling reset must be gated against old TNs that do not enforce these new protobuf fields.
  3. COPY/CLONE reconciliation and end-to-end restart/multi-CN coverage should remain explicit acceptance gates, as stated in #23143.

Process nit: the PR body still says intentionally Draft, while the PR is currently Ready for review.

@mergify mergify Bot added the queued label Jul 22, 2026
@mergify

mergify Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-07-22 11:24 UTC · Rule: main · triggered by rule Automatic queue on approval for main
  • 🟠 Checks running · in-place
  • 🚫 Left the queue2026-07-22 11:47 UTC · at 5f21beba0e74162020705452de369d0ee34f44cb

This pull request spent 22 minutes 41 seconds in the queue, with no time running CI.

Waiting for
  • any of: [🛡 GitHub branch protection]
    • 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)
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
  • any of: [🛡 GitHub branch protection]
    • 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)
    • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
  • any of: [🛡 GitHub branch protection]
    • 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)
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of: [🛡 GitHub branch protection]
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
  • any of: [🛡 GitHub branch protection]
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
    • check-success = Matrixone Utils CI / Coverage
  • any of: [🛡 GitHub branch protection]
    • check-neutral = Matrixone CI / SCA Test on Linux/arm64
    • check-skipped = Matrixone CI / SCA Test on Linux/arm64
    • check-success = Matrixone CI / SCA Test on Linux/arm64
All conditions
  • any of [🛡 GitHub branch protection]:
    • 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)
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • 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)
    • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
  • any of [🛡 GitHub branch protection]:
    • 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)
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
    • check-success = Matrixone Utils CI / Coverage
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone CI / SCA Test on Linux/arm64
    • check-skipped = Matrixone CI / SCA Test on Linux/arm64
    • check-success = Matrixone CI / SCA Test on Linux/arm64
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-approved [🛡 GitHub branch protection] (documentation)
  • github-review-decision = APPROVED [🛡 GitHub branch protection] (documentation)

Reason

Pull request #26027 has been dequeued

Pull request from fork cannot be queued. This pull request comes from a fork, and Mergify needs the author's permission to update its branch.

The author needs to enable "Allow edits from maintainers" on this pull request.

Hint

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.
If you do update this pull request, 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.

Tick the box to put this pull request back in the merge queue (same as @mergifyio queue).

  • Requeue this pull request

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants