Skip to content

Commit

Permalink
HBASE-22767 System table RIT STUCK if their RSGroup has no highest ve…
Browse files Browse the repository at this point in the history
…rsion RSes

Signed-off-by: stack <[email protected]>
  • Loading branch information
sunhelly authored and saintstack committed Oct 9, 2019
1 parent 79c772f commit 4e5cb0f
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ private static String[] getVersionComponents(final String version) {
return comps;
}

public static int getMajorVersion(String version) {
return Integer.parseInt(version.split("\\.")[0]);
}

public static void main(String[] args) {
writeTo(System.out);
}
Expand Down
4 changes: 3 additions & 1 deletion hbase-common/src/saveVersion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ package org.apache.hadoop.hbase;
import org.apache.yetus.audience.InterfaceAudience;
@InterfaceAudience.Private
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="DM_STRING_CTOR",
justification="Intentional; to be modified in test")
public class Version {
public static final String version = "$version";
public static final String version = new String("$version");
public static final String revision = "$revision";
public static final String user = "$user";
public static final String date = "$date";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand All @@ -30,6 +32,7 @@
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Version;
import org.apache.hadoop.hbase.Waiter;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.RegionInfo;
Expand All @@ -40,6 +43,7 @@
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.JVMClusterUtil;
import org.apache.hadoop.hbase.util.VersionInfo;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
Expand Down Expand Up @@ -224,4 +228,54 @@ public void testKillAllRSInGroup() throws Exception {
// wait and check if table regions are online
TEST_UTIL.waitTableAvailable(tableName, 30000);
}

@Test
public void testLowerMetaGroupVersion() throws Exception{
// create a rsgroup and move one regionserver to it
String groupName = "meta_group";
int groupRSCount = 1;
addGroup(groupName, groupRSCount);

// move hbase:meta to meta_group
tableName = TableName.META_TABLE_NAME;
Set<TableName> toAddTables = new HashSet<>();
toAddTables.add(tableName);
rsGroupAdmin.moveTables(toAddTables, groupName);
assertTrue(rsGroupAdmin.getRSGroupInfo(groupName).getTables().contains(tableName));
TEST_UTIL.waitTableAvailable(tableName, 30000);

// restart the regionserver in meta_group, and lower its version
String originVersion = "";
Set<Address> servers = new HashSet<>();
for(Address addr : rsGroupAdmin.getRSGroupInfo(groupName).getServers()) {
servers.add(addr);
TEST_UTIL.getMiniHBaseCluster().stopRegionServer(getServerName(addr));
originVersion = master.getRegionServerVersion(getServerName(addr));
}
// better wait for a while for region reassign
sleep(10000);
assertEquals(NUM_SLAVES_BASE - groupRSCount,
TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size());
Address address = servers.iterator().next();
int majorVersion = VersionInfo.getMajorVersion(originVersion);
assertTrue(majorVersion >= 1);
String lowerVersion = String.valueOf(majorVersion - 1) + originVersion.split("\\.")[1];
setFinalStatic(Version.class.getField("version"), lowerVersion);
TEST_UTIL.getMiniHBaseCluster().startRegionServer(address.getHostname(),
address.getPort());
assertEquals(NUM_SLAVES_BASE,
TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size());
assertTrue(VersionInfo.compareVersion(originVersion,
master.getRegionServerVersion(getServerName(servers.iterator().next()))) > 0);
LOG.debug("wait for META assigned...");
TEST_UTIL.waitTableAvailable(tableName, 30000);
}

private static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1934,12 +1934,24 @@ private void processAssignQueue() {
LOG.debug("Processing assignQueue; systemServersCount=" + serversForSysTables.size() +
", allServersCount=" + servers.size());
processAssignmentPlans(regions, null, systemHRIs,
serversForSysTables.isEmpty()? servers: serversForSysTables);
serversForSysTables.isEmpty() && !containsBogusAssignments(regions, systemHRIs) ?
servers: serversForSysTables);
}

processAssignmentPlans(regions, retainMap, userHRIs, servers);
}

private boolean containsBogusAssignments(Map<RegionInfo, RegionStateNode> regions,
List<RegionInfo> hirs) {
for (RegionInfo ri : hirs) {
if (regions.get(ri).getRegionLocation() != null &&
regions.get(ri).getRegionLocation().equals(LoadBalancer.BOGUS_SERVER_NAME)){
return true;
}
}
return false;
}

private void processAssignmentPlans(final HashMap<RegionInfo, RegionStateNode> regions,
final HashMap<RegionInfo, ServerName> retainMap, final List<RegionInfo> hris,
final List<ServerName> servers) {
Expand Down Expand Up @@ -1995,7 +2007,16 @@ private void acceptPlan(final HashMap<RegionInfo, RegionStateNode> regions,
for (RegionInfo hri: entry.getValue()) {
final RegionStateNode regionNode = regions.get(hri);
regionNode.setRegionLocation(server);
events[evcount++] = regionNode.getProcedureEvent();
if (server.equals(LoadBalancer.BOGUS_SERVER_NAME) && regionNode.isSystemTable()) {
assignQueueLock.lock();
try {
pendingAssignQueue.add(regionNode);
} finally {
assignQueueLock.unlock();
}
}else {
events[evcount++] = regionNode.getProcedureEvent();
}
}
}
ProcedureEvent.wakeEvents(getProcedureScheduler(), events);
Expand Down

0 comments on commit 4e5cb0f

Please sign in to comment.