/// <exception cref="System.IO.IOException"/> internal static void DoMerge(CheckpointSignature sig, RemoteEditLogManifest manifest , bool loadImage, FSImage dstImage, FSNamesystem dstNamesystem) { NNStorage dstStorage = dstImage.GetStorage(); dstStorage.SetStorageInfo(sig); if (loadImage) { FilePath file = dstStorage.FindImageFile(NNStorage.NameNodeFile.Image, sig.mostRecentCheckpointTxId ); if (file == null) { throw new IOException("Couldn't find image file at txid " + sig.mostRecentCheckpointTxId + " even though it should have " + "just been downloaded"); } dstNamesystem.WriteLock(); try { dstImage.ReloadFromImageFile(file, dstNamesystem); } finally { dstNamesystem.WriteUnlock(); } dstNamesystem.ImageLoadComplete(); } // error simulation code for junit test CheckpointFaultInjector.GetInstance().DuringMerge(); Checkpointer.RollForwardByApplyingLogs(manifest, dstImage, dstNamesystem); // The following has the side effect of purging old fsimages/edit logs. dstImage.SaveFSImageInAllDirs(dstNamesystem, dstImage.GetLastAppliedTxId()); dstStorage.WriteAll(); }
/// <exception cref="System.IO.IOException"/> internal static void DownloadEditsToStorage(Uri fsName, RemoteEditLog log, NNStorage dstStorage) { System.Diagnostics.Debug.Assert(log.GetStartTxId() > 0 && log.GetEndTxId() > 0, "bad log: " + log); string fileid = ImageServlet.GetParamStringForLog(log, dstStorage); string finalFileName = NNStorage.GetFinalizedEditsFileName(log.GetStartTxId(), log .GetEndTxId()); IList <FilePath> finalFiles = dstStorage.GetFiles(NNStorage.NameNodeDirType.Edits, finalFileName); System.Diagnostics.Debug.Assert(!finalFiles.IsEmpty(), "No checkpoint targets."); foreach (FilePath f in finalFiles) { if (f.Exists() && FileUtil.CanRead(f)) { Log.Info("Skipping download of remote edit log " + log + " since it already is stored locally at " + f); return; } else { if (Log.IsDebugEnabled()) { Log.Debug("Dest file: " + f); } } } long milliTime = Time.MonotonicNow(); string tmpFileName = NNStorage.GetTemporaryEditsFileName(log.GetStartTxId(), log. GetEndTxId(), milliTime); IList <FilePath> tmpFiles = dstStorage.GetFiles(NNStorage.NameNodeDirType.Edits, tmpFileName ); GetFileClient(fsName, fileid, tmpFiles, dstStorage, false); Log.Info("Downloaded file " + tmpFiles[0].GetName() + " size " + finalFiles[0].Length () + " bytes."); CheckpointFaultInjector.GetInstance().BeforeEditsRename(); foreach (Storage.StorageDirectory sd in dstStorage.DirIterable(NNStorage.NameNodeDirType .Edits)) { FilePath tmpFile = NNStorage.GetTemporaryEditsFile(sd, log.GetStartTxId(), log.GetEndTxId (), milliTime); FilePath finalizedFile = NNStorage.GetFinalizedEditsFile(sd, log.GetStartTxId(), log.GetEndTxId()); if (Log.IsDebugEnabled()) { Log.Debug("Renaming " + tmpFile + " to " + finalizedFile); } bool success = tmpFile.RenameTo(finalizedFile); if (!success) { Log.Warn("Unable to rename edits file from " + tmpFile + " to " + finalizedFile); } } }
/// <exception cref="System.IO.IOException"/> private static void CopyFileToStream(OutputStream @out, FilePath localfile, FileInputStream infile, DataTransferThrottler throttler, Canceler canceler) { byte[] buf = new byte[HdfsConstants.IoFileBufferSize]; try { CheckpointFaultInjector.GetInstance().AboutToSendFile(localfile); if (CheckpointFaultInjector.GetInstance().ShouldSendShortFile(localfile)) { // Test sending image shorter than localfile long len = localfile.Length(); buf = new byte[(int)Math.Min(len / 2, HdfsConstants.IoFileBufferSize)]; // This will read at most half of the image // and the rest of the image will be sent over the wire infile.Read(buf); } int num = 1; while (num > 0) { if (canceler != null && canceler.IsCancelled()) { throw new SaveNamespaceCancelledException(canceler.GetCancellationReason()); } num = infile.Read(buf); if (num <= 0) { break; } if (CheckpointFaultInjector.GetInstance().ShouldCorruptAByte(localfile)) { // Simulate a corrupted byte on the wire Log.Warn("SIMULATING A CORRUPT BYTE IN IMAGE TRANSFER!"); buf[0]++; } @out.Write(buf, 0, num); if (throttler != null) { throttler.Throttle(num, canceler); } } } catch (EofException) { Log.Info("Connection closed by client"); @out = null; } finally { // so we don't close in the finally if (@out != null) { @out.Close(); } } }
/// <exception cref="System.Exception"/> public Void Run() { if (parsedParams.IsGetImage()) { long txid = parsedParams.GetTxId(); FilePath imageFile = null; string errorMessage = "Could not find image"; if (parsedParams.ShouldFetchLatest()) { imageFile = nnImage.GetStorage().GetHighestFsImageName(); } else { errorMessage += " with txid " + txid; imageFile = nnImage.GetStorage().GetFsImage(txid, EnumSet.Of(NNStorage.NameNodeFile .Image, NNStorage.NameNodeFile.ImageRollback)); } if (imageFile == null) { throw new IOException(errorMessage); } CheckpointFaultInjector.GetInstance().BeforeGetImageSetsHeaders(); long start = Time.MonotonicNow(); this.ServeFile(imageFile); if (metrics != null) { long elapsed = Time.MonotonicNow() - start; metrics.AddGetImage(elapsed); } } else { if (parsedParams.IsGetEdit()) { long startTxId = parsedParams.GetStartTxId(); long endTxId = parsedParams.GetEndTxId(); FilePath editFile = nnImage.GetStorage().FindFinalizedEditsFile(startTxId, endTxId ); long start = Time.MonotonicNow(); this.ServeFile(editFile); if (metrics != null) { long elapsed = Time.MonotonicNow() - start; metrics.AddGetEdit(elapsed); } } } return(null); }
public virtual bool DoCheckpoint() { checkpointImage.EnsureCurrentDirExists(); NNStorage dstStorage = checkpointImage.GetStorage(); // Tell the namenode to start logging transactions in a new edit file // Returns a token that would be used to upload the merged image. CheckpointSignature sig = namenode.RollEditLog(); bool loadImage = false; bool isFreshCheckpointer = (checkpointImage.GetNamespaceID() == 0); bool isSameCluster = (dstStorage.VersionSupportsFederation(NameNodeLayoutVersion. Features) && sig.IsSameCluster(checkpointImage)) || (!dstStorage.VersionSupportsFederation (NameNodeLayoutVersion.Features) && sig.NamespaceIdMatches(checkpointImage)); if (isFreshCheckpointer || (isSameCluster && !sig.StorageVersionMatches(checkpointImage .GetStorage()))) { // if we're a fresh 2NN, or if we're on the same cluster and our storage // needs an upgrade, just take the storage info from the server. dstStorage.SetStorageInfo(sig); dstStorage.SetClusterID(sig.GetClusterID()); dstStorage.SetBlockPoolID(sig.GetBlockpoolID()); loadImage = true; } sig.ValidateStorageInfo(checkpointImage); // error simulation code for junit test CheckpointFaultInjector.GetInstance().AfterSecondaryCallsRollEditLog(); RemoteEditLogManifest manifest = namenode.GetEditLogManifest(sig.mostRecentCheckpointTxId + 1); // Fetch fsimage and edits. Reload the image if previous merge failed. loadImage |= DownloadCheckpointFiles(fsName, checkpointImage, sig, manifest) | checkpointImage .HasMergeError(); try { DoMerge(sig, manifest, loadImage, checkpointImage, namesystem); } catch (IOException ioe) { // A merge error occurred. The in-memory file system state may be // inconsistent, so the image and edits need to be reloaded. checkpointImage.SetMergeError(); throw; } // Clear any error since merge was successful. checkpointImage.ClearMergeError(); // // Upload the new image into the NameNode. Then tell the Namenode // to make this new uploaded image as the most current image. // long txid = checkpointImage.GetLastAppliedTxId(); TransferFsImage.UploadImageFromStorage(fsName, conf, dstStorage, NNStorage.NameNodeFile .Image, txid); // error simulation code for junit test CheckpointFaultInjector.GetInstance().AfterSecondaryUploadsNewImage(); Log.Warn("Checkpoint done. New Image Size: " + dstStorage.GetFsImageName(txid).Length ()); if (legacyOivImageDir != null && !legacyOivImageDir.IsEmpty()) { try { checkpointImage.SaveLegacyOIVImage(namesystem, legacyOivImageDir, new Canceler()); } catch (IOException e) { Log.Warn("Failed to write legacy OIV image: ", e); } } return(loadImage); }