You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ra...@apache.org on 2012/08/24 20:43:33 UTC
svn commit: r1377033 - in /hbase/trunk/hbase-server/src:
main/java/org/apache/hadoop/hbase/coprocessor/
main/java/org/apache/hadoop/hbase/regionserver/
main/java/org/apache/hadoop/hbase/security/access/
test/java/org/apache/hadoop/hbase/coprocessor/ te...
Author: ramkrishna
Date: Fri Aug 24 18:43:33 2012
New Revision: 1377033
URL: http://svn.apache.org/viewvc?rev=1377033&view=rev
Log:
HBASE-6633 Adding new hooks to the split flow - For roll backs and one final hook after split is completed either successfully or failed
Submitted by:Ram
Reviewed by:Stack
Modified:
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransaction.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java Fri Aug 24 18:43:33 2012
@@ -105,6 +105,26 @@ public abstract class BaseRegionObserver
@Override
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
}
+
+ @Override
+ public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c,
+ byte[] splitRow) throws IOException {
+ }
+
+ @Override
+ public void preRollBackSplit(ObserverContext<RegionCoprocessorEnvironment> ctx)
+ throws IOException {
+ }
+
+ @Override
+ public void postRollBackSplit(
+ ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException {
+ }
+
+ @Override
+ public void postCompleteSplit(
+ ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException {
+ }
@Override
public void postSplit(ObserverContext<RegionCoprocessorEnvironment> e, HRegion l, HRegion r)
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java Fri Aug 24 18:43:33 2012
@@ -213,8 +213,17 @@ public interface RegionObserver extends
* @param c the environment provided by the region server
* (e.getRegion() returns the parent region)
* @throws IOException if an error occurred on the coprocessor
+ * @deprecated Use preSplit(final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow)
*/
void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
+
+ /**
+ * Called before the region is split.
+ * @param c the environment provided by the region server
+ * (e.getRegion() returns the parent region)
+ * @throws IOException if an error occurred on the coprocessor
+ */
+ void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow) throws IOException;
/**
* Called after the region is split.
@@ -223,10 +232,32 @@ public interface RegionObserver extends
* @param l the left daughter region
* @param r the right daughter region
* @throws IOException if an error occurred on the coprocessor
+ * @deprecated Use postCompleteSplit() instead
*/
void postSplit(final ObserverContext<RegionCoprocessorEnvironment> c, final HRegion l,
final HRegion r) throws IOException;
-
+
+ /**
+ * This will be called before the roll back of the split region is completed
+ * @param ctx
+ * @throws IOException
+ */
+ void preRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
+
+ /**
+ * This will be called after the roll back of the split region is completed
+ * @param ctx
+ * @throws IOException
+ */
+ void postRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
+
+ /**
+ * Called after any split request is processed. This will be called irrespective of success or
+ * failure of the split.
+ * @param ctx
+ * @throws IOException
+ */
+ void postCompleteSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
/**
* Called before the region is reported as closed to the master.
* @param c the environment provided by the region server
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java Fri Aug 24 18:43:33 2012
@@ -601,6 +601,27 @@ public class RegionCoprocessorHost
}
}
}
+
+ /**
+ * Invoked just before a split
+ * @throws IOException
+ */
+ public void preSplit(byte[] splitRow) throws IOException {
+ ObserverContext<RegionCoprocessorEnvironment> ctx = null;
+ for (RegionEnvironment env: coprocessors) {
+ if (env.getInstance() instanceof RegionObserver) {
+ ctx = ObserverContext.createAndPrepare(env, ctx);
+ try {
+ ((RegionObserver)env.getInstance()).preSplit(ctx, splitRow);
+ } catch (Throwable e) {
+ handleCoprocessorThrowable(env, e);
+ }
+ if (ctx.shouldComplete()) {
+ break;
+ }
+ }
+ }
+ }
/**
* Invoked just after a split
@@ -624,7 +645,69 @@ public class RegionCoprocessorHost
}
}
}
-
+
+ /**
+ * Invoked just before the rollback of a failed split is started
+ * @throws IOException
+ */
+ public void preRollBackSplit() throws IOException {
+ ObserverContext<RegionCoprocessorEnvironment> ctx = null;
+ for (RegionEnvironment env : coprocessors) {
+ if (env.getInstance() instanceof RegionObserver) {
+ ctx = ObserverContext.createAndPrepare(env, ctx);
+ try {
+ ((RegionObserver) env.getInstance()).preRollBackSplit(ctx);
+ } catch (Throwable e) {
+ handleCoprocessorThrowable(env, e);
+ }
+ if (ctx.shouldComplete()) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Invoked just after the rollback of a failed split is done
+ * @throws IOException
+ */
+ public void postRollBackSplit() throws IOException {
+ ObserverContext<RegionCoprocessorEnvironment> ctx = null;
+ for (RegionEnvironment env : coprocessors) {
+ if (env.getInstance() instanceof RegionObserver) {
+ ctx = ObserverContext.createAndPrepare(env, ctx);
+ try {
+ ((RegionObserver) env.getInstance()).postRollBackSplit(ctx);
+ } catch (Throwable e) {
+ handleCoprocessorThrowable(env, e);
+ }
+ if (ctx.shouldComplete()) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Invoked after a split is completed irrespective of a failure or success.
+ * @throws IOException
+ */
+ public void postCompleteSplit() throws IOException {
+ ObserverContext<RegionCoprocessorEnvironment> ctx = null;
+ for (RegionEnvironment env : coprocessors) {
+ if (env.getInstance() instanceof RegionObserver) {
+ ctx = ObserverContext.createAndPrepare(env, ctx);
+ try {
+ ((RegionObserver) env.getInstance()).postCompleteSplit(ctx);
+ } catch (Throwable e) {
+ handleCoprocessorThrowable(env, e);
+ }
+ if (ctx.shouldComplete()) {
+ break;
+ }
+ }
+ }
+ }
// RegionObserver support
/**
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java Fri Aug 24 18:43:33 2012
@@ -105,6 +105,15 @@ class SplitRequest implements Runnable {
.checkIOException(ex));
this.server.getMetrics().incrementSplitFailureCount();
server.checkFileSystem();
+ } finally {
+ if (this.parent.getCoprocessorHost() != null) {
+ try {
+ this.parent.getCoprocessorHost().postCompleteSplit();
+ } catch (IOException io) {
+ LOG.error("Split failed " + this,
+ RemoteExceptionHandler.checkIOException(io));
+ }
+ }
}
}
}
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java Fri Aug 24 18:43:33 2012
@@ -229,6 +229,11 @@ public class SplitTransaction {
if (this.parent.getCoprocessorHost() != null) {
this.parent.getCoprocessorHost().preSplit();
}
+
+ // Coprocessor callback
+ if (this.parent.getCoprocessorHost() != null) {
+ this.parent.getCoprocessorHost().preSplit(this.splitrow);
+ }
// If true, no cluster to write meta edits to or to update znodes in.
boolean testing = server == null? true:
@@ -727,6 +732,11 @@ public class SplitTransaction {
*/
public boolean rollback(final Server server, final RegionServerServices services)
throws IOException {
+ // Coprocessor callback
+ if (this.parent.getCoprocessorHost() != null) {
+ this.parent.getCoprocessorHost().preRollBackSplit();
+ }
+
boolean result = true;
FileSystem fs = this.parent.getFilesystem();
ListIterator<JournalEntry> iterator =
@@ -793,6 +803,10 @@ public class SplitTransaction {
throw new RuntimeException("Unhandled journal entry: " + je);
}
}
+ // Coprocessor callback
+ if (this.parent.getCoprocessorHost() != null) {
+ this.parent.getCoprocessorHost().postRollBackSplit();
+ }
return result;
}
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java Fri Aug 24 18:43:33 2012
@@ -799,6 +799,12 @@ public class AccessController extends Ba
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
requirePermission(getTableName(e.getEnvironment()), null, null, Action.ADMIN);
}
+
+ @Override
+ public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e,
+ byte[] splitRow) throws IOException {
+ requirePermission(getTableName(e.getEnvironment()), null, null, Action.ADMIN);
+ }
@Override
public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e,
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java Fri Aug 24 18:43:33 2012
@@ -140,6 +140,7 @@ public class TestCoprocessorInterface ex
private boolean postFlushCalled;
private boolean preSplitCalled;
private boolean postSplitCalled;
+ private boolean preSplitWithSplitRowCalled;
private ConcurrentMap<String, Object> sharedData;
@Override
@@ -195,6 +196,12 @@ public class TestCoprocessorInterface ex
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e) {
preSplitCalled = true;
}
+
+ @Override
+ public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c,
+ byte[] splitRow) throws IOException {
+ preSplitWithSplitRowCalled = true;
+ }
@Override
public void postSplit(ObserverContext<RegionCoprocessorEnvironment> e, HRegion l, HRegion r) {
postSplitCalled = true;
@@ -225,7 +232,7 @@ public class TestCoprocessorInterface ex
return (preCompactCalled && postCompactCalled);
}
boolean wasSplit() {
- return (preSplitCalled && postSplitCalled);
+ return (preSplitCalled && postSplitCalled && preSplitWithSplitRowCalled);
}
Map<String, Object> getSharedData() {
return sharedData;
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransaction.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransaction.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransaction.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransaction.java Fri Aug 24 18:43:33 2012
@@ -35,6 +35,10 @@ import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
+import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
+import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.HLog;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.PairOfSameType;
@@ -63,13 +67,19 @@ public class TestSplitTransaction {
private static final byte [] GOOD_SPLIT_ROW = new byte [] {'d', 'd', 'd'};
private static final byte [] CF = HConstants.CATALOG_FAMILY;
+ private static boolean preRollBackCalled = false;
+ private static boolean postRollBackCalled = false;
+
@Before public void setup() throws IOException {
this.fs = FileSystem.get(TEST_UTIL.getConfiguration());
+ TEST_UTIL.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, CustomObserver.class.getName());
this.fs.delete(this.testdir, true);
this.wal = new HLog(fs, new Path(this.testdir, "logs"),
new Path(this.testdir, "archive"),
TEST_UTIL.getConfiguration());
this.parent = createRegion(this.testdir, this.wal);
+ RegionCoprocessorHost host = new RegionCoprocessorHost(this.parent, null, TEST_UTIL.getConfiguration());
+ this.parent.setCoprocessorHost(host);
TEST_UTIL.getConfiguration().setBoolean("hbase.testing.nocluster", true);
}
@@ -280,6 +290,11 @@ public class TestSplitTransaction {
assertEquals(rowcount, daughtersRowCount);
// Assert the write lock is no longer held on parent
assertTrue(!this.parent.lock.writeLock().isHeldByCurrentThread());
+ assertTrue("Rollback hooks should be called.", wasRollBackHookCalled());
+ }
+
+ private boolean wasRollBackHookCalled(){
+ return (preRollBackCalled && postRollBackCalled);
}
/**
@@ -318,6 +333,20 @@ public class TestSplitTransaction {
return HRegion.openHRegion(testdir, hri, htd, wal,
TEST_UTIL.getConfiguration());
}
+
+ public static class CustomObserver extends BaseRegionObserver{
+ @Override
+ public void preRollBackSplit(
+ ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException {
+ preRollBackCalled = true;
+ }
+
+ @Override
+ public void postRollBackSplit(
+ ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException {
+ postRollBackCalled = true;
+ }
+ }
@org.junit.Rule
public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java?rev=1377033&r1=1377032&r2=1377033&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java Fri Aug 24 18:43:33 2012
@@ -460,6 +460,22 @@ public class TestAccessController {
}
@Test
+ public void testSplitWithSplitRow() throws Exception {
+ PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preSplit(
+ ObserverContext.createAndPrepare(RCP_ENV, null),
+ Bytes.toBytes("row2"));
+ return null;
+ }
+ };
+
+ verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
+ verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
+ }
+
+
+ @Test
public void testFlush() throws Exception {
PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
public Object run() throws Exception {