You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by mb...@apache.org on 2013/12/10 12:44:31 UTC
svn commit: r1549819 - in /hbase/branches/0.96/hbase-server/src:
main/java/org/apache/hadoop/hbase/master/snapshot/
main/java/org/apache/hadoop/hbase/regionserver/
main/java/org/apache/hadoop/hbase/snapshot/
test/java/org/apache/hadoop/hbase/client/ te...
Author: mbertozzi
Date: Tue Dec 10 11:44:31 2013
New Revision: 1549819
URL: http://svn.apache.org/r1549819
Log:
HBASE-10111 Verify that a snapshot is not corrupted before restoring it
Modified:
hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotReferenceUtil.java
hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java
hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/SnapshotTestingUtils.java
Modified: hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java?rev=1549819&r1=1549818&r2=1549819&view=diff
==============================================================================
--- hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java (original)
+++ hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java Tue Dec 10 11:44:31 2013
@@ -67,6 +67,7 @@ import org.apache.hadoop.hbase.snapshot.
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
import org.apache.hadoop.hbase.snapshot.SnapshotExistsException;
+import org.apache.hadoop.hbase.snapshot.SnapshotReferenceUtil;
import org.apache.hadoop.hbase.snapshot.TablePartiallyOpenException;
import org.apache.hadoop.hbase.snapshot.UnknownSnapshotException;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
@@ -708,6 +709,9 @@ public class SnapshotManager implements
// stop tracking "abandoned" handlers
cleanupSentinels();
+ // Verify snapshot validity
+ SnapshotReferenceUtil.verifySnapshot(master.getConfiguration(), fs, snapshotDir, fsSnapshot);
+
// Execute the restore/clone operation
if (MetaReader.tableExists(master.getCatalogTracker(), tableName)) {
if (master.getAssignmentManager().getZKTable().isEnabledTable(
Modified: hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java?rev=1549819&r1=1549818&r2=1549819&view=diff
==============================================================================
--- hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java (original)
+++ hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java Tue Dec 10 11:44:31 2013
@@ -322,7 +322,7 @@ public class StoreFileInfo {
// after data loss in hdfs for whatever reason (upgrade, etc.): HBASE-646
// NOTE: that the HFileLink is just a name, so it's an empty file.
if (!HFileLink.isHFileLink(p) && fileStatus.getLen() <= 0) {
- LOG.warn("Skipping " + p + " beccreateStoreDirause its empty. HBASE-646 DATA LOSS?");
+ LOG.warn("Skipping " + p + " because it is empty. HBASE-646 DATA LOSS?");
return false;
}
Modified: hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotReferenceUtil.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotReferenceUtil.java?rev=1549819&r1=1549818&r2=1549819&view=diff
==============================================================================
--- hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotReferenceUtil.java (original)
+++ hbase/branches/0.96/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotReferenceUtil.java Tue Dec 10 11:44:31 2013
@@ -19,6 +19,7 @@
package org.apache.hadoop.hbase.snapshot;
import java.io.IOException;
+import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -27,10 +28,13 @@ import java.util.Set;
import java.util.TreeMap;
import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.io.HFileLink;
+import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
import org.apache.hadoop.hbase.regionserver.wal.HLogUtil;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.FSVisitor;
@@ -150,6 +154,32 @@ public final class SnapshotReferenceUtil
}
/**
+ * Verify the validity of the snapshot
+ *
+ * @param conf The current {@link Configuration} instance.
+ * @param fs {@link FileSystem}
+ * @param snapshotDir {@link Path} to the Snapshot directory of the snapshot to verify
+ * @param snapshotDesc the {@link SnapshotDescription} of the snapshot to verify
+ * @throws CorruptedSnapshotException if the snapshot is corrupted
+ * @throws IOException if an error occurred while scanning the directory
+ */
+ public static void verifySnapshot(final Configuration conf, final FileSystem fs,
+ final Path snapshotDir, final SnapshotDescription snapshotDesc) throws IOException {
+ final TableName table = TableName.valueOf(snapshotDesc.getTable());
+ visitTableStoreFiles(fs, snapshotDir, new FSVisitor.StoreFileVisitor() {
+ public void storeFile (final String region, final String family, final String hfile)
+ throws IOException {
+ HFileLink link = HFileLink.create(conf, table, region, family, hfile);
+ try {
+ link.getFileStatus(fs);
+ } catch (FileNotFoundException e) {
+ throw new CorruptedSnapshotException("Corrupted snapshot '" + snapshotDesc + "'", e);
+ }
+ }
+ });
+ }
+
+ /**
* Returns the set of region names available in the snapshot.
*
* @param fs {@link FileSystem}
Modified: hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java?rev=1549819&r1=1549818&r2=1549819&view=diff
==============================================================================
--- hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java (original)
+++ hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestRestoreSnapshotFromClient.java Tue Dec 10 11:44:31 2013
@@ -18,6 +18,7 @@
package org.apache.hadoop.hbase.client;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import java.io.IOException;
@@ -36,6 +37,7 @@ import org.apache.hadoop.hbase.LargeTest
import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
+import org.apache.hadoop.hbase.snapshot.CorruptedSnapshotException;
import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSUtils;
@@ -254,6 +256,22 @@ public class TestRestoreSnapshotFromClie
SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, snapshot0Rows);
}
+ @Test
+ public void testCorruptedSnapshot() throws IOException, InterruptedException {
+ SnapshotTestingUtils.corruptSnapshot(TEST_UTIL, Bytes.toString(snapshotName0));
+ TableName cloneName = TableName.valueOf("corruptedClone-" + System.currentTimeMillis());
+ try {
+ admin.cloneSnapshot(snapshotName0, cloneName);
+ fail("Expected CorruptedSnapshotException, got succeeded cloneSnapshot()");
+ } catch (CorruptedSnapshotException e) {
+ // Got the expected corruption exception.
+ // check for no references of the cloned table.
+ assertFalse(admin.tableExists(cloneName));
+ } catch (Exception e) {
+ fail("Expected CorruptedSnapshotException got: " + e);
+ }
+ }
+
// ==========================================================================
// Helpers
// ==========================================================================
Modified: hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/SnapshotTestingUtils.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/SnapshotTestingUtils.java?rev=1549819&r1=1549818&r2=1549819&view=diff
==============================================================================
--- hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/SnapshotTestingUtils.java (original)
+++ hbase/branches/0.96/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/SnapshotTestingUtils.java Tue Dec 10 11:44:31 2013
@@ -47,6 +47,7 @@ import org.apache.hadoop.hbase.client.Du
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.io.HFileLink;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
@@ -56,6 +57,7 @@ import org.apache.hadoop.hbase.protobuf.
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.snapshot.SnapshotReferenceUtil;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSTableDescriptors;
import org.apache.hadoop.hbase.util.FSUtils;
@@ -377,6 +379,40 @@ public class SnapshotTestingUtils {
new Path(rootDir, HConstants.HREGION_LOGDIR_NAME), null);
}
+ /**
+ * Corrupt the specified snapshot by deleting some files.
+ *
+ * @param util {@link HBaseTestingUtility}
+ * @param snapshotName name of the snapshot to corrupt
+ * @return array of the corrupted HFiles
+ * @throws IOException on unexecpted error reading the FS
+ */
+ public static ArrayList corruptSnapshot(final HBaseTestingUtility util, final String snapshotName)
+ throws IOException {
+ final MasterFileSystem mfs = util.getHBaseCluster().getMaster().getMasterFileSystem();
+ final FileSystem fs = mfs.getFileSystem();
+
+ Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName,
+ mfs.getRootDir());
+ SnapshotDescription snapshotDesc = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
+ final TableName table = TableName.valueOf(snapshotDesc.getTable());
+
+ final ArrayList corruptedFiles = new ArrayList();
+ SnapshotReferenceUtil.visitTableStoreFiles(fs, snapshotDir, new FSVisitor.StoreFileVisitor() {
+ public void storeFile (final String region, final String family, final String hfile)
+ throws IOException {
+ HFileLink link = HFileLink.create(util.getConfiguration(), table, region, family, hfile);
+ if (corruptedFiles.size() % 2 == 0) {
+ fs.delete(link.getAvailablePath(fs));
+ corruptedFiles.add(hfile);
+ }
+ }
+ });
+
+ assertTrue(corruptedFiles.size() > 0);
+ return corruptedFiles;
+ }
+
// ==========================================================================
// Table Helpers
// ==========================================================================