diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java index 2f6d309..de80e5d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java @@ -19,7 +19,6 @@ package org.apache.hadoop.hbase.regionserver; import java.io.IOException; -import java.security.PrivilegedExceptionAction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,7 +58,7 @@ class SplitRequest implements Runnable { return "regionName=" + parent + ", midKey=" + Bytes.toStringBinary(midKey); } - private void doSplitting() { + private void doSplitting(User user) { boolean success = false; server.metricsRegionServer.incrSplitRequest(); long startTime = EnvironmentEdgeManager.currentTime(); @@ -80,7 +79,7 @@ class SplitRequest implements Runnable { // the prepare call -- we are not ready to split just now. Just return. if (!st.prepare()) return; try { - st.execute(this.server, this.server); + st.execute(this.server, this.server, user); success = true; } catch (Exception e) { if (this.server.isStopping() || this.server.isStopped()) { @@ -152,22 +151,7 @@ class SplitRequest implements Runnable { this.server.isStopping() + " or stopped=" + this.server.isStopped()); return; } - if (this.user == null) doSplitting(); - else { - try { - user.getUGI().doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - doSplitting(); - return null; - } - }); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } catch (IOException ioe) { - LOG.error("Encountered exception while splitting", ioe); - } - } + doSplitting(user); } protected void releaseTableLock() { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java index a21c19d..4bfc55e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java @@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.HBaseInterfaceAudience; import org.apache.hadoop.hbase.Server; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.PairOfSameType; /** @@ -191,20 +192,47 @@ public interface SplitTransaction { * @return Regions created * @throws IOException * @see #rollback(Server, RegionServerServices) + * @deprecated use #execute(Server, RegionServerServices, User) */ PairOfSameType execute(Server server, RegionServerServices services) throws IOException; /** + * Run the transaction. + * @param server Hosting server instance. Can be null when testing. + * @param services Used to online/offline regions. + * @param user + * @throws IOException If thrown, transaction failed. + * Call {@link #rollback(Server, RegionServerServices)} + * @return Regions created + * @throws IOException + * @see #rollback(Server, RegionServerServices) + */ + PairOfSameType execute(Server server, RegionServerServices services, User user) + throws IOException; + + /** * Roll back a failed transaction * @param server Hosting server instance (May be null when testing). * @param services * @throws IOException If thrown, rollback failed. Take drastic action. * @return True if we successfully rolled back, false if we got to the point * of no return and so now need to abort the server to minimize damage. + * @deprecated use #rollback(Server, RegionServerServices, User) */ boolean rollback(Server server, RegionServerServices services) throws IOException; /** + * Roll back a failed transaction + * @param server Hosting server instance (May be null when testing). + * @param services + * @param user + * @throws IOException If thrown, rollback failed. Take drastic action. + * @return True if we successfully rolled back, false if we got to the point + * of no return and so now need to abort the server to minimize damage. + */ + boolean rollback(Server server, RegionServerServices services, User user) throws IOException; + + /** * Register a listener for transaction preparation, execution, and possibly * rollback phases. *

A listener can abort a transaction by throwing an exception. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransactionImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransactionImpl.java index 5c24eaf..33bed2f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransactionImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransactionImpl.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.regionserver; import java.io.IOException; import java.io.InterruptedIOException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; @@ -47,6 +48,7 @@ import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.coordination.BaseCoordinatedStateManager; import org.apache.hadoop.hbase.coordination.SplitTransactionCoordination; import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CancelableProgressable; import org.apache.hadoop.hbase.util.ConfigUtil; @@ -217,12 +219,13 @@ public class SplitTransactionImpl implements SplitTransaction { * @param server Hosting server instance. Can be null when testing (won't try * and update in zk if a null server) * @param services Used to online/offline regions. + * @param user * @throws IOException If thrown, transaction failed. * Call {@link #rollback(Server, RegionServerServices)} * @return Regions created */ /* package */PairOfSameType createDaughters(final Server server, - final RegionServerServices services) throws IOException { + final RegionServerServices services, User user) throws IOException { LOG.info("Starting split of region " + this.parent); if ((server != null && server.isStopped()) || (services != null && services.isStopping())) { @@ -235,9 +238,26 @@ public class SplitTransactionImpl implements SplitTransaction { // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - // TODO: Remove one of these - this.parent.getCoprocessorHost().preSplit(); - this.parent.getCoprocessorHost().preSplit(this.splitrow); + if (user == null) { + // TODO: Remove one of these + parent.getCoprocessorHost().preSplit(); + parent.getCoprocessorHost().preSplit(splitrow); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preSplit(); + parent.getCoprocessorHost().preSplit(splitrow); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } transition(SplitTransactionPhase.AFTER_PRE_SPLIT_HOOK); @@ -251,11 +271,27 @@ public class SplitTransactionImpl implements SplitTransaction { PairOfSameType daughterRegions = stepsBeforePONR(server, services, testing); - List metaEntries = new ArrayList(); + final List metaEntries = new ArrayList(); + boolean ret = false; if (this.parent.getCoprocessorHost() != null) { - if (this.parent.getCoprocessorHost(). - preSplitBeforePONR(this.splitrow, metaEntries)) { - throw new IOException("Coprocessor bypassing region " + if (user == null) { + ret = parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries); + } else { + try { + ret = user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Boolean run() throws Exception { + return parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries); + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } + if (ret) { + throw new IOException("Coprocessor bypassing region " + this.parent.getRegionInfo().getRegionNameAsString() + " split."); } try { @@ -485,6 +521,15 @@ public class SplitTransactionImpl implements SplitTransaction { } } + public PairOfSameType execute(final Server server, + final RegionServerServices services) + throws IOException { + if (User.isHBaseSecurityEnabled(server.getConfiguration())) { + LOG.warn("Should use execute(Server, RegionServerServices, User)"); + } + return execute(server, services, null); + } + /** * Run the transaction. * @param server Hosting server instance. Can be null when testing @@ -495,8 +540,9 @@ public class SplitTransactionImpl implements SplitTransaction { * @throws IOException * @see #rollback(Server, RegionServerServices) */ + @Override public PairOfSameType execute(final Server server, - final RegionServerServices services) throws IOException { + final RegionServerServices services, User user) throws IOException { this.server = server; this.rsServices = services; useZKForAssignment = server == null ? true : @@ -506,11 +552,27 @@ public class SplitTransactionImpl implements SplitTransaction { ((BaseCoordinatedStateManager) server.getCoordinatedStateManager()) .getSplitTransactionCoordination().getDefaultDetails(); } - PairOfSameType regions = createDaughters(server, services); + PairOfSameType regions = createDaughters(server, services, user); if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().preSplitAfterPONR(); + if (user == null) { + parent.getCoprocessorHost().preSplitAfterPONR(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preSplitAfterPONR(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } - regions = stepsAfterPONR(server, services, regions); + regions = stepsAfterPONR(server, services, regions, user); transition(SplitTransactionPhase.COMPLETED); @@ -518,7 +580,7 @@ public class SplitTransactionImpl implements SplitTransaction { } public PairOfSameType stepsAfterPONR(final Server server, - final RegionServerServices services, PairOfSameType regions) + final RegionServerServices services, final PairOfSameType regions, User user) throws IOException { openDaughters(server, services, regions.getFirst(), regions.getSecond()); if (useCoordinatedStateManager(server)) { @@ -531,7 +593,23 @@ public class SplitTransactionImpl implements SplitTransaction { // Coprocessor callback if (parent.getCoprocessorHost() != null) { - parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + if (user == null) { + this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } transition(SplitTransactionPhase.AFTER_POST_SPLIT_HOOK); @@ -800,6 +878,15 @@ public class SplitTransactionImpl implements SplitTransaction { return splitStoreFile(family, sf); } } + + @Override + public boolean rollback(final Server server, final RegionServerServices services) + throws IOException { + if (User.isHBaseSecurityEnabled(server.getConfiguration())) { + LOG.warn("Should use rollback(Server, RegionServerServices, User)"); + } + return rollback(server, services, null); + } /** * @param server Hosting server instance (May be null when testing). @@ -808,12 +895,29 @@ public class SplitTransactionImpl implements SplitTransaction { * @return True if we successfully rolled back, false if we got to the point * of no return and so now need to abort the server to minimize damage. */ + @Override @SuppressWarnings("deprecation") - public boolean rollback(final Server server, final RegionServerServices services) + public boolean rollback(final Server server, final RegionServerServices services, User user) throws IOException { // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().preRollBackSplit(); + if (user == null) { + this.parent.getCoprocessorHost().preRollBackSplit(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preRollBackSplit(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } boolean result = true; @@ -895,7 +999,23 @@ public class SplitTransactionImpl implements SplitTransaction { } // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().postRollBackSplit(); + if (user == null) { + this.parent.getCoprocessorHost().postRollBackSplit(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().postRollBackSplit(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } return result; } 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 8de04a2..dfb01cb 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 @@ -114,7 +114,7 @@ public class TestEndToEndSplitTransaction { split.prepare(); // 1. phase I - PairOfSameType regions = split.createDaughters(server, server); + PairOfSameType regions = split.createDaughters(server, server, null); assertFalse(test(conn, tableName, firstRow, server)); assertFalse(test(conn, tableName, lastRow, server)); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java index 73d4622..df0d87c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java @@ -89,6 +89,7 @@ import org.apache.hadoop.hbase.master.RegionStates; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.regionserver.compactions.CompactionContext; import org.apache.hadoop.hbase.regionserver.compactions.NoLimitCompactionThroughputController; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; @@ -947,7 +948,7 @@ public class TestSplitTransactionOnCluster { SplitTransactionImpl st = new SplitTransactionImpl(region, Bytes.toBytes("row2")); try { st.prepare(); - st.createDaughters(regionServer, regionServer); + st.createDaughters(regionServer, regionServer, null); } catch (IOException e) { } @@ -1703,7 +1704,7 @@ public class TestSplitTransactionOnCluster { throws IOException { RegionCoprocessorEnvironment environment = ctx.getEnvironment(); HRegionServer rs = (HRegionServer) environment.getRegionServerServices(); - st.stepsAfterPONR(rs, rs, daughterRegions); + st.stepsAfterPONR(rs, rs, daughterRegions, null); } }