From a1c6a462f75f3e266bfa68651957073a84feb86e Mon Sep 17 00:00:00 2001 From: Nihal Jain Date: Mon, 21 Jan 2019 12:33:01 +0530 Subject: [PATCH] HBASE-21644 Modify table procedure runs infinitely for a table having region replication > 1 Signed-off-by: zhangduo --- .../hadoop/hbase/regionserver/HRegion.java | 15 ++++++++++- .../hadoop/hbase/client/TestAdmin1.java | 20 ++++++++++++++ .../TestReplicationAdminWithClusters.java | 26 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index e292772b9c7..03f7487c1fa 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -989,7 +989,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // Use maximum of log sequenceid or that which was found in stores // (particularly if no recovered edits, seqid will be -1). long maxSeqIdFromFile = - WALSplitter.getMaxRegionSequenceId(getWalFileSystem(), getWALRegionDir()); + WALSplitter.getMaxRegionSequenceId(getWalFileSystem(), getWALRegionDirOfDefaultReplica()); long nextSeqId = Math.max(maxSeqId, maxSeqIdFromFile) + 1; // The openSeqNum will always be increase even for read only region, as we rely on it to // determine whether a region has been successfully reopend, so here we always need to update @@ -1897,6 +1897,19 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi return regionDir; } + /** + * @return the Region directory under WALRootDirectory; in case of secondary replica return the + * region directory corresponding to its default replica + * @throws IOException if there is an error getting WALRootDir + */ + private Path getWALRegionDirOfDefaultReplica() throws IOException { + RegionInfo regionInfo = getRegionInfo(); + if (!RegionReplicaUtil.isDefaultReplica(regionInfo)) { + regionInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(regionInfo); + } + return FSUtils.getWALRegionDir(conf, regionInfo.getTable(), regionInfo.getEncodedName()); + } + @Override public long getEarliestFlushTimeForAllStores() { return Collections.min(lastStoreFlushTimeMap.values()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java index 40de30a59b7..dfc3a2cd713 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java @@ -1555,4 +1555,24 @@ public class TestAdmin1 { // expected } } + + @Test + public void testModifyTableOnTableWithRegionReplicas() throws Exception { + TableName tableName = TableName.valueOf(name.getMethodName()); + TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName) + .setColumnFamily(ColumnFamilyDescriptorBuilder.of(Bytes.toBytes("cf"))) + .setRegionReplication(5) + .build(); + + admin.createTable(desc); + + int maxFileSize = 10000000; + TableDescriptor newDesc = TableDescriptorBuilder.newBuilder(desc) + .setMaxFileSize(maxFileSize) + .build(); + + admin.modifyTable(newDesc); + TableDescriptor newTableDesc = admin.getDescriptor(tableName); + assertEquals(maxFileSize, newTableDesc.getMaxFileSize()); + } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdminWithClusters.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdminWithClusters.java index e5743a886e3..0ff757eaa48 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdminWithClusters.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdminWithClusters.java @@ -33,8 +33,12 @@ import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; +import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.hadoop.hbase.client.TableDescriptorBuilder; import org.apache.hadoop.hbase.replication.BaseReplicationEndpoint; import org.apache.hadoop.hbase.replication.ReplicationPeerConfig; import org.apache.hadoop.hbase.replication.TestReplicationBase; @@ -178,6 +182,28 @@ public class TestReplicationAdminWithClusters extends TestReplicationBase { } } + @Test + public void testEnableReplicationForTableWithRegionReplica() throws Exception { + TableName tn = TableName.valueOf(name.getMethodName()); + TableDescriptor td = TableDescriptorBuilder.newBuilder(tn) + .setRegionReplication(5) + .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(noRepfamName).build()) + .build(); + + admin1.createTable(td); + + try { + admin1.enableTableReplication(tn); + td = admin1.getDescriptor(tn); + for (ColumnFamilyDescriptor fam : td.getColumnFamilies()) { + assertEquals(HConstants.REPLICATION_SCOPE_GLOBAL, fam.getScope()); + } + } finally { + utility1.deleteTable(tn); + utility2.deleteTable(tn); + } + } + @Test(expected = TableNotFoundException.class) public void testDisableReplicationForNonExistingTable() throws Exception { admin1.disableTableReplication(TableName.valueOf(name.getMethodName()));