Repository: hbase
Updated Branches:
  refs/heads/master 2f8ddf6fc -> 6d98c4869


HBASE-17452 Failed taking snapshot - region Manifest proto-message too large 
(huaxiang sun)


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/6d98c486
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/6d98c486
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/6d98c486

Branch: refs/heads/master
Commit: 6d98c48699061bfe60aee5ab6c2a1e9bff22587b
Parents: 2f8ddf6
Author: tedyu <yuzhih...@gmail.com>
Authored: Fri Jan 13 07:59:31 2017 -0800
Committer: tedyu <yuzhih...@gmail.com>
Committed: Fri Jan 13 07:59:31 2017 -0800

----------------------------------------------------------------------
 .../hadoop/hbase/snapshot/SnapshotManifest.java |   6 +-
 .../hbase/snapshot/SnapshotManifestV2.java      |   8 +-
 .../hbase/snapshot/TestSnapshotManifest.java    | 110 +++++++++++++++----
 3 files changed, 96 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/6d98c486/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java
index 7dd6f49..e74982d 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java
@@ -365,7 +365,8 @@ public final class SnapshotManifest {
           ThreadPoolExecutor tpool = createExecutor("SnapshotManifestLoader");
           try {
             v1Regions = SnapshotManifestV1.loadRegionManifests(conf, tpool, 
fs, workingDir, desc);
-            v2Regions = SnapshotManifestV2.loadRegionManifests(conf, tpool, 
fs, workingDir, desc);
+            v2Regions = SnapshotManifestV2.loadRegionManifests(conf, tpool, 
fs, workingDir, desc,
+                manifestSizeLimit);
           } catch (InvalidProtocolBufferException e) {
             throw new CorruptedSnapshotException("unable to parse region 
manifest " +
                 e.getMessage(), e);
@@ -458,7 +459,8 @@ public final class SnapshotManifest {
     ThreadPoolExecutor tpool = createExecutor("SnapshotManifestLoader");
     try {
       v1Regions = SnapshotManifestV1.loadRegionManifests(conf, tpool, fs, 
workingDir, desc);
-      v2Regions = SnapshotManifestV2.loadRegionManifests(conf, tpool, fs, 
workingDir, desc);
+      v2Regions = SnapshotManifestV2.loadRegionManifests(conf, tpool, fs, 
workingDir, desc,
+          manifestSizeLimit);
     } finally {
       tpool.shutdown();
     }

http://git-wip-us.apache.org/repos/asf/hbase/blob/6d98c486/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifestV2.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifestV2.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifestV2.java
index 18c2a13..a1341fb 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifestV2.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifestV2.java
@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.hbase.snapshot;
 
+import org.apache.hadoop.hbase.shaded.com.google.protobuf.CodedInputStream;
 import 
org.apache.hadoop.hbase.shaded.com.google.protobuf.InvalidProtocolBufferException;
 import org.apache.hadoop.hbase.shaded.com.google.protobuf.UnsafeByteOperations;
 
@@ -127,7 +128,7 @@ public final class SnapshotManifestV2 {
 
   static List<SnapshotRegionManifest> loadRegionManifests(final Configuration 
conf,
       final Executor executor,final FileSystem fs, final Path snapshotDir,
-      final SnapshotDescription desc) throws IOException {
+      final SnapshotDescription desc, final int manifestSizeLimit) throws 
IOException {
     FileStatus[] manifestFiles = FSUtils.listStatus(fs, snapshotDir, new 
PathFilter() {
       @Override
       public boolean accept(Path path) {
@@ -144,8 +145,11 @@ public final class SnapshotManifestV2 {
         @Override
         public SnapshotRegionManifest call() throws IOException {
           FSDataInputStream stream = fs.open(st.getPath());
+          CodedInputStream cin = CodedInputStream.newInstance(stream);
+          cin.setSizeLimit(manifestSizeLimit);
+
           try {
-            return SnapshotRegionManifest.parseFrom(stream);
+            return SnapshotRegionManifest.parseFrom(cin);
           } finally {
             stream.close();
           }

http://git-wip-us.apache.org/repos/asf/hbase/blob/6d98c486/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestSnapshotManifest.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestSnapshotManifest.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestSnapshotManifest.java
index 2a610bf..f8aa5ca 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestSnapshotManifest.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestSnapshotManifest.java
@@ -51,6 +51,7 @@ public class TestSnapshotManifest {
   private static final String TABLE_NAME_STR = "testSnapshotManifest";
   private static final TableName TABLE_NAME = 
TableName.valueOf(TABLE_NAME_STR);
   private static final int TEST_NUM_REGIONS = 16000;
+  private static final int TEST_NUM_REGIONFILES = 1000000;
 
   private static HBaseTestingUtility TEST_UTIL;
   private Configuration conf;
@@ -58,6 +59,7 @@ public class TestSnapshotManifest {
   private Path rootDir;
   private Path snapshotDir;
   private SnapshotDescription snapshotDesc;
+  private SnapshotTestingUtils.SnapshotMock.SnapshotBuilder builder;
 
   @Before
   public void setup() throws Exception {
@@ -69,20 +71,63 @@ public class TestSnapshotManifest {
 
     SnapshotTestingUtils.SnapshotMock snapshotMock =
       new SnapshotTestingUtils.SnapshotMock(conf, fs, rootDir);
-    SnapshotTestingUtils.SnapshotMock.SnapshotBuilder builder =
-      snapshotMock.createSnapshotV2("snapshot", TABLE_NAME_STR, 0);
+    builder = snapshotMock.createSnapshotV2("snapshot", TABLE_NAME_STR, 0);
     snapshotDir = builder.commit();
     snapshotDesc = builder.getSnapshotDescription();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    fs.delete(rootDir,true);
+  }
 
+  @Test
+  public void testReadSnapshotManifest() throws IOException {
+
+    Path p = createDataManifest();
+    try {
+      SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
+      fail("fail to test snapshot manifest because message size is too 
small.");
+    } catch (CorruptedSnapshotException cse) {
+      try {
+        conf.setInt(SnapshotManifest.SNAPSHOT_MANIFEST_SIZE_LIMIT_CONF_KEY, 
128 * 1024 * 1024);
+        SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
+        LOG.info("open snapshot manifest succeed.");
+      } catch (CorruptedSnapshotException cse2) {
+        fail("fail to take snapshot because Manifest proto-message too 
large.");
+      }
+    } finally {
+      fs.delete(p, false);
+    }
+  }
+
+  @Test
+  public void testReadSnapshotRegionManifest() throws IOException {
+
+    // remove datamanifest file
+    fs.delete(new Path(snapshotDir, SnapshotManifest.DATA_MANIFEST_NAME), 
true);
+    Path regionPath = createRegionManifest();
+
+    try {
+      conf.setInt(SnapshotManifest.SNAPSHOT_MANIFEST_SIZE_LIMIT_CONF_KEY, 128 
* 1024 * 1024);
+      SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
+    } catch (CorruptedSnapshotException e) {
+      fail("fail to test snapshot manifest because region message size is too 
small.");
+    } finally {
+      fs.delete(regionPath, false);
+    }
+  }
+
+  private Path createDataManifest() throws IOException {
     SnapshotDataManifest.Builder dataManifestBuilder =
-      SnapshotDataManifest.newBuilder();
+        SnapshotDataManifest.newBuilder();
     byte[] startKey = null;
     byte[] stopKey = null;
     for (int i = 1; i <= TEST_NUM_REGIONS; i++) {
       stopKey = Bytes.toBytes(String.format("%016d", i));
       HRegionInfo regionInfo = new HRegionInfo(TABLE_NAME, startKey, stopKey, 
false);
       SnapshotRegionManifest.Builder dataRegionManifestBuilder =
-        SnapshotRegionManifest.newBuilder();
+          SnapshotRegionManifest.newBuilder();
 
       for (HColumnDescriptor hcd: builder.getTableDescriptor().getFamilies()) {
         SnapshotRegionManifest.FamilyFiles.Builder family =
@@ -90,7 +135,7 @@ public class TestSnapshotManifest {
         family.setFamilyName(UnsafeByteOperations.unsafeWrap(hcd.getName()));
         for (int j = 0; j < 100; ++j) {
           SnapshotRegionManifest.StoreFile.Builder sfManifest =
-            SnapshotRegionManifest.StoreFile.newBuilder();
+              SnapshotRegionManifest.StoreFile.newBuilder();
           sfManifest.setName(String.format("%032d", i));
           sfManifest.setFileSize((1 + i) * (1 + i) * 1024);
           family.addStoreFiles(sfManifest.build());
@@ -108,37 +153,54 @@ public class TestSnapshotManifest {
         
.setTableSchema(ProtobufUtil.convertToTableSchema(builder.getTableDescriptor()));
 
     SnapshotDataManifest dataManifest = dataManifestBuilder.build();
-    writeDataManifest(dataManifest);
+    return writeDataManifest(dataManifest);
   }
 
-  @After
-  public void tearDown() throws Exception {
-    fs.delete(rootDir,true);
-  }
+  private Path createRegionManifest() throws IOException {
+    byte[] startKey = Bytes.toBytes("AAAAAA");
+    byte[] stopKey = Bytes.toBytes("BBBBBB");
+    HRegionInfo regionInfo = new HRegionInfo(TABLE_NAME, startKey, stopKey, 
false);
+    SnapshotRegionManifest.Builder dataRegionManifestBuilder = 
SnapshotRegionManifest.newBuilder();
+    dataRegionManifestBuilder.setRegionInfo(HRegionInfo.convert(regionInfo));
+
+    for (HColumnDescriptor hcd: builder.getTableDescriptor().getFamilies()) {
+      SnapshotRegionManifest.FamilyFiles.Builder family =
+          SnapshotRegionManifest.FamilyFiles.newBuilder();
+      family.setFamilyName(UnsafeByteOperations.unsafeWrap(hcd.getName()));
+      for (int j = 0; j < TEST_NUM_REGIONFILES; ++j) {
+        SnapshotRegionManifest.StoreFile.Builder sfManifest =
+              SnapshotRegionManifest.StoreFile.newBuilder();
+        sfManifest.setName(String.format("%064d", j));
+        sfManifest.setFileSize(j * 1024);
+        family.addStoreFiles(sfManifest.build());
+      }
+      dataRegionManifestBuilder.addFamilyFiles(family.build());
+    }
 
-  @Test
-  public void testReadSnapshotManifest() throws IOException {
+    SnapshotRegionManifest manifest = dataRegionManifestBuilder.build();
+    Path regionPath = new Path(snapshotDir,
+        SnapshotManifestV2.SNAPSHOT_MANIFEST_PREFIX + 
regionInfo.getEncodedName());
+
+    FSDataOutputStream stream = fs.create(regionPath);
     try {
-      SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
-      fail("fail to test snapshot manifest because message size is too 
small.");
-    } catch (CorruptedSnapshotException cse) {
-      try {
-        conf.setInt(SnapshotManifest.SNAPSHOT_MANIFEST_SIZE_LIMIT_CONF_KEY, 
128 * 1024 * 1024);
-        SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
-        LOG.info("open snapshot manifest succeed.");
-      } catch (CorruptedSnapshotException cse2) {
-        fail("fail to take snapshot because Manifest proto-message too 
large.");
-      }
+      manifest.writeTo(stream);
+    } finally {
+      stream.close();
     }
+
+    return regionPath;
   }
 
-  private void writeDataManifest(final SnapshotDataManifest manifest)
+  private Path writeDataManifest(final SnapshotDataManifest manifest)
       throws IOException {
-    FSDataOutputStream stream = fs.create(new Path(snapshotDir, 
SnapshotManifest.DATA_MANIFEST_NAME));
+    Path dataRegionPath = new Path(snapshotDir, 
SnapshotManifest.DATA_MANIFEST_NAME);
+    FSDataOutputStream stream = fs.create(dataRegionPath);
     try {
       manifest.writeTo(stream);
     } finally {
       stream.close();
     }
+
+    return dataRegionPath;
   }
 }

Reply via email to