You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ka...@apache.org on 2019/09/15 20:39:55 UTC
[phoenix] branch 4.x-HBase-1.4 updated: PHOENIX-5473 Index write
failures during index rebuilds should not change index table state
This is an automated email from the ASF dual-hosted git repository.
kadir pushed a commit to branch 4.x-HBase-1.4
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.x-HBase-1.4 by this push:
new 0f00e16 PHOENIX-5473 Index write failures during index rebuilds should not change index table state
0f00e16 is described below
commit 0f00e16c0b1b67920a0c9077983a47257b856398
Author: Kadir <ko...@salesforce.com>
AuthorDate: Thu Sep 12 01:30:28 2019 -0700
PHOENIX-5473 Index write failures during index rebuilds should not change index table state
---
.../org/apache/phoenix/end2end/IndexToolIT.java | 54 ++++++++++++++++++++++
.../end2end/index/MutableIndexRebuilderIT.java | 7 ++-
.../end2end/index/PartialIndexRebuilderIT.java | 7 +--
.../UngroupedAggregateRegionObserver.java | 3 ++
.../phoenix/index/PhoenixIndexFailurePolicy.java | 7 ++-
5 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolIT.java
index 7819374..185b5a0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/IndexToolIT.java
@@ -57,6 +57,7 @@ import org.apache.phoenix.mapreduce.index.PhoenixServerBuildIndexMapper;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.PIndexState;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.transaction.PhoenixTransactionProvider.Feature;
import org.apache.phoenix.transaction.TransactionFactory;
@@ -336,6 +337,59 @@ public class IndexToolIT extends BaseUniqueNamesOwnClusterIT {
}
@Test
+ public void testSecondaryGlobalIndexFailure() throws Exception {
+ // This test is for building non-transactional global indexes with direct api
+ if (localIndex || transactional || !directApi || useSnapshot) {
+ return;
+ }
+ String schemaName = generateUniqueName();
+ String dataTableName = generateUniqueName();
+ String dataTableFullName = SchemaUtil.getTableName(schemaName, dataTableName);
+ String indexTableName = generateUniqueName();
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ String stmString1 =
+ "CREATE TABLE " + dataTableFullName
+ + " (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR, ZIP INTEGER) "
+ + tableDDLOptions;
+ conn.createStatement().execute(stmString1);
+ String upsertQuery = String.format("UPSERT INTO %s VALUES(?, ?, ?)", dataTableFullName);
+ PreparedStatement stmt1 = conn.prepareStatement(upsertQuery);
+
+ // Insert two rows
+ upsertRow(stmt1, 1);
+ upsertRow(stmt1, 2);
+ conn.commit();
+
+ String stmtString2 =
+ String.format(
+ "CREATE %s INDEX %s ON %s (LPAD(UPPER(NAME, 'en_US'),8,'x')||'_xyz') ASYNC ",
+ (localIndex ? "LOCAL" : ""), indexTableName, dataTableFullName);
+ conn.createStatement().execute(stmtString2);
+
+ // Run the index MR job.
+ runIndexTool(directApi, useSnapshot, schemaName, dataTableName, indexTableName);
+
+ String qIndexTableName = SchemaUtil.getQualifiedTableName(schemaName, indexTableName);
+
+ // Verify that the index table is in the ACTIVE state
+ assertEquals(PIndexState.ACTIVE, TestUtil.getIndexState(conn, qIndexTableName));
+
+ ConnectionQueryServices queryServices = conn.unwrap(PhoenixConnection.class).getQueryServices();
+ Admin admin = queryServices.getAdmin();
+ TableName tableName = TableName.valueOf(qIndexTableName);
+ admin.disableTable(tableName);
+
+ // Run the index MR job and it should fail (return -1)
+ runIndexTool(directApi, useSnapshot, schemaName, dataTableName, indexTableName,
+ null, -1, new String[0]);
+
+ // Verify that the index table should be still in the ACTIVE state
+ assertEquals(PIndexState.ACTIVE, TestUtil.getIndexState(conn, qIndexTableName));
+ }
+ }
+
+ @Test
public void testSaltedVariableLengthPK() throws Exception {
if (!mutable) return;
if (transactional) return;
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexRebuilderIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexRebuilderIT.java
index a3af20d..0373249 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexRebuilderIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexRebuilderIT.java
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver;
+import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
import org.apache.phoenix.coprocessor.MetaDataRegionObserver;
import org.apache.phoenix.coprocessor.MetaDataRegionObserver.BuildIndexScheduleTask;
@@ -75,7 +76,7 @@ public class MutableIndexRebuilderIT extends BaseUniqueNamesOwnClusterIT {
*/
@Test
public void testRebuildRetriesSuccessful() throws Throwable {
- int numberOfRetries = 5;
+ int numberOfRetries = 3;
Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(10);
serverProps.put(QueryServices.INDEX_FAILURE_HANDLING_REBUILD_ATTRIB, Boolean.TRUE.toString());
serverProps.put(QueryServices.INDEX_FAILURE_HANDLING_REBUILD_INTERVAL_ATTRIB, Long.toString(REBUILD_INTERVAL));
@@ -84,6 +85,8 @@ public class MutableIndexRebuilderIT extends BaseUniqueNamesOwnClusterIT {
serverProps.put(QueryServices.INDEX_FAILURE_HANDLING_REBUILD_OVERLAP_FORWARD_TIME_ATTRIB, Long.toString(WAIT_AFTER_DISABLED));
serverProps.put(HConstants.HBASE_CLIENT_RETRIES_NUMBER, numberOfRetries + "");
Map<String, String> clientProps = Maps.newHashMapWithExpectedSize(1);
+ // Index rebuilds are not needed with IndexRegionObserver
+ clientProps.put(QueryServices.INDEX_REGION_OBSERVER_ENABLED_ATTRIB, "false");
setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), new ReadOnlyProps(clientProps.entrySet().iterator()));
indexRebuildTaskRegionEnvironment =
(RegionCoprocessorEnvironment) getUtility()
@@ -155,7 +158,7 @@ public class MutableIndexRebuilderIT extends BaseUniqueNamesOwnClusterIT {
@Override
public void postBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c, MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
attempts.incrementAndGet();
- throw new DoNotRetryIOException("Simulating write failure on " + c.getEnvironment().getRegionInfo().getTable().getNameAsString());
+ throw new TimeoutIOException("Simulating write failure on " + c.getEnvironment().getRegionInfo().getTable().getNameAsString());
}
}
}
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/PartialIndexRebuilderIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/PartialIndexRebuilderIT.java
index 6ec3e2f..1d18ad6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/PartialIndexRebuilderIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/PartialIndexRebuilderIT.java
@@ -69,6 +69,7 @@ import org.apache.phoenix.util.RunUntilFailure;
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.TestUtil;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
@@ -1042,9 +1043,9 @@ public class PartialIndexRebuilderIT extends BaseUniqueNamesOwnClusterIT {
}
//Tests that when we're updating an index from within the RS (e.g. UngruopedAggregateRegionObserver),
- // if the index write fails the index gets disabled
+ // if the index write fails the index does not get disabled
@Test
- public void testIndexFailureWithinRSDisablesIndex() throws Throwable {
+ public void testIndexFailureWithinRSDoesnotDisablesIndex() throws Throwable {
String schemaName = generateUniqueName();
String tableName = generateUniqueName();
String indexName = generateUniqueName();
@@ -1065,7 +1066,7 @@ public class PartialIndexRebuilderIT extends BaseUniqueNamesOwnClusterIT {
} catch (SQLException e) {
// expected
}
- assertTrue(TestUtil.checkIndexState(conn, fullIndexName, PIndexState.DISABLE, null));
+ assertFalse(TestUtil.checkIndexState(conn, fullIndexName, PIndexState.PENDING_ACTIVE, null));
} finally {
TestUtil.removeCoprocessor(conn, fullIndexName, WriteFailingRegionObserver.class);
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
index b9a0f11..02596a0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
@@ -247,6 +247,9 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
try {
commitBatch(region, localRegionMutations, blockingMemstoreSize);
} catch (IOException e) {
+ if (e instanceof DoNotRetryIOException) {
+ throw(e);
+ }
handleIndexWriteException(localRegionMutations, e, new MutateCommand() {
@Override
public void doMutation() throws IOException {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
index eb264b5..7ca3d5b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
@@ -507,8 +507,11 @@ public class PhoenixIndexFailurePolicy extends DelegateIndexFailurePolicy {
throw new IOException(e);
}
}
- // max retries hit - disable the index
- handleIndexWriteFailureFromClient(iwe, connection);
+ if (!PhoenixIndexMetaData.isIndexRebuild(
+ mutateCommand.getMutationList().get(0).getAttributesMap())) {
+ // max retries hit - disable the index
+ handleIndexWriteFailureFromClient(iwe, connection);
+ }
throw new DoNotRetryIOException(iwe); // send failure back to client
}