You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ac...@apache.org on 2017/09/25 14:13:09 UTC
hbase git commit: HBASE-18796 Admin#isTableAvailable returns
incorrect result before daughter regions are opened
Repository: hbase
Updated Branches:
refs/heads/branch-1.3 0068ae83b -> 1b3a745f8
HBASE-18796 Admin#isTableAvailable returns incorrect result before daughter regions are opened
Signed-off-by: Andrew Purtell <ap...@apache.org>
Signed-off-by: Abhishek Singh Chouhan <ac...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/1b3a745f
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/1b3a745f
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/1b3a745f
Branch: refs/heads/branch-1.3
Commit: 1b3a745f8640b52b33fec245917eb4796e7f4421
Parents: 0068ae8
Author: Abhishek Singh Chouhan <ac...@apache.org>
Authored: Mon Sep 18 14:56:14 2017 +0530
Committer: Abhishek Singh Chouhan <ac...@apache.org>
Committed: Mon Sep 25 19:41:15 2017 +0530
----------------------------------------------------------------------
.../apache/hadoop/hbase/MetaTableAccessor.java | 13 +++-
.../hadoop/hbase/TestMetaTableAccessor.java | 41 +++++++++++++
.../TestEndToEndSplitTransaction.java | 62 ++++++++++++++++++++
3 files changed, 114 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/1b3a745f/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
index a09ff88..3f11558 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
@@ -1297,8 +1297,8 @@ public class MetaTableAccessor {
Put putA = makePutFromRegionInfo(splitA);
Put putB = makePutFromRegionInfo(splitB);
- addLocation(putA, sn, 1, -1, splitA.getReplicaId()); //new regions, openSeqNum = 1 is fine.
- addLocation(putB, sn, 1, -1, splitB.getReplicaId());
+ addSequenceNum(putA, 1, -1, splitA.getReplicaId()); //new regions, openSeqNum = 1 is fine.
+ addSequenceNum(putB, 1, -1, splitB.getReplicaId());
// Add empty locations for region replicas of daughters so that number of replicas can be
// cached whenever the primary region is looked up from meta
@@ -1540,6 +1540,15 @@ public class MetaTableAccessor {
return p;
}
+ public static Put addSequenceNum(final Put p, long openSeqNum, long time, int replicaId) {
+ if (time <= 0) {
+ time = EnvironmentEdgeManager.currentTime();
+ }
+ p.addImmutable(HConstants.CATALOG_FAMILY, getSeqNumColumn(replicaId), time,
+ Bytes.toBytes(openSeqNum));
+ return p;
+ }
+
/**
* Checks whether hbase:meta contains any info:server entry.
* @param connection connection we're using
http://git-wip-us.apache.org/repos/asf/hbase/blob/1b3a745f/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableAccessor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableAccessor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableAccessor.java
index 3955a4c..cb2494b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableAccessor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableAccessor.java
@@ -644,5 +644,46 @@ public class TestMetaTableAccessor {
assertTrue(prevCalls < scheduler.numPriorityCalls);
}
}
+
+ @Test
+ public void testEmptyMetaDaughterLocationDuringSplit() throws IOException {
+ long regionId = System.currentTimeMillis();
+ ServerName serverName0 = ServerName.valueOf("foo", 60010, random.nextLong());
+ HRegionInfo parent = new HRegionInfo(TableName.valueOf("table_foo"), HConstants.EMPTY_START_ROW,
+ HConstants.EMPTY_END_ROW, false, regionId, 0);
+ HRegionInfo splitA = new HRegionInfo(TableName.valueOf("table_foo"), HConstants.EMPTY_START_ROW,
+ Bytes.toBytes("a"), false, regionId + 1, 0);
+ HRegionInfo splitB = new HRegionInfo(TableName.valueOf("table_foo"), Bytes.toBytes("a"),
+ HConstants.EMPTY_END_ROW, false, regionId + 1, 0);
+
+ Table meta = MetaTableAccessor.getMetaHTable(connection);
+ try {
+ List<HRegionInfo> regionInfos = Lists.newArrayList(parent);
+ MetaTableAccessor.addRegionsToMeta(connection, regionInfos, 3);
+
+ MetaTableAccessor.splitRegion(connection, parent, splitA, splitB, serverName0, 3);
+ Get get1 = new Get(splitA.getRegionName());
+ Result resultA = meta.get(get1);
+ Cell serverCellA = resultA.getColumnLatestCell(HConstants.CATALOG_FAMILY,
+ MetaTableAccessor.getServerColumn(splitA.getReplicaId()));
+ Cell startCodeCellA = resultA.getColumnLatestCell(HConstants.CATALOG_FAMILY,
+ MetaTableAccessor.getStartCodeColumn(splitA.getReplicaId()));
+ assertNull(serverCellA);
+ assertNull(startCodeCellA);
+
+ Get get2 = new Get(splitA.getRegionName());
+ Result resultB = meta.get(get2);
+ Cell serverCellB = resultB.getColumnLatestCell(HConstants.CATALOG_FAMILY,
+ MetaTableAccessor.getServerColumn(splitB.getReplicaId()));
+ Cell startCodeCellB = resultB.getColumnLatestCell(HConstants.CATALOG_FAMILY,
+ MetaTableAccessor.getStartCodeColumn(splitB.getReplicaId()));
+ assertNull(serverCellB);
+ assertNull(startCodeCellB);
+ } finally {
+ if (meta != null) {
+ meta.close();
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/1b3a745f/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java
index dfb01cb..0df3a91 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java
@@ -136,6 +136,11 @@ public class TestEndToEndSplitTransaction {
regions.getSecond().getRegionInfo());
}
+ // first daughter second
+ if (split.useZKForAssignment) {
+ server.postOpenDeployTasks(regions.getFirst());
+ }
+
// Add to online regions
server.addToOnlineRegions(regions.getSecond());
// THIS is the crucial point:
@@ -161,6 +166,63 @@ public class TestEndToEndSplitTransaction {
}
}
+ @Test
+ public void testTableAvailableWhileSplitting() throws Exception {
+ TableName tableName = TableName.valueOf("TestTableAvailableWhileSplitting");
+ byte[] familyName = Bytes.toBytes("fam");
+ try (HTable ht = TEST_UTIL.createTable(tableName, familyName)) {
+ TEST_UTIL.loadTable(ht, familyName, false);
+ }
+ Admin admin = TEST_UTIL.getHBaseAdmin();
+ HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(0);
+ byte[] splitRow = Bytes.toBytes("lll");
+ try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
+ byte[] regionName = conn.getRegionLocator(tableName).getRegionLocation(splitRow)
+ .getRegionInfo().getRegionName();
+ Region region = server.getRegion(regionName);
+ SplitTransactionImpl split = new SplitTransactionImpl((HRegion) region, splitRow);
+ split.prepare();
+ assertTrue(admin.isTableAvailable(tableName));
+
+ // 1. phase I
+ PairOfSameType<Region> regions = split.createDaughters(server, server, null);
+ // Parent should be offline at this stage and daughters not yet open
+ assertFalse(admin.isTableAvailable(tableName));
+
+ // passing null as services prevents final step of postOpenDeployTasks
+ // 2, most of phase II
+ split.openDaughters(server, null, regions.getFirst(), regions.getSecond());
+ assertFalse(admin.isTableAvailable(tableName));
+
+ // Finish openeing daughters
+ // 2nd daughter first
+ if (split.useZKForAssignment) {
+ server.postOpenDeployTasks(regions.getSecond());
+ } else {
+ server.reportRegionStateTransition(
+ RegionServerStatusProtos.RegionStateTransition.TransitionCode.SPLIT,
+ region.getRegionInfo(), regions.getFirst().getRegionInfo(),
+ regions.getSecond().getRegionInfo());
+ }
+
+ // first daughter second
+ if (split.useZKForAssignment) {
+ server.postOpenDeployTasks(regions.getFirst());
+ }
+
+ // After postOpenDeploy daughters should have location in meta
+ assertTrue(admin.isTableAvailable(tableName));
+
+ server.addToOnlineRegions(regions.getSecond());
+ server.addToOnlineRegions(regions.getFirst());
+ assertTrue(admin.isTableAvailable(tableName));
+ } finally {
+ if (admin != null) {
+ admin.close();
+ }
+ }
+ }
+
/**
* attempt to locate the region and perform a get and scan
* @return True if successful, False otherwise.