Beispiel #1
0
 internal static string GetParamStringForLog(RemoteEditLog log, StorageInfo remoteStorageInfo
                                             )
 {
     return("getedit=1&" + StartTxidParam + "=" + log.GetStartTxId() + "&" + EndTxidParam
            + "=" + log.GetEndTxId() + "&" + StorageinfoParam + "=" + remoteStorageInfo.ToColonSeparatedString
                ());
 }
Beispiel #2
0
        public virtual void TestConvertRemoteEditLog()
        {
            RemoteEditLog l = new RemoteEditLog(1, 100);

            HdfsProtos.RemoteEditLogProto lProto = PBHelper.Convert(l);
            RemoteEditLog l1 = PBHelper.Convert(lProto);

            Compare(l, l1);
        }
Beispiel #3
0
        /// <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);
                }
            }
        }
Beispiel #4
0
 /// <summary>Return a manifest of what finalized edit logs are available.</summary>
 /// <remarks>
 /// Return a manifest of what finalized edit logs are available. All available
 /// edit logs are returned starting from the transaction id passed. If
 /// 'fromTxId' falls in the middle of a log, that log is returned as well.
 /// </remarks>
 /// <param name="fromTxId">Starting transaction id to read the logs.</param>
 /// <returns>RemoteEditLogManifest object.</returns>
 public virtual RemoteEditLogManifest GetEditLogManifest(long fromTxId)
 {
     lock (this)
     {
         // Collect RemoteEditLogs available from each FileJournalManager
         IList <RemoteEditLog> allLogs = Lists.NewArrayList();
         foreach (JournalSet.JournalAndStream j in journals)
         {
             if (j.GetManager() is FileJournalManager)
             {
                 FileJournalManager fjm = (FileJournalManager)j.GetManager();
                 try
                 {
                     Sharpen.Collections.AddAll(allLogs, fjm.GetRemoteEditLogs(fromTxId, false));
                 }
                 catch (Exception t)
                 {
                     Log.Warn("Cannot list edit logs in " + fjm, t);
                 }
             }
         }
         // Group logs by their starting txid
         ImmutableListMultimap <long, RemoteEditLog> logsByStartTxId = Multimaps.Index(allLogs
                                                                                       , RemoteEditLog.GetStartTxid);
         long curStartTxId          = fromTxId;
         IList <RemoteEditLog> logs = Lists.NewArrayList();
         while (true)
         {
             ImmutableList <RemoteEditLog> logGroup = ((ImmutableList <RemoteEditLog>)logsByStartTxId
                                                       .Get(curStartTxId));
             if (logGroup.IsEmpty())
             {
                 // we have a gap in logs - for example because we recovered some old
                 // storage directory with ancient logs. Clear out any logs we've
                 // accumulated so far, and then skip to the next segment of logs
                 // after the gap.
                 ICollection <long> startTxIds = Sets.NewTreeSet(logsByStartTxId.KeySet());
                 startTxIds = startTxIds.TailSet(curStartTxId);
                 if (startTxIds.IsEmpty())
                 {
                     break;
                 }
                 else
                 {
                     if (Log.IsDebugEnabled())
                     {
                         Log.Debug("Found gap in logs at " + curStartTxId + ": " + "not returning previous logs in manifest."
                                   );
                     }
                     logs.Clear();
                     curStartTxId = startTxIds.First();
                     continue;
                 }
             }
             // Find the one that extends the farthest forward
             RemoteEditLog bestLog = Sharpen.Collections.Max(logGroup);
             logs.AddItem(bestLog);
             // And then start looking from after that point
             curStartTxId = bestLog.GetEndTxId() + 1;
         }
         RemoteEditLogManifest ret = new RemoteEditLogManifest(logs);
         if (Log.IsDebugEnabled())
         {
             Log.Debug("Generated manifest for logs since " + fromTxId + ":" + ret);
         }
         return(ret);
     }
 }
Beispiel #5
0
 private static void Compare(RemoteEditLog l1, RemoteEditLog l2)
 {
     NUnit.Framework.Assert.AreEqual(l1.GetEndTxId(), l2.GetEndTxId());
     NUnit.Framework.Assert.AreEqual(l1.GetStartTxId(), l2.GetStartTxId());
 }
Beispiel #6
0
        /// <summary>Create a new checkpoint</summary>
        /// <exception cref="System.IO.IOException"/>
        internal virtual void DoCheckpoint()
        {
            BackupImage bnImage   = GetFSImage();
            NNStorage   bnStorage = bnImage.GetStorage();
            long        startTime = Time.MonotonicNow();

            bnImage.FreezeNamespaceAtNextRoll();
            NamenodeCommand cmd = GetRemoteNamenodeProxy().StartCheckpoint(backupNode.GetRegistration
                                                                               ());
            CheckpointCommand cpCmd = null;

            switch (cmd.GetAction())
            {
            case NamenodeProtocol.ActShutdown:
            {
                Shutdown();
                throw new IOException("Name-node " + backupNode.nnRpcAddress + " requested shutdown."
                                      );
            }

            case NamenodeProtocol.ActCheckpoint:
            {
                cpCmd = (CheckpointCommand)cmd;
                break;
            }

            default:
            {
                throw new IOException("Unsupported NamenodeCommand: " + cmd.GetAction());
            }
            }
            bnImage.WaitUntilNamespaceFrozen();
            CheckpointSignature sig = cpCmd.GetSignature();

            // Make sure we're talking to the same NN!
            sig.ValidateStorageInfo(bnImage);
            long lastApplied = bnImage.GetLastAppliedTxId();

            Log.Debug("Doing checkpoint. Last applied: " + lastApplied);
            RemoteEditLogManifest manifest = GetRemoteNamenodeProxy().GetEditLogManifest(bnImage
                                                                                         .GetLastAppliedTxId() + 1);
            bool needReloadImage = false;

            if (!manifest.GetLogs().IsEmpty())
            {
                RemoteEditLog firstRemoteLog = manifest.GetLogs()[0];
                // we don't have enough logs to roll forward using only logs. Need
                // to download and load the image.
                if (firstRemoteLog.GetStartTxId() > lastApplied + 1)
                {
                    Log.Info("Unable to roll forward using only logs. Downloading " + "image with txid "
                             + sig.mostRecentCheckpointTxId);
                    MD5Hash downloadedHash = TransferFsImage.DownloadImageToStorage(backupNode.nnHttpAddress
                                                                                    , sig.mostRecentCheckpointTxId, bnStorage, true);
                    bnImage.SaveDigestAndRenameCheckpointImage(NNStorage.NameNodeFile.Image, sig.mostRecentCheckpointTxId
                                                               , downloadedHash);
                    lastApplied     = sig.mostRecentCheckpointTxId;
                    needReloadImage = true;
                }
                if (firstRemoteLog.GetStartTxId() > lastApplied + 1)
                {
                    throw new IOException("No logs to roll forward from " + lastApplied);
                }
                // get edits files
                foreach (RemoteEditLog log in manifest.GetLogs())
                {
                    TransferFsImage.DownloadEditsToStorage(backupNode.nnHttpAddress, log, bnStorage);
                }
                if (needReloadImage)
                {
                    Log.Info("Loading image with txid " + sig.mostRecentCheckpointTxId);
                    FilePath file = bnStorage.FindImageFile(NNStorage.NameNodeFile.Image, sig.mostRecentCheckpointTxId
                                                            );
                    bnImage.ReloadFromImageFile(file, backupNode.GetNamesystem());
                }
                RollForwardByApplyingLogs(manifest, bnImage, backupNode.GetNamesystem());
            }
            long txid = bnImage.GetLastAppliedTxId();

            backupNode.namesystem.WriteLock();
            try
            {
                backupNode.namesystem.SetImageLoaded();
                if (backupNode.namesystem.GetBlocksTotal() > 0)
                {
                    backupNode.namesystem.SetBlockTotal();
                }
                bnImage.SaveFSImageInAllDirs(backupNode.GetNamesystem(), txid);
                bnStorage.WriteAll();
            }
            finally
            {
                backupNode.namesystem.WriteUnlock();
            }
            if (cpCmd.NeedToReturnImage())
            {
                TransferFsImage.UploadImageFromStorage(backupNode.nnHttpAddress, conf, bnStorage,
                                                       NNStorage.NameNodeFile.Image, txid);
            }
            GetRemoteNamenodeProxy().EndCheckpoint(backupNode.GetRegistration(), sig);
            if (backupNode.GetRole() == HdfsServerConstants.NamenodeRole.Backup)
            {
                bnImage.ConvergeJournalSpool();
            }
            backupNode.SetRegistration();
            // keep registration up to date
            long imageSize = bnImage.GetStorage().GetFsImageName(txid).Length();

            Log.Info("Checkpoint completed in " + (Time.MonotonicNow() - startTime) / 1000 +
                     " seconds." + " New Image Size: " + imageSize);
        }