Explorar el Código

HDFS-3044. svn merge -c 1304063 from trunk

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1304067 13f79535-47bb-0310-9956-ffa450edef68
Eli Collins hace 13 años
padre
commit
44322a37c8

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

@@ -156,6 +156,9 @@ Release 0.23.3 - UNRELEASED
     HDFS-309. FSEditLog should log progress during replay. (Sho Shimauchi
     HDFS-309. FSEditLog should log progress during replay. (Sho Shimauchi
     via todd)
     via todd)
 
 
+    HDFS-3044. fsck move should be non-destructive by default.
+    (Colin Patrick McCabe via eli)
+
   OPTIMIZATIONS
   OPTIMIZATIONS
 
 
     HDFS-2477. Optimize computing the diff between a block report and the
     HDFS-2477. Optimize computing the diff between a block report and the

+ 37 - 29
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NamenodeFsck.java

@@ -85,13 +85,6 @@ public class NamenodeFsck {
   public static final String NONEXISTENT_STATUS = "does not exist";
   public static final String NONEXISTENT_STATUS = "does not exist";
   public static final String FAILURE_STATUS = "FAILED";
   public static final String FAILURE_STATUS = "FAILED";
   
   
-  /** Don't attempt any fixing . */
-  public static final int FIXING_NONE = 0;
-  /** Move corrupted files to /lost+found . */
-  public static final int FIXING_MOVE = 1;
-  /** Delete corrupted files. */
-  public static final int FIXING_DELETE = 2;
-  
   private final NameNode namenode;
   private final NameNode namenode;
   private final NetworkTopology networktopology;
   private final NetworkTopology networktopology;
   private final int totalDatanodes;
   private final int totalDatanodes;
@@ -107,7 +100,21 @@ public class NamenodeFsck {
   private boolean showLocations = false;
   private boolean showLocations = false;
   private boolean showRacks = false;
   private boolean showRacks = false;
   private boolean showCorruptFileBlocks = false;
   private boolean showCorruptFileBlocks = false;
-  private int fixing = FIXING_NONE;
+
+  /** 
+   * True if the user specified the -move option.
+   *
+   * Whe this option is in effect, we will copy salvaged blocks into the lost
+   * and found. */
+  private boolean doMove = false;
+
+  /** 
+   * True if the user specified the -delete option.
+   *
+   * Whe this option is in effect, we will delete corrupted files.
+   */
+  private boolean doDelete = false;
+
   private String path = "/";
   private String path = "/";
 
 
   // We return back N files that are corrupt; the list of files returned is
   // We return back N files that are corrupt; the list of files returned is
@@ -144,8 +151,8 @@ public class NamenodeFsck {
     for (Iterator<String> it = pmap.keySet().iterator(); it.hasNext();) {
     for (Iterator<String> it = pmap.keySet().iterator(); it.hasNext();) {
       String key = it.next();
       String key = it.next();
       if (key.equals("path")) { this.path = pmap.get("path")[0]; }
       if (key.equals("path")) { this.path = pmap.get("path")[0]; }
-      else if (key.equals("move")) { this.fixing = FIXING_MOVE; }
-      else if (key.equals("delete")) { this.fixing = FIXING_DELETE; }
+      else if (key.equals("move")) { this.doMove = true; }
+      else if (key.equals("delete")) { this.doDelete = true; }
       else if (key.equals("files")) { this.showFiles = true; }
       else if (key.equals("files")) { this.showFiles = true; }
       else if (key.equals("blocks")) { this.showBlocks = true; }
       else if (key.equals("blocks")) { this.showBlocks = true; }
       else if (key.equals("locations")) { this.showLocations = true; }
       else if (key.equals("locations")) { this.showLocations = true; }
@@ -377,16 +384,20 @@ public class NamenodeFsck {
             + " blocks of total size " + missize + " B.");
             + " blocks of total size " + missize + " B.");
       }
       }
       res.corruptFiles++;
       res.corruptFiles++;
-      switch(fixing) {
-      case FIXING_NONE:
-        break;
-      case FIXING_MOVE:
-        if (!isOpen)
-          lostFoundMove(parent, file, blocks);
-        break;
-      case FIXING_DELETE:
-        if (!isOpen)
-          namenode.getRpcServer().delete(path, true);
+      try {
+        if (doMove) {
+          if (!isOpen) {
+            copyBlocksToLostFound(parent, file, blocks);
+          }
+        }
+        if (doDelete) {
+          if (!isOpen) {
+            LOG.warn("\n - deleting corrupted file " + path);
+            namenode.getRpcServer().delete(path, true);
+          }
+        }
+      } catch (IOException e) {
+        LOG.error("error processing " + path + ": " + e.toString());
       }
       }
     }
     }
     if (showFiles) {
     if (showFiles) {
@@ -401,8 +412,8 @@ public class NamenodeFsck {
     }
     }
   }
   }
   
   
-  private void lostFoundMove(String parent, HdfsFileStatus file, LocatedBlocks blocks)
-    throws IOException {
+  private void copyBlocksToLostFound(String parent, HdfsFileStatus file,
+        LocatedBlocks blocks) throws IOException {
     final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf);
     final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf);
     try {
     try {
     if (!lfInited) {
     if (!lfInited) {
@@ -436,12 +447,10 @@ public class NamenodeFsck {
         }
         }
         if (fos == null) {
         if (fos == null) {
           fos = dfs.create(target + "/" + chain, true);
           fos = dfs.create(target + "/" + chain, true);
-          if (fos != null) chain++;
+          if (fos != null)
+            chain++;
           else {
           else {
-            LOG.warn(errmsg + ": could not store chain " + chain);
-            // perhaps we should bail out here...
-            // return;
-            continue;
+            throw new IOException(errmsg + ": could not store chain " + chain);
           }
           }
         }
         }
         
         
@@ -458,8 +467,7 @@ public class NamenodeFsck {
         }
         }
       }
       }
       if (fos != null) fos.close();
       if (fos != null) fos.close();
-      LOG.warn("\n - moved corrupted file " + fullName + " to /lost+found");
-      dfs.delete(fullName, true);
+      LOG.warn("\n - copied corrupted file " + fullName + " to /lost+found");
     }  catch (Exception e) {
     }  catch (Exception e) {
       e.printStackTrace();
       e.printStackTrace();
       LOG.warn(errmsg + ": " + e.getMessage());
       LOG.warn(errmsg + ": " + e.getMessage());

+ 17 - 3
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFsck.java

@@ -227,7 +227,7 @@ public class TestFsck extends TestCase {
     }
     }
   }
   }
 
 
-  public void testFsckMove() throws Exception {
+  public void testFsckMoveAndDelete() throws Exception {
     DFSTestUtil util = new DFSTestUtil("TestFsck", 5, 3, 8*1024);
     DFSTestUtil util = new DFSTestUtil("TestFsck", 5, 3, 8*1024);
     MiniDFSCluster cluster = null;
     MiniDFSCluster cluster = null;
     FileSystem fs = null;
     FileSystem fs = null;
@@ -248,8 +248,9 @@ public class TestFsck extends TestCase {
       String[] fileNames = util.getFileNames(topDir);
       String[] fileNames = util.getFileNames(topDir);
       DFSClient dfsClient = new DFSClient(new InetSocketAddress("localhost",
       DFSClient dfsClient = new DFSClient(new InetSocketAddress("localhost",
                                           cluster.getNameNodePort()), conf);
                                           cluster.getNameNodePort()), conf);
+      String corruptFileName = fileNames[0];
       ExtendedBlock block = dfsClient.getNamenode().getBlockLocations(
       ExtendedBlock block = dfsClient.getNamenode().getBlockLocations(
-          fileNames[0], 0, Long.MAX_VALUE).get(0).getBlock();
+          corruptFileName, 0, Long.MAX_VALUE).get(0).getBlock();
       for (int i=0; i<4; i++) {
       for (int i=0; i<4; i++) {
         File blockFile = MiniDFSCluster.getBlockFile(i, block);
         File blockFile = MiniDFSCluster.getBlockFile(i, block);
         if(blockFile != null && blockFile.exists()) {
         if(blockFile != null && blockFile.exists()) {
@@ -267,8 +268,21 @@ public class TestFsck extends TestCase {
         outStr = runFsck(conf, 1, false, "/");
         outStr = runFsck(conf, 1, false, "/");
       } 
       } 
       
       
+      // After a fsck -move, the corrupted file should still exist.
+      outStr = runFsck(conf, 1, true, "/", "-move" );
+      assertTrue(outStr.contains(NamenodeFsck.CORRUPT_STATUS));
+      String[] newFileNames = util.getFileNames(topDir);
+      boolean found = false;
+      for (String f : newFileNames) {
+        if (f.equals(corruptFileName)) {
+          found = true;
+          break;
+        }
+      }
+      assertTrue(found);
+
       // Fix the filesystem by moving corrupted files to lost+found
       // Fix the filesystem by moving corrupted files to lost+found
-      outStr = runFsck(conf, 1, true, "/", "-move");
+      outStr = runFsck(conf, 1, true, "/", "-move", "-delete");
       assertTrue(outStr.contains(NamenodeFsck.CORRUPT_STATUS));
       assertTrue(outStr.contains(NamenodeFsck.CORRUPT_STATUS));
       
       
       // Check to make sure we have healthy filesystem
       // Check to make sure we have healthy filesystem