You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2011/08/18 21:41:47 UTC

svn commit: r1159375 - in /hbase/trunk: CHANGES.txt src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java src/main/java/org/apache/hadoop/hbase/util/FSUtils.java src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java

Author: tedyu
Date: Thu Aug 18 19:41:47 2011
New Revision: 1159375

URL: http://svn.apache.org/viewvc?rev=1159375&view=rev
Log:
HBASE-4175 Fix FSUtils.createTableDescriptor()

Added:
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java
Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1159375&r1=1159374&r2=1159375&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Thu Aug 18 19:41:47 2011
@@ -202,6 +202,7 @@ Release 0.91.0 - Unreleased
    HBASE-2399  Forced splits only act on the first family in a table (Ming Ma)
    HBASE-4211  Do init-sizing of the StringBuilder making a ServerName
                (Benoît Sigoure)
+   HBASE-4175  Fix FSUtils.createTableDescriptor() (Ramkrishna)
 
   IMPROVEMENTS
    HBASE-3290  Max Compaction Size (Nicolas Spiegelberg via Stack)  

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java?rev=1159375&r1=1159374&r2=1159375&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java Thu Aug 18 19:41:47 2011
@@ -410,11 +410,13 @@ public class MasterFileSystem {
     return tableInfoPath;
   }
 
-    /**
+  /**
    * Create new HTableDescriptor in HDFS.
+   * 
    * @param htableDescriptor
    */
-  public void createTableDescriptor(HTableDescriptor htableDescriptor) {
+  public void createTableDescriptor(HTableDescriptor htableDescriptor)
+      throws IOException {
     FSUtils.createTableDescriptor(htableDescriptor, conf);
   }
 
@@ -478,4 +480,4 @@ public class MasterFileSystem {
     this.services.getTableDescriptors().add(htd);
     return htd;
   }
-}
\ No newline at end of file
+}

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java?rev=1159375&r1=1159374&r2=1159375&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java Thu Aug 18 19:41:47 2011
@@ -938,42 +938,72 @@ public abstract class FSUtils {
   }
 
   /**
-   * Create new HTableDescriptor in HDFS.  Happens when we are creating table.
+   * Create new HTableDescriptor in HDFS. Happens when we are creating table.
+   * 
+   * @param htableDescriptor
+   * @param conf
+   */
+  public static boolean createTableDescriptor(
+      HTableDescriptor htableDescriptor, Configuration conf) throws IOException {
+    return createTableDescriptor(htableDescriptor, conf, false);
+  }
+
   /**
+   * Create new HTableDescriptor in HDFS. Happens when we are creating table. If
+   * forceCreation is true then even if previous table descriptor is present it
+   * will be overwritten
+   * 
    * @param htableDescriptor
    * @param conf
+   * @param forceCreation
    */
-  public static void createTableDescriptor(HTableDescriptor htableDescriptor,
-      Configuration conf) {
-    try {
-      FileSystem fs = getCurrentFileSystem(conf);
-      createTableDescriptor(fs, getRootDir(conf), htableDescriptor);
-    } catch(IOException ioe) {
-      LOG.info("IOException while trying to create tableInfo in HDFS", ioe);
-    }
+  public static boolean createTableDescriptor(
+      HTableDescriptor htableDescriptor, Configuration conf,
+      boolean forceCreation) throws IOException {
+    FileSystem fs = getCurrentFileSystem(conf);
+    return createTableDescriptor(fs, getRootDir(conf), htableDescriptor,
+        forceCreation);
   }
 
   /**
+   * Create new HTableDescriptor in HDFS. Happens when we are creating table.
+   * 
    * @param fs
    * @param htableDescriptor
    * @param rootdir
    */
-  public static void createTableDescriptor(FileSystem fs,
-      Path rootdir, HTableDescriptor htableDescriptor) {
-    try {
-      Path tableInfoPath =
-        getTableInfoPath(rootdir, htableDescriptor.getNameAsString());
-      LOG.info("Current tableInfoPath = " + tableInfoPath) ;
-      if (fs.exists(tableInfoPath) &&
-          fs.getFileStatus(tableInfoPath).getLen() > 0) {
+  public static boolean createTableDescriptor(FileSystem fs, Path rootdir,
+      HTableDescriptor htableDescriptor) throws IOException {
+    return createTableDescriptor(fs, rootdir, htableDescriptor, false);
+  }
+
+  /**
+   * Create new HTableDescriptor in HDFS. Happens when we are creating table. If
+   * forceCreation is true then even if previous table descriptor is present it
+   * will be overwritten
+   * 
+   * @param fs
+   * @param htableDescriptor
+   * @param rootdir
+   * @param forceCreation
+   */
+  public static boolean createTableDescriptor(FileSystem fs, Path rootdir,
+      HTableDescriptor htableDescriptor, boolean forceCreation)
+      throws IOException {
+    Path tableInfoPath = getTableInfoPath(rootdir, htableDescriptor
+        .getNameAsString());
+    LOG.info("Current tableInfoPath = " + tableInfoPath);
+    if (!forceCreation) {
+      if (fs.exists(tableInfoPath)
+          && fs.getFileStatus(tableInfoPath).getLen() > 0) {
         LOG.info("TableInfo already exists.. Skipping creation");
-        return;
+        return false;
       }
-      writeTableDescriptor(fs, htableDescriptor,
-        getTablePath(rootdir, htableDescriptor.getNameAsString()));
-    } catch(IOException ioe) {
-      LOG.info("IOException while trying to create tableInfo in HDFS", ioe);
     }
+    writeTableDescriptor(fs, htableDescriptor, getTablePath(rootdir,
+        htableDescriptor.getNameAsString()), forceCreation);
+
+    return true;
   }
 
   /**
@@ -990,25 +1020,42 @@ public abstract class FSUtils {
 
   /**
    * Called when we are creating a table to write out the tables' descriptor.
+   * 
    * @param fs
    * @param hTableDescriptor
    * @param tableDir
    * @throws IOException
    */
   private static void writeTableDescriptor(FileSystem fs,
-      HTableDescriptor hTableDescriptor, Path tableDir)
-  throws IOException {
+      HTableDescriptor hTableDescriptor, Path tableDir, boolean forceCreation)
+      throws IOException {
     // Create in tmpdir and then move into place in case we crash after
-    // create but before close.  If we don't successfully close the file,
+    // create but before close. If we don't successfully close the file,
     // subsequent region reopens will fail the below because create is
     // registered in NN.
     Path tableInfoPath = new Path(tableDir, HConstants.TABLEINFO_NAME);
-    Path tmpPath = new Path(new Path(tableDir,".tmp"), HConstants.TABLEINFO_NAME);
+    Path tmpPath = new Path(new Path(tableDir, ".tmp"),
+        HConstants.TABLEINFO_NAME);
     LOG.info("TableInfoPath = " + tableInfoPath + " tmpPath = " + tmpPath);
-    writeHTD(fs, tmpPath, hTableDescriptor);
+    try {
+      writeHTD(fs, tmpPath, hTableDescriptor);
+    } catch (IOException e) {
+      LOG.error("Unable to write the tabledescriptor in the path" + tmpPath
+          + ".", e);
+      throw e;
+    }
+    if (forceCreation) {
+      if (!fs.delete(tableInfoPath, false)) {
+        String errMsg = "Unable to delete " + tableInfoPath
+            + " while forcefully writing the table descriptor.";
+        LOG.error(errMsg);
+        throw new IOException(errMsg);
+      }
+    }
     if (!fs.rename(tmpPath, tableInfoPath)) {
-      throw new IOException("Unable to rename " + tmpPath + " to " +
-        tableInfoPath);
+      String errMsg = "Unable to rename " + tmpPath + " to " + tableInfoPath;
+      LOG.error(errMsg);
+      throw new IOException(errMsg);
     } else {
       LOG.info("TableDescriptor stored. TableInfoPath = " + tableInfoPath);
     }

Added: hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java?rev=1159375&view=auto
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java (added)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestFSTableDescriptorForceCreation.java Thu Aug 18 19:41:47 2011
@@ -0,0 +1,84 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.util.FSTableDescriptors;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestFSTableDescriptorForceCreation {
+  private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+
+  @BeforeClass
+  public static void setUpCluster() throws Exception {
+    UTIL.startMiniDFSCluster(1);
+  }
+
+  @AfterClass
+  public static void shutDownCluster() throws Exception {
+    UTIL.shutdownMiniDFSCluster();
+  }
+
+  @Test
+  public void testShouldCreateNewTableDescriptorIfForcefulCreationIsFalse()
+      throws IOException {
+    final String name = "newTable2";
+    FileSystem fs = FileSystem.get(UTIL.getConfiguration());
+    Path rootdir = new Path(fs.getWorkingDirectory(), name);
+    HTableDescriptor htd = new HTableDescriptor(name);
+    assertTrue("Should create new table descriptor", FSUtils
+        .createTableDescriptor(fs, rootdir, htd, false));
+  }
+
+  @Test
+  public void testShouldNotCreateTheSameTableDescriptorIfForcefulCreationIsFalse()
+      throws IOException {
+    final String name = "testAlreadyExists";
+    FileSystem fs = FileSystem.get(UTIL.getConfiguration());
+    // Cleanup old tests if any detrius laying around.
+    Path rootdir = new Path(fs.getWorkingDirectory(), name);
+    TableDescriptors htds = new FSTableDescriptors(fs, rootdir);
+    HTableDescriptor htd = new HTableDescriptor(name);
+    htds.add(htd);
+    assertFalse("Should not create new table descriptor", FSUtils
+        .createTableDescriptor(fs, rootdir, htd, false));
+  }
+
+  @Test
+  public void testShouldAllowForcefulCreationOfAlreadyExistingTableDescriptor()
+      throws Exception {
+    final String name = "createNewTableNew2";
+    FileSystem fs = FileSystem.get(UTIL.getConfiguration());
+    Path rootdir = new Path(fs.getWorkingDirectory(), name);
+    HTableDescriptor htd = new HTableDescriptor(name);
+    FSUtils.createTableDescriptor(fs, rootdir, htd, false);
+    assertTrue("Should create new table descriptor", FSUtils
+        .createTableDescriptor(fs, rootdir, htd, true));
+  }
+}