HBASE-7992 provide pre/post region offline hooks for HMaster.offlineRegion() (Rajeshbabu)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1457854 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Zhihong Yu 2013-03-18 16:44:04 +00:00
parent c826a16e5d
commit a832f774c4
7 changed files with 130 additions and 1 deletions

View File

@ -232,6 +232,16 @@ public class BaseMasterObserver implements MasterObserver {
HRegionInfo regionInfo, boolean force) throws IOException { HRegionInfo regionInfo, boolean force) throws IOException {
} }
@Override
public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> ctx,
HRegionInfo regionInfo) throws IOException {
}
@Override
public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> ctx,
HRegionInfo regionInfo) throws IOException {
}
@Override @Override
public void preBalance(ObserverContext<MasterCoprocessorEnvironment> ctx) public void preBalance(ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException { throws IOException {

View File

@ -440,6 +440,23 @@ public interface MasterObserver extends Coprocessor {
void postUnassign(final ObserverContext<MasterCoprocessorEnvironment> ctx, void postUnassign(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final HRegionInfo regionInfo, final boolean force) throws IOException; final HRegionInfo regionInfo, final boolean force) throws IOException;
/**
* Called prior to marking a given region as offline. <code>ctx.bypass()</code> will not have any
* impact on this hook.
* @param ctx the environment to interact with the framework and master
* @param regionInfo
*/
void preRegionOffline(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final HRegionInfo regionInfo) throws IOException;
/**
* Called after the region has been marked offline.
* @param ctx the environment to interact with the framework and master
* @param regionInfo
*/
void postRegionOffline(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final HRegionInfo regionInfo) throws IOException;
/** /**
* Called prior to requesting rebalancing of the cluster regions, though after * Called prior to requesting rebalancing of the cluster regions, though after
* the initial checks for regions in transition and the balance switch flag. * the initial checks for regions in transition and the balance switch flag.

View File

@ -2252,7 +2252,11 @@ Server {
} }
/** /**
* Special method, only used by hbck. * Offline specified region from master's in-memory state. It will not attempt to
* reassign the region as in unassign.
*
* This is a special method that should be used by experts or hbck.
*
*/ */
@Override @Override
public OfflineRegionResponse offlineRegion(RpcController controller, OfflineRegionRequest request) public OfflineRegionResponse offlineRegion(RpcController controller, OfflineRegionRequest request)
@ -2269,7 +2273,13 @@ Server {
MetaReader.getRegion(this.catalogTracker, regionName); MetaReader.getRegion(this.catalogTracker, regionName);
if (pair == null) throw new UnknownRegionException(Bytes.toStringBinary(regionName)); if (pair == null) throw new UnknownRegionException(Bytes.toStringBinary(regionName));
HRegionInfo hri = pair.getFirst(); HRegionInfo hri = pair.getFirst();
if (cpHost != null) {
cpHost.preRegionOffline(hri);
}
this.assignmentManager.regionOffline(hri); this.assignmentManager.regionOffline(hri);
if (cpHost != null) {
cpHost.postRegionOffline(hri);
}
} catch (IOException ioe) { } catch (IOException ioe) {
throw new ServiceException(ioe); throw new ServiceException(ioe);
} }

View File

@ -811,6 +811,40 @@ public class MasterCoprocessorHost
} }
} }
void preRegionOffline(final HRegionInfo regionInfo) throws IOException {
ObserverContext<MasterCoprocessorEnvironment> ctx = null;
for (MasterEnvironment env : coprocessors) {
if (env.getInstance() instanceof MasterObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((MasterObserver) env.getInstance()).preRegionOffline(ctx, regionInfo);
} catch (Throwable e) {
handleCoprocessorThrowable(env, e);
}
if (ctx.shouldComplete()) {
break;
}
}
}
}
void postRegionOffline(final HRegionInfo regionInfo) throws IOException {
ObserverContext<MasterCoprocessorEnvironment> ctx = null;
for (MasterEnvironment env : coprocessors) {
if (env.getInstance() instanceof MasterObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((MasterObserver) env.getInstance()).postRegionOffline(ctx, regionInfo);
} catch (Throwable e) {
handleCoprocessorThrowable(env, e);
}
if (ctx.shouldComplete()) {
break;
}
}
}
}
boolean preBalance() throws IOException { boolean preBalance() throws IOException {
boolean bypass = false; boolean bypass = false;
ObserverContext<MasterCoprocessorEnvironment> ctx = null; ObserverContext<MasterCoprocessorEnvironment> ctx = null;

View File

@ -674,6 +674,17 @@ public class AccessController extends BaseRegionObserver
public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c, public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c,
HRegionInfo regionInfo, boolean force) throws IOException {} HRegionInfo regionInfo, boolean force) throws IOException {}
@Override
public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c,
HRegionInfo regionInfo) throws IOException {
requirePermission("regionOffline", regionInfo.getTableName(), null, null, Action.ADMIN);
}
@Override
public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c,
HRegionInfo regionInfo) throws IOException {
}
@Override @Override
public void preBalance(ObserverContext<MasterCoprocessorEnvironment> c) public void preBalance(ObserverContext<MasterCoprocessorEnvironment> c)
throws IOException { throws IOException {

View File

@ -90,6 +90,8 @@ public class TestMasterObserver {
private boolean postAssignCalled; private boolean postAssignCalled;
private boolean preUnassignCalled; private boolean preUnassignCalled;
private boolean postUnassignCalled; private boolean postUnassignCalled;
private boolean preRegionOfflineCalled;
private boolean postRegionOfflineCalled;
private boolean preBalanceCalled; private boolean preBalanceCalled;
private boolean postBalanceCalled; private boolean postBalanceCalled;
private boolean preBalanceSwitchCalled; private boolean preBalanceSwitchCalled;
@ -151,6 +153,8 @@ public class TestMasterObserver {
postAssignCalled = false; postAssignCalled = false;
preUnassignCalled = false; preUnassignCalled = false;
postUnassignCalled = false; postUnassignCalled = false;
preRegionOfflineCalled = false;
postRegionOfflineCalled = false;
preBalanceCalled = false; preBalanceCalled = false;
postBalanceCalled = false; postBalanceCalled = false;
preBalanceSwitchCalled = false; preBalanceSwitchCalled = false;
@ -441,6 +445,26 @@ public class TestMasterObserver {
return preUnassignCalled && !postUnassignCalled; return preUnassignCalled && !postUnassignCalled;
} }
@Override
public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
final HRegionInfo regionInfo) throws IOException {
preRegionOfflineCalled = true;
}
@Override
public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
final HRegionInfo regionInfo) throws IOException {
postRegionOfflineCalled = true;
}
public boolean wasRegionOfflineCalled() {
return preRegionOfflineCalled && postRegionOfflineCalled;
}
public boolean preRegionOfflineCalledOnly() {
return preRegionOfflineCalled && !postRegionOfflineCalled;
}
@Override @Override
public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env) public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env)
throws IOException { throws IOException {

View File

@ -486,6 +486,29 @@ public class TestAccessController {
verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE); verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
} }
@Test
public void testRegionOffline() throws Exception {
Map<HRegionInfo, ServerName> regions;
HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE);
try {
regions = table.getRegionLocations();
} finally {
table.close();
}
final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preRegionOffline(ObserverContext.createAndPrepare(CP_ENV, null),
firstRegion.getKey());
return null;
}
};
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
}
@Test @Test
public void testBalance() throws Exception { public void testBalance() throws Exception {
PrivilegedExceptionAction action = new PrivilegedExceptionAction() { PrivilegedExceptionAction action = new PrivilegedExceptionAction() {