Conversation
…efault Brings the server-side immutable-index correctness hardening to the Consistent Failover feature branch and enables it by default (DEFAULT_SERVER_SIDE_IMMUTABLE_INDEXES_ENABLED=true). Immutable, global, non-transactional secondary indexes are maintained server-side by IndexRegionObserver rather than by the client, while immutable tables that declare a ROW_TIMESTAMP column stay client-maintained regardless of the flag. Hardening (identical to the off-by-default change on master): - Centralize the maintenance-side decision in IndexUtil.isServerSideImmutableIndexMaintenanceEnabled(...) and route every data-table gate through it (getClientMaintainedIndexes, the INDEX_UUID gate, MutationState.filterIndexCheckerMutations, DeleteCompiler.isMaintainedOnClient, IndexMetaDataCacheClient, and UpsertCompiler) so client and server never disagree. - Force a current-row read-back for immutable batches carrying a covered or uncovered global index when an enabled mutation omits one of that index's on-disk columns, so partial upserts no longer drop a covered column or write a spurious null-keyed uncovered entry. - Broaden the immutable server-serialize filter to IndexUtil.isGlobalIndex so uncovered global immutable indexes with a matching storage scheme are maintained. Tests: partial-upsert/delete coverage in BaseImmutableIndexIT runs under both ServerSideImmutableIndexIT and ClientSideImmutableIndexIT; the ITs that account for client-side index mutations pin the flag off; the IndexTool and GlobalIndexCheckerIT assertions read the effective flag so they stay correct under either default. Generated-by: Claude Code (Opus 4.8) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lokiore
marked this pull request as ready for review
September 15, 2026 19:18
tkhurana
approved these changes
Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
This targets the Consistent Failover feature branch (
PHOENIX-7562-feature-new). It brings the server-side immutable-index correctness hardening from #2611 to this branch and enables it by default (DEFAULT_SERVER_SIDE_IMMUTABLE_INDEXES_ENABLEDflipsfalse→true).With the flag on, immutable, global, non-transactional secondary indexes are maintained server-side by
IndexRegionObserver(PHOENIX-7426) rather than by the client: the client ships the serializedIndexMaintainerand the region server builds the index updates exactly once. Immutable data tables that declare aROW_TIMESTAMPcolumn continue to be maintained client-side regardless of the flag.This is the companion of #2611. #2611 lands the same hardening on
masteroff by default (a pure correctness fix); this PR is where the default is turned on, on the branch that adopts server-side immutable-index maintenance.Hardening (identical to #2611):
IndexUtil.isServerSideImmutableIndexMaintenanceEnabled(...)and every data-table gate routes through it —IndexUtil.getClientMaintainedIndexes,IndexMaintainer.maintainedLocalOrGlobalIndexesWithoutMatchingStorageScheme(theINDEX_UUIDgate),MutationState.filterIndexCheckerMutations,DeleteCompiler.isMaintainedOnClient(signature extended to take the data table soROW_TIMESTAMPresolves against the data table),IndexMetaDataCacheClient.setMetaDataOnMutations, andUpsertCompiler— so client and server never disagree on which side maintains a table.IndexRegionObserverskips the current-row read-back for immutable batches; a partial upsert omitting an indexed/covered/index-WHERE column would then build the index entry from the partial mutation alone (dropping a covered column, or writing a spurious null-keyed uncovered entry). The read-back gate now forces a read-back for immutable batches carrying a covered or uncovered global index when an enabled mutation omits one of that index's on-disk columns; full-row upserts and single-cell tables keep the no-read-back fast path.IndexUtil.isGlobalIndex(coveringGLOBALandUNCOVERED_GLOBAL), so an uncovered global immutable index with a matching storage scheme is maintained rather than dropped by both client and server.Why are the changes needed?
Enabling server-side maintenance by default on this branch removes per-batch client index-mutation generation for immutable tables and lets
IndexRegionObserver(the default index path) build the updates, reducing client-side work and mutation payload. TheROW_TIMESTAMPcarve-out is required for correctness: server-side maintenance re-stamps every data cell — including theROW_TIMESTAMPcolumn — with the server batch timestamp, soROW_TIMESTAMPrange predicates (which push an HBase scanTimeRange) would silently drop rows on range reads. This mirrorsCANNOT_CREATE_INDEX_ON_MUTABLE_TABLE_WITH_ROWTIMESTAMPfor the mutable variant.Does this PR introduce any user-facing change?
Yes, on this feature branch: immutable, global, non-transactional secondary indexes are maintained server-side by default (previously client-side unless the flag was set). Immutable tables with a
ROW_TIMESTAMPcolumn are unaffected (client-maintained). Upgrade region servers before clients; server-side maintenance rides the default-enabledIndexRegionObserverpath. The previous behavior can be restored withphoenix.server.side.immutable.indexes.enabled=false.How was this patch tested?
Same coverage as #2611. Partial-upsert/delete coverage in
BaseImmutableIndexITruns under bothServerSideImmutableIndexIT(flag on) andClientSideImmutableIndexIT(flag off), parameterized over storage scheme.GlobalIndexCheckerIT#testPartialRowUpdateForImmutable{,Uncovered}lock the read-back fix; the uncovered COUNT invariant is asserted only when server-side maintenance is enabled (read from the effective flag).UncoveredGlobalImmutableNonTxIndexIT/...2ITexercise the broadened serialize filter.RowTimestampITlocks theROW_TIMESTAMPcarve-out. The metrics/RPC ITs pin the flag off for assertions that account for client-side index mutations;IndexToolITreads the effective flag. Heavy immutable/index ITs are exercised in CI.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8)