-
Notifications
You must be signed in to change notification settings - Fork 1k
PHOENIX-7961 Secondary index diverges from data table after TTL expiry on partial-touch upserts #2574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sanjeet006py
wants to merge
16
commits into
apache:master
Choose a base branch
from
sanjeet006py:fix-index-data-table-sync
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
PHOENIX-7961 Secondary index diverges from data table after TTL expiry on partial-touch upserts #2574
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
6f62f6e
TTL-aware internal current-row read and index-referenced column re-sy…
c46a154
Thread empty-column CF/CQ unconditionally and mask no-index current-r…
4d5dfb5
Drop IndexMaintainer as emptyCF/CQ source for internal current-row scan
1534ddd
Extend index-referenced column re-sync to atomic / ON DUPLICATE KEY p…
83cdb45
Consolidate atomic / ON DUPLICATE KEY re-sync into rewriteIndexRefere…
2e9ccfd
Fix rewriteIndexReferencedColumns doc and clean up post-consolidation…
5f13615
Add IndexDataTableTTLBoundaryConsistencyIT regression test for TTL-bo…
339fe94
Anchor internal current-row masked scan at batchTimestamp; drop rewri…
1b328d1
Add concurrent-major-compaction regression test; rename and prune TTL…
8b2ac94
Trim explanatory comments and correct TTL-sync IT phase-2 timeline
6a7db2e
Thread view literal TTL on dedicated _LITERAL_TTL mutation attribute
06c6cf6
Merge remote-tracking branch 'apache/master' into fix-index-data-tabl…
e88e927
Include batchTimestamp boundary cell in index current-row read
01ff414
Address Tanuj's comments
f1f503d
Address Tanuj's comments
0576605
Address Tanuj's comments
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
123 changes: 123 additions & 0 deletions
123
phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/ServerScanUtil.java
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.phoenix.coprocessor; | ||
|
|
||
| import java.io.IOException; | ||
| import org.apache.hadoop.hbase.client.Scan; | ||
| import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; | ||
| import org.apache.hadoop.hbase.regionserver.Region; | ||
| import org.apache.hadoop.hbase.regionserver.RegionScanner; | ||
| import org.apache.phoenix.coprocessorclient.BaseScannerRegionObserverConstants; | ||
| import org.apache.phoenix.schema.types.PBoolean; | ||
|
|
||
| /** | ||
| * Utilities for internal server-side region scans that must honor Phoenix TTL exactly like a client | ||
| * read. The client normally sets the empty-column and TTL scan attributes | ||
| * ({@link org.apache.phoenix.util.ScanUtil#setScanAttributesForPhoenixTTL}) and the coprocessor | ||
| * hook {@code BaseScannerRegionObserver.postScannerOpen} wraps the scan in a | ||
| * {@link TTLRegionScanner}. Internal scans opened directly via {@code region.getScanner(scan)} | ||
| * bypass that hook, so they set no attributes and are never TTL-masked. These helpers reproduce the | ||
| * TTL-masking step for server-side callers (e.g. {@code IndexRegionObserver} current-row reads) so | ||
| * an internal scan masks identically to a client scan. | ||
| * <p> | ||
| * Note: server paging is intentionally <b>not</b> reproduced here. Paging exists to bound the work | ||
| * a single RPC handler thread does before yielding; these internal scans are region-local (opened | ||
| * directly on the {@link Region}, not through the RPC scan path), so they consume no handler thread | ||
| * and there is nothing for paging to protect. | ||
| */ | ||
| public class ServerScanUtil { | ||
|
|
||
| private ServerScanUtil() { | ||
| } | ||
|
|
||
| /** | ||
| * Sets the Phoenix TTL scan attributes on an internal data-table scan so it masks exactly like a | ||
| * client read. | ||
| * <p> | ||
| * TTL masking attributes ({@link TTLRegionScanner} reads these): | ||
| * <ul> | ||
| * <li>the empty-column CF/CQ, supplied by the caller from the bytes the client threaded on the | ||
| * mutation ({@link org.apache.phoenix.util.ScanUtil#annotateMutationWithLiteralTTL}) — the single | ||
| * source for every path, secondary-index and no-index (atomic / ON DUPLICATE KEY / | ||
| * {@code returnResult} / row-delete) alike;</li> | ||
| * <li>{@code IS_STRICT_TTL=false} when {@code isStrictTTL == false}, so a non-strict table is not | ||
| * masked (absence of the attribute defaults to strict, matching the read path);</li> | ||
| * <li>the view's literal TTL as the standard {@code _TTL} scan attribute when | ||
| * {@code literalTTLForScan != null}. A base table's literal TTL is left unset so | ||
| * {@link TTLRegionScanner}'s CF-descriptor fallback derives it.</li> | ||
| * </ul> | ||
| */ | ||
| public static void setInternalScanAttributes(Scan scan, byte[] emptyCF, byte[] emptyCQ, | ||
| byte[] literalTTLForScan, boolean isStrictTTL) { | ||
| scan.setAttribute(BaseScannerRegionObserverConstants.EMPTY_COLUMN_FAMILY_NAME, emptyCF); | ||
| scan.setAttribute(BaseScannerRegionObserverConstants.EMPTY_COLUMN_QUALIFIER_NAME, emptyCQ); | ||
| if (!isStrictTTL) { | ||
| // Absence of the attribute defaults to strict-true (ScanUtil.isStrictTTL), so only set it | ||
| // when the table/view is non-strict, mirroring setScanAttributesForPhoenixTTL. | ||
| scan.setAttribute(BaseScannerRegionObserverConstants.IS_STRICT_TTL, | ||
| PBoolean.INSTANCE.toBytes(false)); | ||
| } | ||
| if (literalTTLForScan != null) { | ||
| // Only views carry a literal TTL here; a base table relies on the CF-descriptor fallback. | ||
| scan.setAttribute(BaseScannerRegionObserverConstants.TTL, literalTTLForScan); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Opens a region scanner wrapped in a {@link TTLRegionScanner} exactly as | ||
| * {@code BaseScannerRegionObserver.postScannerOpen} wraps a client scan, so TTL masking is | ||
| * applied. This is always safe: {@link TTLRegionScanner#isMaskingEnabled} no-ops the masking when | ||
| * Phoenix compaction is disabled, the empty-column attributes are absent, the TTL is FOREVER, or | ||
| * the scan is non-strict — so wrapping a non-TTL scan changes no behavior. | ||
| * <p> | ||
| * The raw HBase {@link RegionScanner} is wrapped in a {@link NonPagingRegionScanner} rather than | ||
| * passed to {@link TTLRegionScanner} directly: {@link TTLRegionScanner} requires its delegate to | ||
| * be a {@link DelegateRegionScanner} — its gap-analysis and re-scan paths cast the delegate and | ||
| * call {@code getNewRegionScanner} — so a raw HBase scanner would fail those casts. On the client | ||
| * read path {@code PagingRegionScanner} fills this role; here we use a non-paging equivalent | ||
| * because the scan is region-local (opened directly on the {@link Region}, off the RPC path), so | ||
| * it holds no handler thread and has nothing for paging to protect. | ||
| */ | ||
| public static RegionScanner openRegionScanner(RegionCoprocessorEnvironment env, Region region, | ||
| Scan scan) throws IOException { | ||
| return new TTLRegionScanner(env, scan, | ||
| new NonPagingRegionScanner(region, region.getScanner(scan))); | ||
| } | ||
|
|
||
| /** | ||
| * A minimal {@link DelegateRegionScanner} over a raw HBase {@link RegionScanner} that can re-open | ||
| * a fresh scanner from the {@link Region} via {@link #getNewRegionScanner(Scan)} but adds no | ||
| * paging. {@link TTLRegionScanner} needs a {@link DelegateRegionScanner} delegate (it casts and | ||
| * calls {@code getNewRegionScanner} during gap analysis and re-scans); this fills that role for | ||
| * internal region-local scans without reproducing the paging machinery that | ||
| * {@code PagingRegionScanner} adds for the RPC read path. | ||
| */ | ||
| private static final class NonPagingRegionScanner extends DelegateRegionScanner { | ||
| private final Region region; | ||
|
|
||
| private NonPagingRegionScanner(Region region, RegionScanner scanner) { | ||
| super(scanner); | ||
| this.region = region; | ||
| } | ||
|
|
||
| @Override | ||
| public RegionScanner getNewRegionScanner(Scan scan) throws IOException { | ||
| return new NonPagingRegionScanner(region, region.getScanner(scan)); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you verify that conditional ttl doesn't have this problem ? I didn't see any test cases with conditional ttl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I observed that conditional TTL case was already covered by
IndexRegionObserver#updateMutationsForConditionalTTL. There we check if a row is already expired and add delete markers.I didn't explicitly verify via IT. Do you think I should add one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its ok. There are already existing tests.