/// <exception cref="System.Exception"/> /// <exception cref="System.IO.IOException"/> private void DoCheckpoint() { System.Diagnostics.Debug.Assert(canceler != null); long txid; NNStorage.NameNodeFile imageType; // Acquire cpLock to make sure no one is modifying the name system. // It does not need the full namesystem write lock, since the only thing // that modifies namesystem on standby node is edit log replaying. namesystem.CpLockInterruptibly(); try { System.Diagnostics.Debug.Assert(namesystem.GetEditLog().IsOpenForRead(), "Standby Checkpointer should only attempt a checkpoint when " + "NN is in standby mode, but the edit logs are in an unexpected state"); FSImage img = namesystem.GetFSImage(); long prevCheckpointTxId = img.GetStorage().GetMostRecentCheckpointTxId(); long thisCheckpointTxId = img.GetLastAppliedOrWrittenTxId(); System.Diagnostics.Debug.Assert(thisCheckpointTxId >= prevCheckpointTxId); if (thisCheckpointTxId == prevCheckpointTxId) { Log.Info("A checkpoint was triggered but the Standby Node has not " + "received any transactions since the last checkpoint at txid " + thisCheckpointTxId + ". Skipping..."); return; } if (namesystem.IsRollingUpgrade() && !namesystem.GetFSImage().HasRollbackFSImage( )) { // if we will do rolling upgrade but have not created the rollback image // yet, name this checkpoint as fsimage_rollback imageType = NNStorage.NameNodeFile.ImageRollback; } else { imageType = NNStorage.NameNodeFile.Image; } img.SaveNamespace(namesystem, imageType, canceler); txid = img.GetStorage().GetMostRecentCheckpointTxId(); System.Diagnostics.Debug.Assert(txid == thisCheckpointTxId, "expected to save checkpoint at txid=" + thisCheckpointTxId + " but instead saved at txid=" + txid); // Save the legacy OIV image, if the output dir is defined. string outputDir = checkpointConf.GetLegacyOivImageDir(); if (outputDir != null && !outputDir.IsEmpty()) { img.SaveLegacyOIVImage(namesystem, outputDir, canceler); } } finally { namesystem.CpUnlock(); } // Upload the saved checkpoint back to the active // Do this in a separate thread to avoid blocking transition to active // See HDFS-4816 ExecutorService executor = Executors.NewSingleThreadExecutor(uploadThreadFactory); Future <Void> upload = executor.Submit(new _Callable_204(this, imageType, txid)); executor.Shutdown(); try { upload.Get(); } catch (Exception e) { // The background thread may be blocked waiting in the throttler, so // interrupt it. upload.Cancel(true); throw; } catch (ExecutionException e) { throw new IOException("Exception during image upload: " + e.Message, e.InnerException ); } }