Пример #1
0
        private IEnumerable <BackupItemReference> GetReverseBackupSequence(
            DateTime?minBackupEndTime, DateTime?restoreTargetTime, IEnumerable <BackupFileInfo> reverseBackupFileSequence)
        {
            BackupItemReference result = null;
            var sequence = reverseBackupFileSequence.GetEnumerator();

            while (sequence.MoveNext() && result == null)
            {
                Check.DoCheckOperationValid(sequence.Current.IsDatabase);
                var header = ParseBackupHeader(sequence.Current.FileInfo);

                var suitableItems = header.ValidItems
                                    .OrderByDescending(i => i.BackupEndTime)
                                    .Where(b => !restoreTargetTime.HasValue || b.BackupEndTime < restoreTargetTime.Value)
                                    .Where(b => !minBackupEndTime.HasValue || b.BackupEndTime >= minBackupEndTime.Value);

                foreach (var item in suitableItems)
                {
                    yield return(new BackupItemReference()
                    {
                        BackupItem = item, FileHeader = header
                    });
                }
            }
        }
        public void Restore()
        {
            Check.DoCheckOperationValid(IsPrepared, "Restorer is not prepared");

            Log.InfoFormat("Restoring {0}, Target Time: {1}"
                           , DatabaseName, TargetTime.HasValue ? TargetTime.Value.ToString("yy-MM-dd HH:mm:ss:fff") : "Latest");

            if (HaveItemsToRestore)
            {
                var originalUserAccess = DatabaseUserAccess.Multiple;
                if (_preExistingDatabase)
                {
                    if (Database.Status == DatabaseStatus.Restoring)
                    {
                        ForceRecoveringDatabase();
                    }
                    if (_preExistingDatabase)
                    {
                        originalUserAccess = Database.DatabaseOptions.UserAccess;
                        Database.DatabaseOptions.UserAccess = DatabaseUserAccess.Single;
                        Database.Alter(TerminationClause.RollbackTransactionsImmediately);
                    }
                }

                try
                {
                    foreach (var item in _backupItems)
                    {
                        Restore(item);
                        LastRestoredBackup = item;
                    }

                    Server.ConnectionContext.ExecuteNonQuery($"restore database [{DatabaseName}] with recovery;");
                    Log.InfoFormat("Database {0} restored successfully", DatabaseName);
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception restoring {0}: {1}", _databaseName, e);
                    throw;
                }
                finally
                {
                    if (_preExistingDatabase)
                    {
                        Log.InfoFormat("Setting {0} user access to original value {1}", DatabaseName, originalUserAccess);
                        Database.DatabaseOptions.UserAccess = originalUserAccess;
                        Database.Alter();
                    }
                }
            }
        }