Ejemplo n.º 1
0
		/// <summary>
		/// The process for backing up a directory index is simple:
		/// a) create hard links to all the files in the lucene directory in a temp director
		///	   that gives us the current snapshot, and protect us from Lucene's
		///    deleting files.
		/// b) copy the hard links to the destination directory
		/// c) delete the temp directory
		/// </summary>
		public void Execute(ProgressNotifier progressNotifier)
		{
			if (allowOverwrite) // clean destination folder; we want to do this as close as possible to the actual backup operation
			{
				IOExtensions.DeleteDirectory(destination);
				Directory.CreateDirectory(destination);
			}

			foreach (var file in Directory.EnumerateFiles(tempPath))
			{
				Notify("Copying " + Path.GetFileName(file), BackupStatus.BackupMessageSeverity.Informational);
				var fullName = new FileInfo(file).FullName;
				FileCopy(file, Path.Combine(destination, Path.GetFileName(file)), fileToSize[fullName], progressNotifier);
				Notify("Copied " + Path.GetFileName(file), BackupStatus.BackupMessageSeverity.Informational);
			}

			try
			{
				IOExtensions.DeleteDirectory(tempPath);
			}
			catch (Exception e) //cannot delete, probably because there is a file being written there
			{
				logger.WarnException(string.Format("Could not delete {0}, will delete those on startup", tempPath), e);

				foreach (var file in Directory.EnumerateFiles(tempPath))
				{
					MoveFileEx(file, null, MoveFileDelayUntilReboot);
				}
				MoveFileEx(tempPath, null, MoveFileDelayUntilReboot);
			}
		}
Ejemplo n.º 2
0
        private void FileCopy(string src, string dest, long size, ProgressNotifier notifier, CancellationToken token)
        {
            var buffer = new byte[16 * 1024];

            using (var srcStream = File.Open(src, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (File.Exists(dest))
                {
                    File.SetAttributes(dest, FileAttributes.Normal);
                }
                using (var destStream = File.Create(dest, buffer.Length))
                {
                    while (true)
                    {
                        token.ThrowIfCancellationRequested();
                        var read = srcStream.Read(buffer, 0, (int)Math.Min(buffer.Length, size));
                        notifier.UpdateProgress(read, Notify);
                        if (read == 0)
                        {
                            break;
                        }
                        size -= read;
                        destStream.Write(buffer, 0, read);
                    }
                    destStream.Flush();
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// The process for backing up a directory index is simple:
        /// a) create hard links to all the files in the lucene directory in a temp director
        ///	   that gives us the current snapshot, and protect us from Lucene's
        ///    deleting files.
        /// b) copy the hard links to the destination directory
        /// c) delete the temp directory
        /// </summary>
        public void Execute(ProgressNotifier progressNotifier, CancellationToken token)
        {
            if (allowOverwrite) // clean destination folder; we want to do this as close as possible to the actual backup operation
            {
                IOExtensions.DeleteDirectory(destination);
            }

            EnsureDirectoryExists(destination);

            foreach (var file in Directory.EnumerateFiles(tempPath))
            {
                token.ThrowIfCancellationRequested();

                Notify("Copying " + Path.GetFileName(file), null, BackupStatus.BackupMessageSeverity.Informational);
                var fullName = new FileInfo(file).FullName;
                FileCopy(file, Path.Combine(destination, Path.GetFileName(file)), fileToSize[fullName], progressNotifier, token);
                Notify("Copied " + Path.GetFileName(file), null, BackupStatus.BackupMessageSeverity.Informational);
            }

            try
            {
                IOExtensions.DeleteDirectory(tempPath);
            }
            catch (Exception e) //cannot delete, probably because there is a file being written there
            {
                logger.WarnException(string.Format("Could not delete {0}, will delete those on startup", tempPath), e);

                foreach (var file in Directory.EnumerateFiles(tempPath))
                {
                    MoveFileEx(file, null, MoveFileDelayUntilReboot);
                }
                MoveFileEx(tempPath, null, MoveFileDelayUntilReboot);
            }
        }
Ejemplo n.º 4
0
        public void Execute()
        {
            try
            {
                string incrementalTag = null;

                log.Info("Starting backup of '{0}' to '{1}'", backupSourceDirectory, backupDestinationDirectory);
                UpdateBackupStatus(
                    string.Format("Started backup process. Backing up data to directory = '{0}'",
                                  backupDestinationDirectory), BackupStatus.BackupMessageSeverity.Informational);

                if (BackupAlreadyExists) // trying to backup to an existing backup folder
                {
                    if (!incrementalBackup)
                        throw new InvalidOperationException("Denying request to perform a full backup to an existing backup folder. Try doing an incremental backup instead.");

                    while (true)
                    {
                        incrementalTag = SystemTime.UtcNow.ToString("Inc yyyy-MM-dd HH-mm-ss");
                        backupDestinationDirectory = Path.Combine(backupDestinationDirectory, incrementalTag);

                        if (Directory.Exists(backupDestinationDirectory) == false)
                            break;
                        Thread.Sleep(100); // wait until the second changes, should only even happen in tests
                    }
                }
                else
                {
                    incrementalBackup = false; // destination wasn't detected as a backup folder, automatically revert to a full backup if incremental was specified
                }

                UpdateBackupStatus(string.Format("Backing up indexes.."), BackupStatus.BackupMessageSeverity.Informational);

                // Make sure we have an Indexes folder in the backup location
                if (!Directory.Exists(Path.Combine(backupDestinationDirectory, "Indexes")))
                    Directory.CreateDirectory(Path.Combine(backupDestinationDirectory, "Indexes"));

                var directoryBackups = new List<DirectoryBackup>
				{
					new DirectoryBackup(Path.Combine(backupSourceDirectory, "IndexDefinitions"),
                                        Path.Combine(backupDestinationDirectory, "IndexDefinitions"), 
                                        Path.Combine(backupSourceDirectory, "Temp" + Guid.NewGuid().ToString("N")), incrementalBackup)
				};

                database.IndexStorage.Backup(backupDestinationDirectory);

                var progressNotifier = new ProgressNotifier();
                foreach (var directoryBackup in directoryBackups)
                {
                    directoryBackup.Notify += UpdateBackupStatus;
                    var backupSize = directoryBackup.Prepare();
                    progressNotifier.TotalBytes += backupSize;
                }

                foreach (var directoryBackup in directoryBackups)
                {
                    directoryBackup.Execute(progressNotifier);
                }

                UpdateBackupStatus(string.Format("Finished indexes backup. Executing data backup.."), BackupStatus.BackupMessageSeverity.Informational);

                ExecuteBackup(backupDestinationDirectory, incrementalBackup);

                if (databaseDocument != null)
                    File.WriteAllText(Path.Combine(backupDestinationDirectory, "Database.Document"), RavenJObject.FromObject(databaseDocument).ToString());

                OperationFinished();

            }
            catch (AggregateException e)
            {
                var ne = e.ExtractSingleInnerException();
                log.ErrorException("Failed to complete backup", ne);
                UpdateBackupStatus("Failed to complete backup because: " + ne.Message, BackupStatus.BackupMessageSeverity.Error);
            }
            catch (Exception e)
            {
                log.ErrorException("Failed to complete backup", e);
                UpdateBackupStatus("Failed to complete backup because: " + e.Message, BackupStatus.BackupMessageSeverity.Error);
            }
            finally
            {
                CompleteBackup();
            }
        }
Ejemplo n.º 5
0
		private void FileCopy(string src, string dest, long size, ProgressNotifier notifier)
		{
			var buffer = new byte[16 * 1024];
			var initialSize = size;
			using (var srcStream = File.Open(src,FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
			{
				if (File.Exists(dest))
					File.SetAttributes(dest,FileAttributes.Normal);
				using (var destStream = File.Create(dest, buffer.Length))
				{
					while (true)
					{
						var read = srcStream.Read(buffer, 0, (int)Math.Min(buffer.Length, size));
						notifier.UpdateProgress(read, Notify);
						if (read == 0)
							break;
						size -= read;
						destStream.Write(buffer, 0, read);
					}
					destStream.Flush();
				}
			}
		}
Ejemplo n.º 6
0
        public void Execute()
        {
            try
            {
                log.Info("Starting backup of '{0}' to '{1}'", backupSourceDirectory, backupDestinationDirectory);
                UpdateBackupStatus(
                    string.Format("Started backup process. Backing up data to directory = '{0}'",
                                  backupDestinationDirectory), null, BackupStatus.BackupMessageSeverity.Informational);

	            EnsureBackupDestinationExists();

	            if (incrementalBackup)
                {
	                var incrementalBackupState = Path.Combine(backupDestinationDirectory, Constants.IncrementalBackupState);

	                if (File.Exists(incrementalBackupState))
	                {
		                var state = RavenJObject.Parse(File.ReadAllText(incrementalBackupState)).JsonDeserialization<IncrementalBackupState>();

						if(state.ResourceId != database.TransactionalStorage.Id)
							throw new InvalidOperationException(string.Format("Can't perform an incremental backup to a given folder because it already contains incremental backup data of different database. Existing incremental data origins from '{0}' database.", state.ResourceName));
	                }
	                else
	                {
		                var state = new IncrementalBackupState()
		                {
			                ResourceId = database.TransactionalStorage.Id,
							ResourceName = database.Name ?? Constants.SystemDatabase
		                };

						File.WriteAllText(incrementalBackupState, RavenJObject.FromObject(state).ToString());
	                }

	                if (CanPerformIncrementalBackup())
                    {
                        backupDestinationDirectory = DirectoryForIncrementalBackup();
                    }
                    else
                    {
                        incrementalBackup = false; // destination wasn't detected as a backup folder, automatically revert to a full backup if incremental was specified
                    }
                }
                else if (BackupAlreadyExists)
                {
                    throw new InvalidOperationException("Denying request to perform a full backup to an existing backup folder. Try doing an incremental backup instead.");
                }

                UpdateBackupStatus(string.Format("Backing up indexes.."), null, BackupStatus.BackupMessageSeverity.Informational);

                // Make sure we have an Indexes folder in the backup location
                if (!Directory.Exists(Path.Combine(backupDestinationDirectory, "Indexes")))
                    Directory.CreateDirectory(Path.Combine(backupDestinationDirectory, "Indexes"));

                var directoryBackups = new List<DirectoryBackup>
				{
					new DirectoryBackup(Path.Combine(backupSourceDirectory, "IndexDefinitions"),
                                        Path.Combine(backupDestinationDirectory, "IndexDefinitions"), 
                                        Path.Combine(backupSourceDirectory, "Temp" + Guid.NewGuid().ToString("N")), incrementalBackup)
				};

                database.IndexStorage.Backup(backupDestinationDirectory,null, UpdateBackupStatus);

                var progressNotifier = new ProgressNotifier();
                foreach (var directoryBackup in directoryBackups)
                {
                    directoryBackup.Notify += UpdateBackupStatus;
                    var backupSize = directoryBackup.Prepare();
                    progressNotifier.TotalBytes += backupSize;
                }

                foreach (var directoryBackup in directoryBackups)
                {
                    directoryBackup.Execute(progressNotifier);
                }

                UpdateBackupStatus(string.Format("Finished indexes backup. Executing data backup.."), null, BackupStatus.BackupMessageSeverity.Informational);

                ExecuteBackup(backupDestinationDirectory, incrementalBackup);

                if (databaseDocument != null)
                    File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.DatabaseDocumentFilename), RavenJObject.FromObject(databaseDocument).ToString());

                OperationFinished();

            }
            catch (AggregateException e)
            {
                var ne = e.ExtractSingleInnerException();
                log.ErrorException("Failed to complete backup", ne);
                UpdateBackupStatus("Failed to complete backup because: " + ne.Message, ne.ExceptionToString(null), BackupStatus.BackupMessageSeverity.Error);
            }
            catch (Exception e)
            {
                log.ErrorException("Failed to complete backup", e);
                UpdateBackupStatus("Failed to complete backup because: " + e.Message, e.ExceptionToString(null), BackupStatus.BackupMessageSeverity.Error);
            }
            finally
            {
                CompleteBackup();
            }
        }