This is an automated email from the ASF dual-hosted git repository. gokcen pushed a commit to branch 4.x in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.x by this push: new 88b4eb8 PHOENIX-6462 Index build that failed should be reporting it into the PHOENIX_INDEX_TOOL_RESULT table 88b4eb8 is described below commit 88b4eb81e0cb10c469f6d08372a187fdf0ff4fb1 Author: Gokcen Iskender <gisken...@salesforce.com> AuthorDate: Mon May 10 11:21:26 2021 -0700 PHOENIX-6462 Index build that failed should be reporting it into the PHOENIX_INDEX_TOOL_RESULT table Signed-off-by: Gokcen Iskender <gisken...@salesforce.com> --- .../end2end/IndexToolForNonTxGlobalIndexIT.java | 43 ++++++++++++++++++++++ .../coprocessor/GlobalIndexRegionScanner.java | 10 ++++- .../coprocessor/IndexRebuildRegionScanner.java | 7 +++- .../coprocessor/IndexToolVerificationResult.java | 15 ++++++++ .../index/IndexVerificationResultRepository.java | 8 +++- 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolForNonTxGlobalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolForNonTxGlobalIndexIT.java index aa21352..a35bf9d 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolForNonTxGlobalIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolForNonTxGlobalIndexIT.java @@ -591,6 +591,49 @@ public class IndexToolForNonTxGlobalIndexIT extends BaseUniqueNamesOwnClusterIT } @Test + public void testIndexToolFailedMapperNotRecordToResultTable() throws Exception { + if (mutable != true || singleCell != true ) { + return; + } + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + try (Connection conn = DriverManager.getConnection(getUrl(), props)) { + String schemaName = generateUniqueName(); + String dataTableName = generateUniqueName(); + String dataTableFullName = SchemaUtil.getTableName(schemaName, dataTableName); + String indexTableName = generateUniqueName(); + String indexTableFullName = SchemaUtil.getTableName(schemaName, indexTableName); + conn.createStatement().execute("CREATE TABLE " + dataTableFullName + + " (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR, ZIP INTEGER) " + + tableDDLOptions); + conn.commit(); + // Insert a row + conn.createStatement().execute("upsert into " + dataTableFullName + " values (1, 'Phoenix', 12345)"); + conn.commit(); + // Configure IndexRegionObserver to fail the first write phase. This should not + // lead to any change on index and thus the index verify during index rebuild should fail + IndexRebuildRegionScanner.setThrowExceptionForRebuild(true); + conn.createStatement().execute(String.format( + "CREATE INDEX %s ON %s (NAME) INCLUDE (ZIP) ASYNC " + this.indexDDLOptions, indexTableName, dataTableFullName)); + // Run the index MR job and verify that the index table rebuild fails + IndexTool it = IndexToolIT.runIndexTool(directApi, useSnapshot, schemaName, dataTableName, indexTableName, + null, -1, IndexTool.IndexVerifyType.BEFORE); + Assert.assertEquals(PIndexState.BUILDING, TestUtil.getIndexState(conn, indexTableFullName)); + + // Now there is no exception, so the second partial build should retry + Long scn = it.getJob().getConfiguration().getLong(CURRENT_SCN_VALUE, 1L); + IndexRebuildRegionScanner.setThrowExceptionForRebuild(false); + it = IndexToolIT.runIndexTool(directApi, useSnapshot, schemaName, dataTableName, indexTableName, + null, 0, IndexTool.IndexVerifyType.BEFORE,"-rv", Long.toString(scn)); + Assert.assertEquals(PIndexState.ACTIVE, TestUtil.getIndexState(conn, indexTableFullName)); + ResultSet rs = + conn.createStatement() + .executeQuery("SELECT COUNT(*) FROM " + indexTableFullName); + rs.next(); + assertEquals(1, rs.getInt(1)); + } + } + + @Test public void testIndexToolOnlyVerifyOption() throws Exception { String schemaName = generateUniqueName(); String dataTableName = generateUniqueName(); diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java index b82810c..6a10edc 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java @@ -125,6 +125,7 @@ public abstract class GlobalIndexRegionScanner extends BaseRegionScanner { protected byte[][] viewConstants; protected IndexVerificationOutputRepository verificationOutputRepository = null; protected boolean skipped = false; + protected boolean shouldRetry = false; protected boolean shouldVerifyCheckDone = false; final protected RegionCoprocessorEnvironment env; protected byte[][] regionEndKeys; @@ -373,7 +374,14 @@ public abstract class GlobalIndexRegionScanner extends BaseRegionScanner { if(verificationResultTemp != null) { verificationResult = verificationResultTemp; } + shouldVerifyCheckDone = true; + if (verificationResult != null && verificationResult.getShouldRetry()) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("ShouldRetry is true. " + region.getRegionInfo().getRegionNameAsString()); + } + return true; + } return verificationResultTemp == null; } @@ -408,7 +416,7 @@ public abstract class GlobalIndexRegionScanner extends BaseRegionScanner { try { if (verificationResultRepository != null) { verificationResultRepository.logToIndexToolResultTable(verificationResult, - verifyType, region.getRegionInfo().getRegionName(), skipped); + verifyType, region.getRegionInfo().getRegionName(), skipped, shouldRetry); } } finally { this.pool.stop("IndexRegionObserverRegionScanner is closing"); diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java index f51f07f..0ce1b08 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java @@ -70,8 +70,9 @@ public class IndexRebuildRegionScanner extends GlobalIndexRegionScanner { private static final Logger LOGGER = LoggerFactory.getLogger(IndexRebuildRegionScanner.class); private static boolean ignoreIndexRebuildForTesting = false; - + private static boolean throwExceptionForRebuild = false; public static void setIgnoreIndexRebuildForTesting(boolean ignore) { ignoreIndexRebuildForTesting = ignore; } + public static void setThrowExceptionForRebuild(boolean throwException) { throwExceptionForRebuild = throwException; } private int singleRowRebuildReturnCode; @@ -144,6 +145,9 @@ public class IndexRebuildRegionScanner extends GlobalIndexRegionScanner { if (ignoreIndexRebuildForTesting) { return; } + if (throwExceptionForRebuild) { + throw new IOException("Exception for testing. Something happened"); + } updateIndexRows(indexMutationMap, indexRowsToBeDeleted, verificationResult); } @@ -357,6 +361,7 @@ public class IndexRebuildRegionScanner extends GlobalIndexRegionScanner { } catch (Throwable e) { LOGGER.error("Exception in IndexRebuildRegionScanner for region " + region.getRegionInfo().getRegionNameAsString(), e); + this.shouldRetry = true; throw e; } finally { region.closeRegionOperation(); diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexToolVerificationResult.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexToolVerificationResult.java index 5919e8f..acdedab 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexToolVerificationResult.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexToolVerificationResult.java @@ -17,10 +17,12 @@ */ package org.apache.phoenix.coprocessor; +import com.sun.org.apache.xpath.internal.operations.Bool; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.schema.types.PBoolean; import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.AFTER_REBUILD_BEYOND_MAXLOOKBACK_INVALID_INDEX_ROW_COUNT_BYTES; import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.AFTER_REBUILD_BEYOND_MAXLOOKBACK_MISSING_INDEX_ROW_COUNT_BYTES; @@ -48,6 +50,7 @@ import static org.apache.phoenix.mapreduce.index.IndexVerificationResultReposito import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.REBUILT_INDEX_ROW_COUNT_BYTES; import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.RESULT_TABLE_COLUMN_FAMILY; import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.SCANNED_DATA_ROW_COUNT_BYTES; +import static org.apache.phoenix.mapreduce.index.IndexVerificationResultRepository.SHOULD_RETRY_BYTES; public class IndexToolVerificationResult { @@ -55,6 +58,10 @@ public class IndexToolVerificationResult { this.scannedDataRowCount = scannedDataRowCount; } + public void setShouldRetry(boolean shouldRetry) { + this.shouldRetry = shouldRetry; + } + public void setRebuiltIndexRowCount(long rebuiltIndexRowCount) { this.rebuiltIndexRowCount = rebuiltIndexRowCount; } @@ -351,6 +358,7 @@ public class IndexToolVerificationResult { private byte[] stopRow; private long scanMaxTs; private byte[] region; + private boolean shouldRetry = false; private PhaseResult before = new PhaseResult(); private PhaseResult after = new PhaseResult(); @@ -368,6 +376,10 @@ public class IndexToolVerificationResult { return scannedDataRowCount; } + public boolean getShouldRetry() { + return shouldRetry; + } + public long getRebuiltIndexRowCount() { return rebuiltIndexRowCount; } @@ -567,6 +579,9 @@ public class IndexToolVerificationResult { addScannedDataRowCount(getValue(cell)); } else if (CellUtil.matchingColumn(cell, RESULT_TABLE_COLUMN_FAMILY, REBUILT_INDEX_ROW_COUNT_BYTES)) { addRebuiltIndexRowCount(getValue(cell)); + } else if (CellUtil.matchingColumn(cell, RESULT_TABLE_COLUMN_FAMILY, SHOULD_RETRY_BYTES)) { + setShouldRetry((boolean) PBoolean.INSTANCE.toObject(cell.getValueArray(), + cell.getValueOffset(), cell.getValueLength())); } else if (CellUtil.matchingColumn(cell, RESULT_TABLE_COLUMN_FAMILY, BEFORE_REBUILD_VALID_INDEX_ROW_COUNT_BYTES)) { addBeforeRebuildValidIndexRowCount(getValue(cell)); } else if (CellUtil.matchingColumn(cell, RESULT_TABLE_COLUMN_FAMILY, BEFORE_REBUILD_EXPIRED_INDEX_ROW_COUNT_BYTES)) { diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java index de25606..7ec9b71 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java @@ -58,6 +58,8 @@ public class IndexVerificationResultRepository implements AutoCloseable { public final static byte[] SCANNED_DATA_ROW_COUNT_BYTES = Bytes.toBytes(SCANNED_DATA_ROW_COUNT); public final static String REBUILT_INDEX_ROW_COUNT = "RebuiltIndexRowCount"; public final static byte[] REBUILT_INDEX_ROW_COUNT_BYTES = Bytes.toBytes(REBUILT_INDEX_ROW_COUNT); + public final static String SHOULD_RETRY = "ShouldRetry"; + public final static byte[] SHOULD_RETRY_BYTES = Bytes.toBytes(SHOULD_RETRY); public final static String BEFORE_REBUILD_VALID_INDEX_ROW_COUNT = "BeforeRebuildValidIndexRowCount"; public final static byte[] BEFORE_REBUILD_VALID_INDEX_ROW_COUNT_BYTES = Bytes.toBytes(BEFORE_REBUILD_VALID_INDEX_ROW_COUNT); @@ -217,11 +219,11 @@ public class IndexVerificationResultRepository implements AutoCloseable { public void logToIndexToolResultTable(IndexToolVerificationResult verificationResult, IndexTool.IndexVerifyType verifyType, byte[] region) throws IOException { - logToIndexToolResultTable(verificationResult, verifyType, region, false); + logToIndexToolResultTable(verificationResult, verifyType, region, false, false); } public void logToIndexToolResultTable(IndexToolVerificationResult verificationResult, - IndexTool.IndexVerifyType verifyType, byte[] region, boolean skipped) throws IOException { + IndexTool.IndexVerifyType verifyType, byte[] region, boolean skipped, boolean shouldRetry) throws IOException { long scanMaxTs = verificationResult.getScanMaxTs(); byte[] rowKey = generateResultTableRowKey(scanMaxTs, indexTable.getName().toBytes(), region, verificationResult.getStartRow(), @@ -231,6 +233,8 @@ public class IndexVerificationResultRepository implements AutoCloseable { Bytes.toBytes(Long.toString(verificationResult.getScannedDataRowCount()))); put.addColumn(RESULT_TABLE_COLUMN_FAMILY, REBUILT_INDEX_ROW_COUNT_BYTES, Bytes.toBytes(Long.toString(verificationResult.getRebuiltIndexRowCount()))); + + put.addColumn(RESULT_TABLE_COLUMN_FAMILY, SHOULD_RETRY_BYTES, Bytes.toBytes(shouldRetry)); put.addColumn(RESULT_TABLE_COLUMN_FAMILY, INDEX_TOOL_RUN_STATUS_BYTES, Bytes.toBytes(skipped ? RUN_STATUS_SKIPPED : RUN_STATUS_EXECUTED)); if (verifyType == IndexTool.IndexVerifyType.BEFORE || verifyType == IndexTool.IndexVerifyType.BOTH ||