示例#1
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 != filesystem.Storage.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 file system. Existing incremental data origins from '{0}' file system.", state.ResourceName));
                        }
                    }
                    else
                    {
                        var state = new IncrementalBackupState()
                        {
                            ResourceId   = filesystem.Storage.Id,
                            ResourceName = filesystem.Name
                        };

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

                    token.ThrowIfCancellationRequested();

                    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.");
                }

                token.ThrowIfCancellationRequested();

                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"));
                }

                token.ThrowIfCancellationRequested();

                filesystem.Search.Backup(backupDestinationDirectory, token);

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

                ExecuteBackup(backupDestinationDirectory, incrementalBackup, token);

                if (filesystemDocument != null)
                {
                    File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.FilesystemDocumentFilename), RavenJObject.FromObject(filesystemDocument).ToString());
                }

                token.ThrowIfCancellationRequested();

                OperationFinishedSuccessfully();
            }
            catch (OperationCanceledException e)
            {
                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), e.Message);
                UpdateBackupStatus("Backup was canceled", null, BackupStatus.BackupMessageSeverity.Error);
                state.MarkCanceled();
            }
            catch (AggregateException e)
            {
                var ne = e.ExtractSingleInnerException();
                UpdateBackupStatus("Failed to complete backup because: " + ne.Message, ne, BackupStatus.BackupMessageSeverity.Error);
                state.MarkFaulted("Failed to complete backup because: " + ne.Message, ne);

                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), ne.Message);
            }
            catch (Exception e)
            {
                UpdateBackupStatus("Failed to complete backup because: " + e.Message, e, BackupStatus.BackupMessageSeverity.Error);
                state.MarkFaulted("Failed to complete backup because: " + e.Message, e);

                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), e.Message);
            }
            finally
            {
                CompleteBackup();
            }
        }
示例#2
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());
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    if (CanPerformIncrementalBackup())
                    {
                        backupDestinationDirectory = DirectoryForIncrementalBackup();
                        EnsureBackupDestinationExists();
                    }
                    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.");
                }

                cancellationToken.ThrowIfCancellationRequested();

                UpdateBackupStatus("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"));
                }

                cancellationToken.ThrowIfCancellationRequested();

                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, cancellationToken);

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

                cancellationToken.ThrowIfCancellationRequested();

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

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

                ExecuteBackup(backupDestinationDirectory, incrementalBackup, cancellationToken);

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

                cancellationToken.ThrowIfCancellationRequested();
                OperationFinishedSuccessfully();
            }
            catch (OperationCanceledException e)
            {
                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), e.Message);
                UpdateBackupStatus("Backup was canceled", null, BackupStatus.BackupMessageSeverity.Error);
                state.MarkCanceled();
            }
            catch (AggregateException e)
            {
                var ne = e.ExtractSingleInnerException();
                // OperationCancledException can be inside AggreateException, because we perform some writes in parallel
                if (ne is OperationCanceledException)
                {
                    state.MarkCanceled();
                    UpdateBackupStatus("Backup was canceled", null, BackupStatus.BackupMessageSeverity.Error);
                }
                else
                {
                    state.MarkFaulted("Failed to complete backup because:" + ne.Message, ne);
                    UpdateBackupStatus("Failed to complete backup because: " + ne.Message, ne, BackupStatus.BackupMessageSeverity.Error);
                }

                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), ne.Message);
            }
            catch (Exception e)
            {
                UpdateBackupStatus("Failed to complete backup because: " + e.Message, e, BackupStatus.BackupMessageSeverity.Error);
                state.MarkFaulted("Failed to complete backup because: " + e.Message);
                File.WriteAllText(Path.Combine(backupDestinationDirectory, Constants.BackupFailureMarker), e.Message);
            }
            finally
            {
                CompleteBackup();
            }
        }