Skip to content

[fix](cloud) Avoid caching partition versions with pending transactions - #68104

Merged
hello-stephen merged 7 commits into
apache:masterfrom
mymeiyi:fix-daemon-get-version
Oct 23, 2026
Merged

hello-stephen merged 7 commits into
apache:masterfrom
mymeiyi:fix-daemon-get-version

Conversation

@mymeiyi

@mymeiyi mymeiyi commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Non-waiting version reads could cache an older partition version while a lazy commit was still pending.
Return per-partition pending state alongside scalar and batch versions. FE keeps pending responses uncached and restores cache validity only for the epoch captured before the RPC.

Copilot AI lite review requested due to automatic review settings September 17, 2026 03:22
@mymeiyi
mymeiyi requested a review from gavinchou as a code owner September 17, 2026 03:22
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@mymeiyi

mymeiyi commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

/review

Copilot AI 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.

🟡 Changes recommended

Critical cache consistency and version-publication issues remain unresolved, along with a partial-refresh failure path.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR hardens Cloud version synchronization against lazy commits, missed pushes, and concurrent cache refreshes.

Changes:

  • Stages and validates partition snapshots before publication.
  • Improves cache invalidation, synchronization tracking, and bounded retries.
  • Adds FE unit tests and cloud regression coverage.
File summaries
File Summary
regression-test/suites/cloud_p0/version/test_lazy_commit_version_syncer.groovy Adds lazy-commit regression coverage.
fe/fe-core/src/test/java/org/apache/doris/cloud/catalog/CloudSyncVersionDaemonTest.java Tests synchronization, retries, invalidation, and snapshot consistency.
fe/fe-core/src/test/java/org/apache/doris/catalog/OlapTableTest.java Tests table cache semantics.
fe/fe-core/src/main/java/org/apache/doris/common/proc/PartitionsProcDir.java Critical (1): table and partition versions may be inconsistent after pending transactions. Moderate (2): partial batch publication can leave inconsistent caches on failure.
fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudSyncVersionDaemon.java Stages, validates, and publishes partition snapshots.
fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudPartition.java Critical (1): foreground snapshots can combine old and newly fetched partition versions.
fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java Critical (3): table-version caching can validate stale SQL results during pending publication.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions 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.

Requesting changes after a static-only exact-head review of dd23972f9672d90d2b2097cace05cb2a8fc4b307.

Checkpoint conclusions:

  • Goal/correctness: the staged daemon path improves failure atomicity and epoch preservation, but SQL-cache token/snapshot coherence, forced publication, and disable/re-enable transitions still have stale or mixed-cache gaps. The first two are already covered by live same-head threads; the attached comments add only distinct issues.
  • Scope/tests: the production changes are focused and the added tests are broad, but they miss the attached cases; the unchanged finite-TTL regression directly conflicts with the new disabled-syncer behavior.
  • Concurrency/lifecycle: metadata/version-lock ordering was traced and no inverse-lock deadlock was found. The forced path nevertheless waits for healthy lazy commits while holding metadata read locks, and the mutable syncer flag has no enable-generation recovery hook.
  • Compatibility/data paths: there is no new persisted format, FE/BE field, or RPC symbol; wait_for_pending_txn is already optional. Commit/push, scalar/batch refresh, SQL-cache, forced SHOW, DDL/topology, and add/drop/restore paths were checked.
  • Errors/observability/performance: staged daemon failures remain retryable and logs identify failed tables, but hot-write non-convergence and catalog-wide snapshot retention create avoidable RPC, cache-miss, heap, and GC pressure.

No additional user focus was supplied. Per the review contract, I did not build or run tests; git diff --check passed. Four same-head Copilot threads were present at the final recheck, so their SQL-cache, forced-sync, and foreground-snapshot issues are not duplicated here.

@mymeiyi
mymeiyi force-pushed the fix-daemon-get-version branch from dd23972 to a65e8a1 Compare September 17, 2026 08:10
@mymeiyi mymeiyi changed the title [fix](cloud) Prevent stale version caches during lazy commit [fix](cloud) Avoid caching partition versions with pending transactions Sep 17, 2026
@mymeiyi
mymeiyi force-pushed the fix-daemon-get-version branch 2 times, most recently from f78d005 to 7bae554 Compare September 17, 2026 08:33
@mymeiyi

mymeiyi commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions 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.

Requesting changes after a static-only exact-head review of 7bae5545b7d6394df738fbeb726c578680ac4033.

Checkpoint conclusions:

  • Goal/correctness: the new-FE/new-MS pending marker correctly keeps pending partition versions from validating the cache, but the two rolling-upgrade directions remain unsafe. A new FE trusts omitted state from an old MS, while an old FE ignores the new response-only field from a new MS.
  • Scope/reuse: the homogeneous-version implementation is focused and reuses the existing cache epoch mechanism; current-MS scalar and batch producers preserve response order and cardinality.
  • Concurrency/lifecycle: foreground, daemon, push, invalidation, retry, and lock orderings were traced. The captured epoch cannot acknowledge a later invalidation, monotonic publication prevents downgrade, and no new deadlock or runtime-field lifecycle defect was found. The previously reported mixed-snapshot and SQL-cache races were not duplicated.
  • Compatibility/parallel paths: additive protobuf encoding is wire-compatible, but semantic capability negotiation is missing in both upgrade directions. Scalar, batch, legacy, versioned, missing, first-write, waiting, and non-waiting paths were checked.
  • Configuration: no new setting is introduced, but the existing infinite default table/partition TTLs make best-effort push and daemon repair insufficient as correctness fences.
  • Transactions/persistence/errors: lazy-commit table/partition timing and wait success/failure were traced. No new EditLog, persisted format, FE/BE data path, or partial-error publication issue was found.
  • Observability/performance: the legacy-response debug log is useful, and pending periods intentionally refetch; no distinct new logging, allocation, lock-hold, or RPC-amplification issue survived review.
  • Tests/results: the added tests cover the homogeneous new/new protocol well, but the legacy-response assertion encodes unsafe caching and there is no old-client capability/rollout-convergence coverage. No result-file change applies. Per the review contract, I did not build or run tests.

No additional user focus was supplied. The nine existing inline discussions were treated as duplicate fences; the two attached P1 comments are distinct compatibility defects.

}

private static boolean isVersionCacheable(Cloud.GetVersionResponse response, int index, int size) {
if (response.getHasPendingTxnsCount() == 0) {

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.

[P1] Treat omitted pending state as unknown

During a mixed-MS rollout, an older node omits this field even when VersionPB still has a pending lazy transaction. Both foreground paths are non-waiting, so returning true acknowledges and caches the pre-commit version; the default TTL is infinite and neither push nor the table-token daemon guarantees repair. For a pending first write, the old batch producer can also return protobuf default version 0, which this client leaves unchanged and ScanNode rejects. Keep zero-count non-waiting responses uncacheable and normalize the legacy 0 to the initial version (or gate both behaviors by capability); reverse the legacy-cache test and cover scalar/batch first writes.

Comment thread gensrc/proto/cloud.proto

// Pending state for partition versions, after any requested wait.
// One entry for scalar reads (including VERSION_NOT_FOUND), or per partition in batch order.
repeated bool has_pending_txns = 9;

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.

[P1] Negotiate pending-state support for old FE clients

An old FE ignores unknown response field 9 and its scalar/batch paths still validate the returned version. A new MS can therefore let its daemon cache a pending old or first-write version, then install the already-advanced table token; a missed push plus equal tokens and infinite TTL can preserve that cache. Add a request capability set by upgraded FEs and use an old-client-safe path such as waiting when it is absent. Also require an upgrade-completion invalidation/sweep/restart, because old endpoints can seed these caches earlier in a mixed-MS rollout; cover scalar, batch, and first-write old-client descriptors.

### What problem does this PR solve?

Problem Summary: Non-waiting version reads could cache an older partition version
while a lazy commit was still pending.

Return per-partition pending state alongside scalar and batch versions, including
versioned reads and missing versions. FE keeps pending responses invalid and
acknowledges only the epoch captured before the RPC when restoring cache validity.
Normalize missing batch versions to -1 instead of protobuf default 0.

When older MS responses omit pending state, preserve legacy caching and emit one
debug message per response. No additional full-table synchronization is introduced;
missed FE pushes and table cache policy remain outside this change.

### Release note

Avoid caching partition versions that still have pending lazy commits. Preserve
legacy caching with older meta services; pending-aware protection requires an
upgraded meta service.

### Check List (For Author)

- Test: 70 FE and 10 MS tests passed on the development machine after the older
  MS compatibility adjustment. After adding the debug logging guard, all 16
  partition cache tests passed again. Subsequent changes only simplify comments.
  clang-tidy previously passed for both changed C++ files. git diff --check passed;
  this squash preserves the exact source tree.
- Behavior changed: Yes; explicit pending state prevents cache reuse while absent
  state preserves legacy behavior.
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#59213

Problem Summary: With calc_delete_bitmap_get_versions_in_batch disabled,
getPartitionVersions reads the FE version cache and ignores
calc_delete_bitmap_get_versions_waiting_for_pending_txns. Stale versions
can cause delete bitmap calculation or updates to fail. Reuse the direct
single-partition MS read and pass the waiting configuration so non-batch
reads have the same freshness and waiting semantics as batch reads.

### Release note

Non-batch partition version reads for delete bitmap calculation now bypass
the FE cache and honor calc_delete_bitmap_get_versions_waiting_for_pending_txns.

### Check List (For Author)

- Test: Unit test added for valid-cache bypass, both waiting flag values,
  next-version calculation, and cache refresh. Build, tests, and Checkstyle
  not run at the user's request. Diff whitespace check passed.
- Behavior changed: Yes; non-batch reads always fetch from MS and honor the waiting configuration.
- Does this need documentation: No
…ctions

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Cloud partition version reads with no explicit waiting policy
always request non-waiting versions. Add cloud_get_version_wait_for_pending_txn,
defaulting to false, and forward it with statements. Use the current session's
value when a ConnectContext exists and the global session default otherwise.
Apply the policy to single and batch cache misses and cache-disabled reads.
Cache hits remain unchanged, and explicit waiting arguments retain precedence.
Incremental reads retain the upstream explicit waiting policy. Forced partition
synchronization explicitly waits for pending
transactions before broadcasting versions to other FEs, whose version messages
do not carry pending state. Reuse existing session serialization and MS request
paths without changing the protocol.

### Release note

Add cloud_get_version_wait_for_pending_txn to control whether Cloud partition
version RPCs wait for pending transactions. It defaults to false, uses the
global session default when no session exists, and does not bypass the version
cache or override explicitly specified waiting policies. Forced partition
version synchronization always waits for pending transactions.

### Check List (For Author)

- Test: Previously passed 99 related FE unit tests and Checkstyle on the
  development machine. After making forced synchronization explicitly wait,
  29 related FE unit tests and Checkstyle passed before a comment removal.
  No tests rerun after rebasing onto apache/master, as requested. Resolved
  incremental-read conflicts by retaining upstream wait=true and its test.
- Behavior changed: Yes; version RPCs without explicit waiting arguments honor
  the session setting or its global default. Forced synchronization explicitly
  waits and may take longer while commits are pending.
- Does this need documentation: Yes; added the session variable description in code.
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: When the Cloud version daemon detects a newer table version,
it queues partition refreshes while leaving existing partition caches valid.
Reads can continue using stale versions while refreshes wait or after refresh
failures, especially with a non-expiring cache TTL. Prepare changed tables for
synchronization by invalidating all partition caches before adding the table
to the refresh set. Follow the existing table-read-lock then version-write-lock
order and keep RPCs outside the locks. Reuse partition cache epochs so old
in-flight responses cannot acknowledge the invalidation. Keep the version
comparison and unchanged-table handling in the caller; equal or older table
versions retain existing behavior.

### Release note

Cloud background version synchronization now invalidates partition version
caches when it detects a newer table version, allowing reads to fetch versions
from MS while background refreshes are pending or have failed.

### Check List (For Author)

- Test: Added unit coverage for changed-table preparation, all-partition
  invalidation, failed refreshes retaining invalidation, and successful reads
  restoring cache validity. Build, tests and Checkstyle not run at the user's
  request. Static self-review, diff whitespace and added-line length checks passed.
- Behavior changed: Yes; partitions of changed tables stop serving cached
  versions before the daemon refreshes them.
- Does this need documentation: No
…default

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Cloud partition version caches default to an infinite TTL,
so missed version updates can leave cached versions stale until another
invalidation or refresh occurs. Use a ten-minute default TTL to make subsequent
reads refresh expired caches from MS. Keep the table version TTL unchanged,
so the existing daemon remains enabled by its default TTL condition. Existing
cache invalidation and pending-transaction handling retain their behavior.

### Release note

Change the default cloud_partition_version_cache_ttl_ms to 600000 milliseconds
(ten minutes). The default table version cache TTL remains unchanged.

### Check List (For Author)

- Test: Tests not run at the user's request. Reviewed the existing TTL tests,
  daemon condition, and single-line style; git diff --check passed. Build and
  Checkstyle were not run.
- Behavior changed: Yes; cloud partition version caches expire after ten
  minutes by default and refresh on subsequent reads.
- Does this need documentation: Yes; the documented default should be updated.
@mymeiyi
mymeiyi force-pushed the fix-daemon-get-version branch from 1c4677a to adc99c7 Compare September 18, 2026 08:12
@mymeiyi

mymeiyi commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions 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.

Static review of exact head adc99c7. The review converged after three rounds over all 12 changed files and the relevant FE/MS call chains. I found two P1 correctness/upgrade issues and three P2 lock/scaling issues that are distinct from the existing inline threads.

Checkpoint summary: the same-binary pending-state protocol is internally cardinality-consistent, but a pending response can still publish future metadata into shared FE state, and upgraded FE images retain the former infinite TTL. Scalar/batch, legacy/versioned storage, first-write, retry/error cleanup, clone routing, lazy-commit persistence, delete-bitmap, proc, daemon, planner, session/global forwarding, image replay, DDL/failure, and direct time/TSO consumers were traced. Existing mixed-binary, cross-partition publication, proc, daemon recovery, staged-memory, and SQL-cache findings were treated as hard duplicate fences. The new wait flag is forwarded consistently; no new FE-BE field is required. Existing observability is adequate, but the new daemon critical section and finite-default foreground refresh are unbounded in partition count.

Validation was static only, as required: I did not run builds, unit tests, regression tests, or runtime validation, and author/CI claims were not treated as independent proof.

// Invalidate before touching the timestamp, even when the cache was valid before this read.
invalidateCachedVisibleVersion();
}
setCachedVisibleVersion(version, updateTimeMs, tso);

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.

[P1] Do not publish metadata from a pending response. The MS returns the old visible version together with the pending transaction's update time and commit TSO. Although this branch invalidates the epoch, the unconditional setter still installs that mismatched tuple on a lagging FE, and direct accessors such as getVisibleVersionTime()/getTso() do not check the epoch; an equal-version push cannot repair it because the setter only accepts a strictly newer version. Ordinary SHOW PARTITIONS and MTMV grace checks can therefore observe metadata for a transaction that is not visible. Return the version to this caller without mutating shared partition state until hasPendingTxns is false, or make the tuple validity-checked atomically.

try {
table.versionWriteLock();
try {
for (Partition partition : table.getAllPartitions()) {

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.

[P2] Avoid the unbounded partition sweep under the table metadata lock. Each table-version advance now holds table.readLock (and the version write lock) while invalidating every partition, so ADD/DROP/ALTER PARTITION is blocked for O(partition count) work; if the later refresh fails, the cached table token is not advanced and the same locked sweep repeats next cycle. Snapshot the partition objects under the metadata lock and invalidate outside it, or use a table-level generation/bounded publication scheme.

public boolean cloudForceSyncTabletStats = false;
@VarAttrDef.VarAttr(name = CLOUD_PARTITION_VERSION_CACHE_TTL_MS)
public long cloudPartitionVersionCacheTtlMs = Long.MAX_VALUE;
public long cloudPartitionVersionCacheTtlMs = 10 * 60 * 1000L;

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.

[P2] Bound the foreground refresh before enabling this finite default. Once 600000 ms elapses, a query selecting P expired partitions sends all P ids in one get-version request and allocates parallel O(P) response lists; unlike the daemon/proc paths, this path ignores cloud_get_version_task_batch_size. Because partitions cached together also expire together, large scans now periodically put an unbounded metadata RPC on the SELECT path by default. Chunk this refresh while preserving a consistent snapshot, or otherwise stagger/renew it before changing the default.

if (!expiredPartitions.isEmpty()) { // Not all partition versions are from cache
versions = getSnapshotVisibleVersionFromMs(
expiredPartitions, /*waitForPendingTxns=*/false); // Get the rest versions from meta-service
versions = getSnapshotVisibleVersionFromMs(expiredPartitions); // Get the rest versions from meta-service

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.

[P2] Do not perform the session-enabled wait while Nereids holds the table metadata lock. Ordinary planning retains the table read lock through PruneEmptyPartition, which reaches this RPC on a cache miss; with cloud_get_version_wait_for_pending_txn enabled, the call can wait/retry for pending lazy commits for the full VersionHelper retry envelope. ADD/DROP/ALTER PARTITION then blocks behind a SELECT planner. Snapshot ids under the lock, wait outside it, and reacquire/revalidate, or move this wait to a post-lock snapshot phase.

@@ -3190,11 +3191,15 @@ public void setDetailShapePlanNodes(String detailShapePlanNodes) {
@VarAttrDef.VarAttr(name = CLOUD_FORCE_SYNC_TABLET_STATS, needForward = true)
public boolean cloudForceSyncTabletStats = false;
@VarAttrDef.VarAttr(name = CLOUD_PARTITION_VERSION_CACHE_TTL_MS)

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.

[P1] Migrate the persisted old default on upgrade. The FE image serializes this annotated long as part of defaultSessionVariable, and image load assigns the saved Long.MAX_VALUE over the initializer; forceUpdateVariables has no migration for this key. Existing clusters that never changed the setting therefore keep an infinite TTL, so the missed-update fallback enabled by this PR only applies to fresh clusters. Add a versioned migration with an explicit policy for real operator overrides and an old-image replay test, or document and scope the change as new-cluster-only.

bobhan1 added a commit to bobhan1/doris that referenced this pull request Oct 16, 2026
### What problem does this PR solve?

Related PR: apache#67813, apache#68104

Problem Summary: Completed retries can return partial partition versions, so
check the response partition count and clear versions and table stats on a
mismatch. Separately validate persisted tablet counts per partition before
the first commit, including each sub-transaction independently. Reject
incomplete inputs before visibility or lazy COMMITTED/pending writes.
Preserve already committed retries and omit unavailable old-BE counts.

### Release note

Invalidate incomplete commit version responses and reject incomplete tablet
metadata before committing when FE supplies expected counts.

### Check List (For Author)

- Test: Unit tests; MS ASAN/FDB 40 passed, 1 pre-existing disabled; FE 59 passed.
- Behavior changed: Yes, count mismatches distinguish response fallback from input rejection.
- Does this need documentation: No user-facing configuration changes.
bobhan1 added a commit to bobhan1/doris that referenced this pull request Oct 16, 2026
### What problem does this PR solve?

Related PR: apache#67813, apache#68104

Problem Summary: Completed retries can return partial partition versions, so
check the response partition count and clear versions and table stats on a
mismatch. Separately validate persisted tablet counts per partition before
the first commit, including each sub-transaction independently. Return INVALID_ARGUMENT for
incomplete inputs before visibility or lazy COMMITTED/pending writes.
Preserve already committed retries and omit unavailable old-BE counts.

### Release note

Invalidate incomplete commit version responses and reject incomplete tablet
metadata before committing when FE supplies expected counts.

### Check List (For Author)

- Test: MS ASAN/FDB focused 13 passed; FE 59 passed; protobuf wire checks passed.
  Prior full MS run: 40 passed, 1 pre-existing disabled.
- Behavior changed: Yes, count mismatches distinguish response fallback from input rejection.
- Does this need documentation: No user-facing configuration changes.
gavinchou
gavinchou previously approved these changes Oct 21, 2026
@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.48 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 344f3dad7e362553401395d4bd54fe145bfdf208, data reload: false

query1	0.00	0.00	0.00
query2	0.09	0.05	0.05
query3	0.26	0.10	0.08
query4	1.61	0.10	0.10
query5	0.24	0.25	0.25
query6	1.18	0.69	0.67
query7	0.04	0.01	0.01
query8	0.05	0.03	0.04
query9	0.40	0.35	0.36
query10	0.57	0.60	0.62
query11	0.20	0.15	0.14
query12	0.19	0.14	0.15
query13	0.50	0.51	0.49
query14	1.05	1.02	1.01
query15	0.63	0.61	0.62
query16	0.36	0.36	0.37
query17	1.17	1.13	1.16
query18	0.22	0.20	0.21
query19	2.08	1.96	1.98
query20	0.02	0.01	0.02
query21	15.43	0.21	0.14
query22	4.88	0.06	0.06
query23	16.39	0.33	0.12
query24	3.23	0.70	0.36
query25	0.10	0.06	0.05
query26	0.90	0.22	0.15
query27	0.06	0.04	0.05
query28	2.63	0.73	0.38
query29	12.53	4.22	3.31
query30	0.29	0.13	0.10
query31	2.77	0.57	0.32
query32	3.22	0.60	0.51
query33	3.15	3.15	3.20
query34	15.28	4.01	3.41
query35	3.36	3.37	3.37
query36	0.54	0.46	0.42
query37	0.13	0.10	0.10
query38	0.06	0.05	0.04
query39	0.04	0.03	0.03
query40	0.17	0.16	0.14
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.04	0.03
Total cold run time: 96.2 s
Total hot run time: 24.48 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 86.96% (40/46) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.10% (35819/46460)
Line Coverage 62.34% (404147/648244)
Region Coverage 58.74% (340902/580331)
Branch Coverage 59.78% (157975/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 52.17% (24/46) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 28429 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 344f3dad7e362553401395d4bd54fe145bfdf208, data reload: false

------ Round 1 ----------------------------------
============================================
q1	16661	5125	5072	5072
q2	2091	331	245	245
q3	9894	1362	810	810
q4	4611	458	338	338
q5	7399	786	538	538
q6	181	186	155	155
q7	740	814	603	603
q8	9368	1358	1098	1098
q9	5462	4196	4201	4196
q10	6830	1286	1009	1009
q11	428	247	227	227
q12	640	398	287	287
q13	17891	3626	3041	3041
q14	282	272	243	243
q15	q16	714	728	645	645
q17	1164	739	582	582
q18	6994	6172	6113	6113
q19	1106	970	602	602
q20	379	336	227	227
q21	5000	2142	2256	2142
q22	350	312	256	256
Total cold run time: 98185 ms
Total hot run time: 28429 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5655	5648	5642	5642
q2	701	591	530	530
q3	5184	5380	4903	4903
q4	2022	2170	1526	1526
q5	5289	5156	5133	5133
q6	326	251	156	156
q7	2365	2068	1841	1841
q8	3038	2716	2742	2716
q9	7991	7991	7841	7841
q10	3718	3671	3310	3310
q11	620	443	395	395
q12	861	758	531	531
q13	3557	3841	3238	3238
q14	310	323	280	280
q15	q16	713	739	671	671
q17	8354	7467	6904	6904
q18	13033	12183	12909	12183
q19	937	824	820	820
q20	2127	2146	1937	1937
q21	5852	4637	4709	4637
q22	496	492	423	423
Total cold run time: 73149 ms
Total hot run time: 65617 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150858 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 344f3dad7e362553401395d4bd54fe145bfdf208, data reload: false

query5	4318	585	444	444
query6	437	209	201	201
query7	4804	467	231	231
query8	335	168	170	168
query9	8788	3116	3098	3098
query10	470	311	254	254
query11	6084	3851	3580	3580
query12	145	91	88	88
query13	1261	441	318	318
query14	6096	3949	3644	3644
query14_1	3453	3446	3459	3446
query15	209	202	177	177
query16	932	425	358	358
query17	854	657	539	539
query18	2420	429	311	311
query19	199	167	136	136
query20	109	79	81	79
query21	207	122	102	102
query22	12939	13029	12787	12787
query23	13517	12921	12544	12544
query23_1	12508	12543	12594	12543
query24	7210	816	455	455
query24_1	459	457	460	457
query25	510	395	352	352
query26	1263	255	136	136
query27	2791	430	271	271
query28	4529	1926	1919	1919
query29	1536	584	460	460
query30	295	219	181	181
query31	1026	925	802	802
query32	139	84	91	84
query33	523	286	235	235
query34	884	843	494	494
query35	731	755	655	655
query36	821	803	731	731
query37	119	93	81	81
query38	1795	1735	1646	1646
query39	801	778	761	761
query39_1	737	722	750	722
query40	227	110	94	94
query41	66	61	62	61
query42	86	82	81	81
query43	348	363	307	307
query44	1306	668	690	668
query45	179	183	159	159
query46	827	957	563	563
query47	2784	2818	2909	2818
query48	290	299	214	214
query49	573	397	285	285
query50	682	263	213	213
query51	10551	10319	10467	10319
query52	79	82	76	76
query53	187	208	152	152
query54	255	248	214	214
query55	74	75	68	68
query56	253	231	229	229
query57	1650	1625	1581	1581
query58	304	270	266	266
query59	2132	2115	1920	1920
query60	307	253	240	240
query61	170	170	186	170
query62	389	338	288	288
query63	193	181	169	169
query64	2859	1067	886	886
query65	3297	3280	3251	3251
query66	1788	469	320	320
query67	20390	20164	19940	19940
query68	2935	1013	596	596
query69	390	304	244	244
query70	845	744	773	744
query71	290	231	204	204
query72	2784	2580	2288	2288
query73	523	517	295	295
query74	4629	4539	4378	4378
query75	2317	2261	1940	1940
query76	2181	1001	605	605
query77	349	378	278	278
query78	9863	9727	9153	9153
query79	1012	844	505	505
query80	853	421	341	341
query81	582	309	269	269
query82	549	130	105	105
query83	307	196	177	177
query84	320	126	97	97
query85	922	431	379	379
query86	382	239	228	228
query87	2003	1965	1801	1801
query88	3619	2670	2658	2658
query89	335	280	239	239
query90	1798	167	166	166
query91	168	148	133	133
query92	100	85	90	85
query93	989	989	564	564
query94	534	296	271	271
query95	584	400	305	305
query96	661	475	242	242
query97	2444	2444	2351	2351
query98	161	154	149	149
query99	776	760	642	642
Total cold run time: 234433 ms
Total hot run time: 150858 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 25.26 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 344f3dad7e362553401395d4bd54fe145bfdf208, data reload: false

query1	0.01	0.01	0.00
query2	0.14	0.10	0.07
query3	0.35	0.13	0.13
query4	1.61	0.12	0.14
query5	0.27	0.26	0.24
query6	1.16	0.66	0.65
query7	0.04	0.01	0.01
query8	0.09	0.07	0.07
query9	0.44	0.35	0.33
query10	0.57	0.59	0.59
query11	0.30	0.18	0.17
query12	0.31	0.20	0.18
query13	0.52	0.52	0.53
query14	0.93	0.94	0.93
query15	0.65	0.58	0.59
query16	0.35	0.36	0.35
query17	1.05	1.09	1.02
query18	0.29	0.28	0.27
query19	1.97	1.88	1.88
query20	0.02	0.02	0.01
query21	15.41	0.35	0.30
query22	4.94	0.13	0.13
query23	15.87	0.50	0.29
query24	2.04	0.57	0.41
query25	0.15	0.10	0.10
query26	0.76	0.27	0.20
query27	0.10	0.10	0.09
query28	3.43	0.87	0.39
query29	12.59	4.32	3.40
query30	0.35	0.17	0.15
query31	2.75	0.60	0.33
query32	3.23	0.59	0.49
query33	2.95	3.05	3.04
query34	15.93	4.07	3.45
query35	3.40	3.39	3.37
query36	0.60	0.49	0.48
query37	0.12	0.09	0.09
query38	0.07	0.06	0.07
query39	0.06	0.06	0.06
query40	0.18	0.16	0.17
query41	0.11	0.06	0.05
query42	0.07	0.06	0.05
query43	0.07	0.05	0.05
Total cold run time: 96.25 s
Total hot run time: 25.26 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.10% (35820/46460)
Line Coverage 62.35% (404152/648244)
Region Coverage 58.73% (340819/580331)
Branch Coverage 59.78% (157972/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.11% (35823/46460)
Line Coverage 62.35% (404179/648244)
Region Coverage 58.74% (340864/580331)
Branch Coverage 59.79% (157993/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 52.17% (24/46) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.08% (35812/46460)
Line Coverage 62.32% (404011/648244)
Region Coverage 58.73% (340839/580331)
Branch Coverage 59.77% (157935/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 52.17% (24/46) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.23% (35879/46460)
Line Coverage 62.47% (404940/648244)
Region Coverage 58.90% (341786/580331)
Branch Coverage 59.91% (158317/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 52.17% (24/46) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.23% (35879/46460)
Line Coverage 62.47% (404940/648244)
Region Coverage 58.90% (341786/580331)
Branch Coverage 59.91% (158317/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 80.43% (37/46) 🎉
Increment coverage report
Complete coverage report

@gavinchou

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions 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.

Reviewed the complete supplied 12-file diff at head 344f3dad7e362553401395d4bd54fe145bfdf208. Static review converged in 1 round: both complete-review agents and the separate cache-risk reviewer returned NO_NEW_VALUABLE_FINDINGS; all candidates, existing threads and R1-R3 risks have evidence-based dispositions. No new inline findings are needed. Changes are still requested for five independently revalidated existing P1s:

  • 4032914010: forced SHOW waits for lazy transactions while holding table/MTMV metadata read locks. The configured retry envelope applies; the current default is 200 attempts with a 30-second attempt timeout, rather than the historical comment's three-attempt example.
  • 4035088962: absent old-MS pending state still validates the cache; legacy first-write batch version 0 is not normalized and reaches the scan's nonpositive-version error. The fresh default is now finite, but persisted/explicit infinite TTL cases remain.
  • 4035088973: old FE clients ignore field 9 and can cache pending old/initial partition versions together with an advanced table token; request capability negotiation and upgrade cache recovery remain absent.
  • 4045487571: pending responses invalidate the epoch but still install a mismatched visible-version/time/TSO tuple on a lagging FE. Direct metadata consumers bypass epoch checks; equal-version pushes cannot repair it.
  • 4045487595: image replay restores the persisted infinite TTL over the new initializer; no versioned migration covers the old default.

The disabled-syncer TTL-bypass thread 4032914017 and dirty-marker/re-enable thread 4032914020 no longer describe this head: the bypass is absent, the table TTL remains infinite, and daemon selection polls managed tables by interval. Historical staged-map/reject-on-token-race branches are also absent. Existing foreground/proc snapshot, wait-under-lock, full invalidation sweep and foreground batching concerns were checked and retained as duplicate fences; no copies are posted.

Individual critical-checkpoint conclusions:

  1. Goal and proof: upgraded MS/FE scalar and batch paths propagate pending state and leave pending responses uncacheable; unit cases cover policy and first-write normalization. The five known P1s prevent accepting the complete upgrade/correctness goal.
  2. Scope and reuse: changes stay within version reads/cache policy, reuse existing waiting/RPC machinery, and centralize implicit wait selection and publication.
  3. Concurrency and locking: query, daemon, commit, push and DDL interactions were traced. Epoch acknowledgement preserves later invalidations and monotonic setters prevent lower-version replacement. No distinct new lock inversion was found; heavy locked waits/sweeps and snapshot gaps remain known concerns.
  4. Lifecycle: cache epochs and flags are transient; existing daemon pools and deduplicated lazy tasks retain their cleanup owners. No new resource lifetime or static initialization issue was found.
  5. Configuration: the new session boolean supports standard SET/global fallback and forwarding; uncached reads observe it immediately. Explicit proc/daemon/MoW policies remain authoritative. Persisted TTL migration remains the known P1.
  6. Compatibility: new-to-new behavior is consistent; old-MS/new-FE and new-MS/old-FE behavior remains blocked as above. No persistent schema or function-symbol removal was introduced.
  7. Shared definitions: complete GetVersionResponse definitions were compared on HEAD and origin/branch-3.1, branch-4.0, branch-4.1 and branch-4.2. Field 9 is unused on every release ref; no reused/colliding ID or new required field was found.
  8. Parallel paths: scalar/batch, legacy/versioned layouts, missing/first-write values, waiting/nonwaiting, clone-source instances, foreground/forced/daemon/proc and MoW paths were covered. The cloud/shared-nothing split remains intact.
  9. Conditions: has_version normalization handles the real pending-first-write producer, pending flags are aligned with versions, and malformed flag cardinality leaves caches invalid. Omitted flags are the already-reported unsafe exception.
  10. Test coverage: all five changed test files were inspected. They cover both layouts, scalar/batch pending and first-write responses, invalidation, explicit/session/default waits, and scalar MoW cache bypass. Mixed-version descriptors, persisted-image migration, real lock contention and large-table behavior lack corresponding added end-to-end proof.
  11. Expected results: inspected mock/version expectations match the intended new-MS behavior; the legacy-cache test preserves the known compatibility issue. No regression output files changed.
  12. Observability: existing RPC latency/profile, retry, lazy-wait and daemon failure logs remain available. No distinct new observability defect was found.
  13. Persistence and failover: no new durable transaction state or EditLog record is required; MS pending state remains durable and lazy work can be reconstructed. Default-session image replay is the known migration gap.
  14. Writes and atomicity: scalar MoW reads now match batch's forced MS read and configured waiting policy after bitmap-lock acquisition, then use visible version +1; callers retain failure cleanup. No distinct new delete-bitmap/sentinel, crash-leak or self-wait defect was found. Known query/proc publication gaps remain.
  15. Variable propagation: the new boolean uses FE session forwarding and the existing FE-to-MS wait field; no new BE query-option plumbing is required.
  16. Performance and memory: pending flags add linear work to existing partition loops. The new full-table invalidation under locks and periodic unbounded foreground refresh remain existing P2s; scalar MoW deliberately trades cache hits for current MS versions. No distinct new growth mechanism was verified.
  17. Final sweep: all 12 paths, 16 existing comments, five carried blockers and R1-R3 dispositions were rechecked; no unresolved static candidate or uncovered assigned path remains.

No additional user focus was supplied. Validation was static only, as required: no builds, tests, source changes or runtime-performance claims. Convergence is complete; the review verdict remains blocking because the five existing P1s still apply.

Review converged after 1 round(s).

Existing P0/P1 findings confirmed for this head: #68104 (comment), #68104 (comment), #68104 (comment), #68104 (comment), #68104 (comment)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.23% (35879/46460)
Line Coverage 62.47% (404940/648244)
Region Coverage 58.90% (341786/580331)
Branch Coverage 59.91% (158317/264247)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 5.49% (24/437) 🎉
Increment coverage report
Complete coverage report

@gavinchou

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions 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.

Request changes at head 344f3dad7e362553401395d4bd54fe145bfdf208. No additional distinct inline finding was verified. Five previously reported P1 findings still apply and are retained as blocking comments rather than reposted:

  • 4045487595 — persisted old TTL: image replay restores the annotated Long.MAX_VALUE over the new ten-minute initializer; no versioned migration changes that value. Existing untouched clusters retain the infinite partition TTL.
  • 4045487571 — pending metadata tuple: pending answers invalidate the epoch but still install an old visible version with the pending transaction's timestamp/TSO on a lagging FE. Direct metadata accessors ignore validity, and equal-version updates cannot repair the tuple.
  • 4035088973 — old FE compatibility: old FEs ignore the new response field and can cache pending versions alongside the advanced table token. There is no capability negotiation or upgrade-completion cache recovery.
  • 4035088962 — old MS compatibility: omitted pending state is still accepted as cacheable. An old MS also returns zero for a pending first-write batch entry, which this FE does not normalize and ScanNode rejects. The finite initializer does not fix existing infinite-TTL sessions or the zero-version error.
  • 4032914010 — waiting under metadata locks: forced SHOW/proc refresh retains table and related MTMV metadata read locks across sequential waiting RPCs. The configurable VersionHelper retry envelope can block metadata writers; its current defaults are 200 attempts and 30 seconds per attempt, broader than the earlier comment's example.

The inspected interaction is lazy commit -> pending VersionPB plus advanced table token -> scalar/batch get-version -> FE epoch/tuple publication -> planner/ScanNode snapshot -> BE visible-version bound. Concurrent daemon workers and FE commit/push workers update the same caches. Forced proc refresh holds metadata read locks during its RPCs; daemon invalidation takes metadata read lock then version write lock; batch and push publication use sorted table version locks.

Critical checkpoint conclusions:

  1. Goal and correctness: explicit pending answers on upgraded MS/FE pairs remain epoch-invalid, including pending first writes. Full correctness is blocked by the tuple and rolling-upgrade findings above. Added unit tests inspect the intended local behavior, without proving upgrade safety.
  2. Scope and reuse: the twelve changed paths are focused on pending-state propagation, shared cache policy, wait selection, scalar MoW cache bypass, and daemon invalidation. Common cacheability and implicit-wait helpers avoid scalar/batch policy duplication.
  3. Concurrency and locks: captured epoch acknowledgment preserves invalidations after request start. Existing metadata-lock waits, full-table locked sweeps, and cached/fetched snapshot races remain. No additional lock-order deadlock was verified.
  4. Lifecycle and initialization: no new worker lifecycle, static initialization dependency, or ownership cycle was introduced. Response metadata and session variables follow existing ownership; cache epochs remain transient.
  5. Configuration: the new wait boolean defaults false, supports SET/forwarding, and is read at cache misses. Explicit daemon, proc, incremental-read and bitmap policies retain precedence. The partition TTL changes to ten minutes for fresh defaults; persisted old values are not migrated. Table TTL remains infinite by default.
  6. Compatibility: no durable storage representation changes. Semantic mixed-MS/FE compatibility remains blocked by the two existing upgrade findings.
  7. Protobuf: complete GetVersionResponse definitions on HEAD and origin/branch-3.1, branch-4.0, branch-4.1 and branch-4.2 were compared. Existing ids retain meaning; field 9 is unused on those releases, repeated and optional on the wire. No field-id collision, reuse, or new required field was found.
  8. Parallel paths: scalar/batch, legacy/versioned MS storage, missing/nonpending/pending-first-write responses, foreground/daemon/proc/MoW consumers, and shared-nothing fallbacks were checked. Forced scalar bitmap reads now follow the existing batch policy.
  9. Special conditions and errors: explicit pending state overrides waiting policy for cacheability; absent state still takes the unsafe legacy branch. Backend read/parse/wait failures propagate status and clear added flags; scalar/batch FE failures retain invalid epochs. No additional distinct error path was verified.
  10. Test coverage: C++ tests cover layouts, ordering, waiting, missing and first-write responses. Java tests cover epochs, scalar/batch cacheability, explicit/session/global waits, forwarding, scalar bitmap cache bypass, and daemon preparation. Missing cases include old images/descriptors, lagging pending metadata tuples, real proc/planner lock scopes, full daemon cycles and failed later batches. The legacy-MS test currently endorses the unsafe caching policy.
  11. Test results: no regression output files changed. New expected values match the inspected implementation; that does not establish the correctness of the legacy policy. No builds or tests were run, as required by this static-only review contract.
  12. Observability: existing get-version RPC metrics, query profile counters, daemon logs and failure warnings remain. No additional distinct observability defect was verified.
  13. Persistence and failover: no new EditLog or KV write protocol was introduced. Persisted TTL replay and upgrade-seeded volatile caches are the lifecycle concerns retained above.
  14. Writes and atomicity: rowset/delete-bitmap publication protocols are unchanged. Scalar bitmap version reads run after the existing bitmap update lock and use existing failure cleanup in ordinary and subtransaction callers. Known shared-cache publication concerns remain duplicate review context.
  15. FE/BE variable passing: no new FE/BE plan or thrift variable is added. The new boolean is FE-side and forwarded between FEs; every MS partition response producer is updated.
  16. Performance: the producer adds one boolean per partition without another metadata read. Existing P2 comments cover unbounded foreground expiry refresh, O(partition count) invalidation under metadata locks, and planner waiting RPCs. These were revalidated and not reposted.
  17. Additional concerns: existing partial-proc-batch publication, table-token-before-wait, and mixed cached/fetched foreground snapshot threads remain duplicate fences. The older disabled-syncer TTL-bypass and dirty/staged-cache reports describe mechanisms absent from this head; P1 ids 4032914017 and 4032914020 are not retained as confirmed blockers.

No additional user focus was supplied. All changed paths and risk focuses received main-agent and independent review. The remaining limitations are static validation and the test gaps stated above; no unresolved distinct candidate or unreviewed changed scope remains. Convergence describes completion of the review search, while the five confirmed P1 findings still require changes.

Review converged after 2 round(s).

Existing P0/P1 findings confirmed for this head: #68104 (comment), #68104 (comment), #68104 (comment), #68104 (comment), #68104 (comment)

@hello-stephen
hello-stephen merged commit 883bf91 into apache:master Oct 23, 2026
38 of 39 checks passed
@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Oct 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

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

Labels

approved Indicates a PR has been approved by one committer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants