Repository navigation
[fix](cloud) Avoid caching partition versions with pending transactions - #68104
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
/review |
There was a problem hiding this comment.
🟡 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.
There was a problem hiding this comment.
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_txnis 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.
dd23972 to
a65e8a1
Compare
f78d005 to
7bae554
Compare
|
/review |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
[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.
|
|
||
| // 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; |
There was a problem hiding this comment.
[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.
1c4677a to
adc99c7
Compare
|
/review |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
[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()) { |
There was a problem hiding this comment.
[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; |
There was a problem hiding this comment.
[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 |
There was a problem hiding this comment.
[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) | |||
There was a problem hiding this comment.
[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.
### 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.
### 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.
ClickBench: Total hot run time: 24.48 s |
FE UT Coverage ReportIncrement line coverage |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
TPC-H: Total hot run time: 28429 ms |
TPC-DS: Total hot run time: 150858 ms |
ClickBench: Total hot run time: 25.26 s |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
|
/review |
There was a problem hiding this comment.
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:
- 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.
- Scope and reuse: changes stay within version reads/cache policy, reuse existing waiting/RPC machinery, and centralize implicit wait selection and publication.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- Observability: existing RPC latency/profile, retry, lazy-wait and daemon failure logs remain available. No distinct new observability defect was found.
- 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.
- 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.
- 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.
- 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.
- 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)
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
FE Regression Coverage ReportIncrement line coverage |
|
/review |
There was a problem hiding this comment.
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_VALUEover 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:
- 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.
- 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.
- 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.
- 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.
- 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.
- Compatibility: no durable storage representation changes. Semantic mixed-MS/FE compatibility remains blocked by the two existing upgrade findings.
- 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.
- 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.
- 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.
- 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.
- 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.
- Observability: existing get-version RPC metrics, query profile counters, daemon logs and failure warnings remain. No additional distinct observability defect was verified.
- 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.
- 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.
- 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.
- 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.
- 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)
|
PR approved by at least one committer and no changes requested. |
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.