Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java (revision 1451424) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java (working copy) @@ -428,10 +428,10 @@ throws HBaseSnapshotException { TakeSnapshotHandler handler; try { - handler = new EnabledTableSnapshotHandler(snapshot, master, this); + handler = new EnabledTableSnapshotHandler(snapshot, master, this).prepare(); this.executorService.submit(handler); this.handler = handler; - } catch (IOException e) { + } catch (Exception e) { // cleanup the working directory by trying to delete it from the fs. Path workingDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(snapshot, rootDir); try { Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java (revision 1451424) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/EnabledTableSnapshotHandler.java (working copy) @@ -25,14 +25,21 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.errorhandling.ForeignException; import org.apache.hadoop.hbase.master.MasterServices; +import org.apache.hadoop.hbase.master.TableLockManager; +import org.apache.hadoop.hbase.master.TableLockManager.TableLock; import org.apache.hadoop.hbase.procedure.Procedure; import org.apache.hadoop.hbase.procedure.ProcedureCoordinator; import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription; import org.apache.hadoop.hbase.exceptions.HBaseSnapshotException; +import org.apache.hadoop.hbase.exceptions.SnapshotCreationException; +import org.apache.hadoop.hbase.executor.EventType; +import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; import com.google.common.collect.Lists; @@ -47,13 +54,44 @@ private static final Log LOG = LogFactory.getLog(EnabledTableSnapshotHandler.class); private final ProcedureCoordinator coordinator; + private final TableLockManager tableLockManager; + private final TableLock tableLock; public EnabledTableSnapshotHandler(SnapshotDescription snapshot, MasterServices master, SnapshotManager manager) throws IOException { super(snapshot, master); this.coordinator = manager.getCoordinator(); + this.tableLockManager = master.getTableLockManager(); + this.tableLock = this.tableLockManager.writeLock(Bytes.toBytes(snapshot.getTable()) + , EventType.C_M_SNAPSHOT_TABLE.toString()); } + @Override + public TakeSnapshotHandler prepare() throws Exception { + this.tableLock.acquire(); + return (TakeSnapshotHandler) super.prepare(); + } + + @Override + public void completeSnapshot(Path snapshotDir, Path workingDir, FileSystem fs) + throws SnapshotCreationException, IOException { + try { + super.completeSnapshot(snapshotDir, workingDir, fs); + } finally { + releaseTableLock(); + } + } + + private void releaseTableLock() { + if (this.tableLock != null) { + try { + this.tableLock.release(); + } catch (IOException ex) { + LOG.warn("Could not release the table lock", ex); + } + } + } + // TODO consider switching over to using regionnames, rather than server names. This would allow // regions to migrate during a snapshot, and then be involved when they are ready. Still want to // enforce a snapshot time constraints, but lets us be potentially a bit more robust. Index: hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java (revision 1451424) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java (working copy) @@ -87,9 +87,9 @@ conf.setInt("hbase.client.pause", 250); conf.setInt("hbase.client.retries.number", 6); conf.setBoolean("hbase.master.enabletable.roundrobin", true); - // Avoid potentially aggressive splitting which would cause snapshot to fail + /* Avoid potentially aggressive splitting which would cause snapshot to fail conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY, - ConstantSizeRegionSplitPolicy.class.getName()); + ConstantSizeRegionSplitPolicy.class.getName()); */ } @Before