You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by sh...@apache.org on 2009/05/15 23:03:01 UTC
svn commit: r775338 - in /hadoop/core/trunk: CHANGES.txt
src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java
src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java
Author: shv
Date: Fri May 15 21:03:00 2009
New Revision: 775338
URL: http://svn.apache.org/viewvc?rev=775338&view=rev
Log:
HADOOP-5314. Prevent unnecessary saving of the file system image during name-node startup. Contributed by Jakob Homan.
Modified:
hadoop/core/trunk/CHANGES.txt
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java
Modified: hadoop/core/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/CHANGES.txt?rev=775338&r1=775337&r2=775338&view=diff
==============================================================================
--- hadoop/core/trunk/CHANGES.txt (original)
+++ hadoop/core/trunk/CHANGES.txt Fri May 15 21:03:00 2009
@@ -599,6 +599,9 @@
HADOOP-5845. Build successful despite test failure on test-core target.
(sharad)
+ HADOOP-5314. Prevent unnecessary saving of the file system image during
+ name-node startup. (Jakob Homan via shv)
+
Release 0.20.1 - Unreleased
INCOMPATIBLE CHANGES
Modified: hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java?rev=775338&r1=775337&r2=775338&view=diff
==============================================================================
--- hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java (original)
+++ hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/common/Storage.java Fri May 15 21:03:00 2009
@@ -159,7 +159,7 @@
/**
* Return default iterator
- * This iterator returns all entires of storageDirs
+ * This iterator returns all entries in storageDirs
*/
public Iterator<StorageDirectory> dirIterator() {
return dirIterator(null);
@@ -167,7 +167,7 @@
/**
* Return iterator based on Storage Directory Type
- * This iterator selects entires of storageDirs of type dirType and returns
+ * This iterator selects entries in storageDirs of type dirType and returns
* them via the Iterator
*/
public Iterator<StorageDirectory> dirIterator(StorageDirType dirType) {
Modified: hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java?rev=775338&r1=775337&r2=775338&view=diff
==============================================================================
--- hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java (original)
+++ hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSImage.java Fri May 15 21:03:00 2009
@@ -28,42 +28,41 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.Random;
-import java.util.Map;
-import java.util.HashMap;
-import java.lang.Math;
-import java.nio.ByteBuffer;
+import java.util.Set;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.fs.permission.FsPermission;
-import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.protocol.DatanodeID;
import org.apache.hadoop.hdfs.protocol.FSConstants;
+import org.apache.hadoop.hdfs.server.common.InconsistentFSStateException;
+import org.apache.hadoop.hdfs.server.common.Storage;
+import org.apache.hadoop.hdfs.server.common.StorageInfo;
+import org.apache.hadoop.hdfs.server.common.UpgradeManager;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.NamenodeRole;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.NodeType;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
-import org.apache.hadoop.io.DeprecatedUTF8;
-import org.apache.hadoop.io.Writable;
-import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.hdfs.server.namenode.BlocksMap.BlockInfo;
-import org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream;
import org.apache.hadoop.hdfs.server.protocol.CheckpointCommand;
import org.apache.hadoop.hdfs.server.protocol.NamenodeCommand;
import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocol;
import org.apache.hadoop.hdfs.server.protocol.NamenodeRegistration;
-import org.apache.hadoop.hdfs.server.common.InconsistentFSStateException;
-import org.apache.hadoop.hdfs.server.common.Storage;
-import org.apache.hadoop.hdfs.server.common.StorageInfo;
-import org.apache.hadoop.hdfs.server.common.UpgradeManager;
+import org.apache.hadoop.io.DeprecatedUTF8;
+import org.apache.hadoop.io.Writable;
/**
* FSImage handles checkpointing and logging of the namespace edits.
@@ -362,7 +361,7 @@
case NON_EXISTENT:
// name-node fails if any of the configured storage dirs are missing
throw new InconsistentFSStateException(sd.getRoot(),
- "storage directory does not exist or is not accessible.");
+ "storage directory does not exist or is not accessible.");
case NOT_FORMATTED:
break;
case NORMAL:
@@ -396,9 +395,9 @@
&& layoutVersion < LAST_PRE_UPGRADE_LAYOUT_VERSION
&& layoutVersion != FSConstants.LAYOUT_VERSION)
throw new IOException(
- "\nFile system image contains an old layout version " + layoutVersion
- + ".\nAn upgrade to version " + FSConstants.LAYOUT_VERSION
- + " is required.\nPlease restart NameNode with -upgrade option.");
+ "\nFile system image contains an old layout version " + layoutVersion
+ + ".\nAn upgrade to version " + FSConstants.LAYOUT_VERSION
+ + " is required.\nPlease restart NameNode with -upgrade option.");
// check whether distributed upgrade is reguired and/or should be continued
verifyDistributedUpgradeProgress(startOpt);
@@ -628,6 +627,13 @@
this.checkpointTime = readCheckpointTime(sd);
}
+ /**
+ * Determine the checkpoint time of the specified StorageDirectory
+ *
+ * @param sd StorageDirectory to check
+ * @return If file exists and can be read, last checkpoint time. If not, 0L.
+ * @throws IOException On errors processing file pointed to by sd
+ */
long readCheckpointTime(StorageDirectory sd) throws IOException {
File timeFile = getImageFile(sd, NameNodeFile.TIME);
long timeStamp = 0L;
@@ -844,51 +850,65 @@
* @throws IOException
*/
boolean loadFSImage() throws IOException {
- // Now check all curFiles and see which is the newest
long latestNameCheckpointTime = Long.MIN_VALUE;
long latestEditsCheckpointTime = Long.MIN_VALUE;
- StorageDirectory latestNameSD = null;
- StorageDirectory latestEditsSD = null;
boolean needToSave = false;
isUpgradeFinalized = true;
+
+ StorageDirectory latestNameSD = null;
+ StorageDirectory latestEditsSD = null;
+
Collection<String> imageDirs = new ArrayList<String>();
Collection<String> editsDirs = new ArrayList<String>();
+
+ // Set to determine if all of storageDirectories share the same checkpoint
+ Set<Long> checkpointTimes = new HashSet<Long>();
+
+ // Process each of the storage directories to find the pair of
+ // newest image file and edit file
for (Iterator<StorageDirectory> it = dirIterator(); it.hasNext();) {
StorageDirectory sd = it.next();
+
+ // Was the file just formatted?
if (!sd.getVersionFile().exists()) {
needToSave |= true;
- continue; // some of them might have just been formatted
+ continue;
}
- boolean imageExists = false, editsExists = false;
+
+ boolean imageExists = false;
+ boolean editsExists = false;
+
+ // Determine if sd is image, edits or both
if (sd.getStorageDirType().isOfType(NameNodeDirType.IMAGE)) {
imageExists = getImageFile(sd, NameNodeFile.IMAGE).exists();
imageDirs.add(sd.getRoot().getCanonicalPath());
}
+
if (sd.getStorageDirType().isOfType(NameNodeDirType.EDITS)) {
editsExists = getImageFile(sd, NameNodeFile.EDITS).exists();
editsDirs.add(sd.getRoot().getCanonicalPath());
}
checkpointTime = readCheckpointTime(sd);
- if ((checkpointTime != Long.MIN_VALUE) &&
- ((checkpointTime != latestNameCheckpointTime) ||
- (checkpointTime != latestEditsCheckpointTime))) {
- // Force saving of new image if checkpoint time
- // is not same in all of the storage directories.
- needToSave |= true;
- }
+
+ checkpointTimes.add(checkpointTime);
+
if (sd.getStorageDirType().isOfType(NameNodeDirType.IMAGE) &&
(latestNameCheckpointTime < checkpointTime) && imageExists) {
latestNameCheckpointTime = checkpointTime;
latestNameSD = sd;
}
+
if (sd.getStorageDirType().isOfType(NameNodeDirType.EDITS) &&
(latestEditsCheckpointTime < checkpointTime) && editsExists) {
latestEditsCheckpointTime = checkpointTime;
latestEditsSD = sd;
}
+
+ // check that we have a valid, non-default checkpointTime
if (checkpointTime <= 0L)
needToSave |= true;
+
// set finalized flag
isUpgradeFinalized = isUpgradeFinalized && !sd.getPreviousDir().exists();
}
@@ -901,10 +921,13 @@
// Make sure we are loading image and edits from same checkpoint
if (latestNameCheckpointTime != latestEditsCheckpointTime)
- throw new IOException("Inconsitent storage detected, " +
+ throw new IOException("Inconsistent storage detected, " +
"name and edits storage do not match");
- // Recover from previous interrrupted checkpoint if any
+ // If there was more than one checkpointTime recorded we should save
+ needToSave |= checkpointTimes.size() != 1;
+
+ // Recover from previous interrupted checkpoint, if any
needToSave |= recoverInterruptedCheckpoint(latestNameSD, latestEditsSD);
long startTime = FSNamesystem.now();
@@ -920,12 +943,16 @@
// Load latest edits
needToSave |= (loadFSEdits(latestEditsSD) > 0);
+
+ assert editLog != null : "editLog must be initialized";
+ if(!editLog.isOpen())
+ editLog.open();
return needToSave;
}
/**
- * Load in the filesystem imagefrom file. It's a big list of
+ * Load in the filesystem image from file. It's a big list of
* filenames and blocks. Return whether we should
* "re-save" and consolidate the edit-logs
*/
@@ -1099,16 +1126,20 @@
int numEdits = 0;
EditLogFileInputStream edits =
new EditLogFileInputStream(getImageFile(sd, NameNodeFile.EDITS));
+
numEdits = editLog.loadFSEdits(edits);
edits.close();
File editsNew = getImageFile(sd, NameNodeFile.EDITS_NEW);
+
if (editsNew.exists() && editsNew.length() > 0) {
edits = new EditLogFileInputStream(editsNew);
numEdits += editLog.loadFSEdits(edits);
edits.close();
}
+
// update the counts.
getFSNamesystem().dir.updateCountForINodeWithQuota();
+
return numEdits;
}