diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java index 28ebf7105854..e51321f32732 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java @@ -88,7 +88,7 @@ public abstract class TakeSnapshotHandler extends EventHandler protected final Path workingDir; private final MasterSnapshotVerifier verifier; protected final ForeignExceptionDispatcher monitor; - private final LockManager.MasterLock tableLock; + private LockManager.MasterLock tableLock; protected final MonitoredTask status; protected final TableName snapshotTable; protected final SnapshotManifest snapshotManifest; @@ -167,17 +167,30 @@ public TakeSnapshotHandler prepare() throws Exception { if (this.tableLock.tryAcquire(this.lockAcquireTimeoutMs)) { try { this.htd = loadTableDescriptor(); // check that .tableinfo is present + if (downgradeToSharedTableLock()) { + // release the exclusive lock and hold the shared lock instead + this.tableLock.release(); + this.tableLock = master.getLockManager().createMasterLock(snapshotTable, LockType.SHARED, + this.getClass().getName() + ": take snapshot " + snapshot.getName()); + if (!this.tableLock.tryAcquire(this.lockAcquireTimeoutMs)) { + throwLockNotAcquiredException(); + } + } } catch (Exception e) { this.tableLock.release(); throw e; } } else { - LOG.error("Master lock could not be acquired in {} ms", lockAcquireTimeoutMs); - throw new DoNotRetryIOException("Master lock could not be acquired"); + throwLockNotAcquiredException(); } return this; } + private void throwLockNotAcquiredException() throws DoNotRetryIOException { + LOG.error("Master lock could not be acquired in {} ms", lockAcquireTimeoutMs); + throw new DoNotRetryIOException("Master lock could not be acquired"); + } + /** * Execute the core common portions of taking a snapshot. The {@link #snapshotRegions(List)} call * should get implemented for each snapshot flavor. @@ -192,18 +205,6 @@ public void process() { MasterLock tableLockToRelease = this.tableLock; status.setStatus(msg); try { - if (downgradeToSharedTableLock()) { - // release the exclusive lock and hold the shared lock instead - tableLockToRelease = master.getLockManager().createMasterLock(snapshotTable, - LockType.SHARED, this.getClass().getName() + ": take snapshot " + snapshot.getName()); - tableLock.release(); - boolean isTableLockAcquired = tableLockToRelease.tryAcquire(this.lockAcquireTimeoutMs); - if (!isTableLockAcquired) { - LOG.error("Could not acquire shared lock on table {} in {} ms", snapshotTable, - lockAcquireTimeoutMs); - throw new IOException("Could not acquire shared lock on table " + snapshotTable); - } - } // If regions move after this meta scan, the region specific snapshot should fail, triggering // an external exception that gets captured here.