コード例 #1
0
        public void AfterBackupRestoreCanQueryIndex_CreatedAfterRestore()
        {
            db.Documents.Put("ayende", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);

            db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
            WaitForBackup(db, true);

            db.Dispose();
            IOExtensions.DeleteDirectory(DataDir);

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir
            }, s => { });

            db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            });
            db.SpinBackgroundWorkers();
            QueryResult queryResult;

            do
            {
                queryResult = db.Queries.Query("Raven/DocumentsByEntityName", new IndexQuery
                {
                    Query    = "Tag:[[Users]]",
                    PageSize = 10
                }, CancellationToken.None);
            } while (queryResult.IsStale);
            Assert.Equal(1, queryResult.Results.Count);
        }
コード例 #2
0
        public void AfterBackupRestoreCanReadDocument()
        {
            db.Documents.Put("ayende", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);

            db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
            WaitForBackup(db, true);

            db.Dispose();
            IOExtensions.DeleteDirectory(DataDir);

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir,
                Defrag           = true
            }, s => { });

            db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            });

            var document = db.Documents.Get("ayende", null);

            Assert.NotNull(document);

            var jObject = document.ToJson();

            Assert.Equal("*****@*****.**", jObject.Value <string>("email"));
        }
コード例 #3
0
 private static void RunSystemDatabaseRestoreOperation(string backupLocation, string databaseLocation, bool defrag)
 {
     try
     {
         var ravenConfiguration = new RavenConfiguration();
         if (File.Exists(Path.Combine(backupLocation, "Raven.voron")))
         {
             ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
         }
         else if (Directory.Exists(Path.Combine(backupLocation, "new")))
         {
             ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
         }
         MaintenanceActions.Restore(ravenConfiguration, new DatabaseRestoreRequest
         {
             BackupLocation   = backupLocation,
             DatabaseLocation = databaseLocation,
             Defrag           = defrag
         }, Console.WriteLine);
     }
     catch (Exception e)
     {
         Console.WriteLine(e);
     }
 }
コード例 #4
0
        public void AfterFailedRestoreOfIndex_ShouldGenerateWarningAndResetIt(string storageName)
        {
            using (var db = new DocumentDatabase(new RavenConfiguration
            {
                DefaultStorageTypeName = storageName,
                DataDirectory = DataDir,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
            }))
            {
                db.SpinBackgroundWorkers();
                db.Indexes.PutIndex(new RavenDocumentsByEntityName().IndexName, new RavenDocumentsByEntityName().CreateIndexDefinition());

                db.Documents.Put("users/1", null, RavenJObject.Parse("{'Name':'Arek'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
                db.Documents.Put("users/2", null, RavenJObject.Parse("{'Name':'David'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
                db.Documents.Put("users/3", null, RavenJObject.Parse("{'Name':'Daniel'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);

                WaitForIndexing(db);

                db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
                WaitForBackup(db, true);
            }
            IOExtensions.DeleteDirectory(DataDir);

            var path = Directory.GetFiles(BackupDir, "index-files.required-for-index-restore", SearchOption.AllDirectories).First();

            // lock file to simulate IOException when restore operation will try to copy this file
            using (var file = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
            {
                var sb = new StringBuilder();

                MaintenanceActions.Restore(new RavenConfiguration(), new RestoreRequest
                {
                    BackupLocation   = BackupDir,
                    DatabaseLocation = DataDir
                }, s => sb.Append(s));

                Assert.Contains(
                    "could not be restored. All already copied index files was deleted." +
                    " Index will be recreated after launching Raven instance",
                    sb.ToString());
            }

            using (var db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            }))
            {
                db.SpinBackgroundWorkers();
                QueryResult queryResult;
                do
                {
                    queryResult = db.Queries.Query("Raven/DocumentsByEntityName", new IndexQuery
                    {
                        Query    = "Tag:[[Users]]",
                        PageSize = 10
                    }, CancellationToken.None);
                } while (queryResult.IsStale);
                Assert.Equal(3, queryResult.Results.Count);
            }
        }
コード例 #5
0
        public void AfterIncrementalBackupRestoreCanReadDocument(string storageName)
        {
            InitializeDocumentDatabase(storageName);
            IOExtensions.DeleteDirectory(BackupDir);

            db.Documents.Put("ayende", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);

            db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
            WaitForBackup(db, true);

            db.Documents.Put("itamar", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);
            db.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument());
            WaitForBackup(db, true);

            db.Dispose();
            IOExtensions.DeleteDirectory(DataDir);

            MaintenanceActions.Restore(new RavenConfiguration
            {
                DefaultStorageTypeName = storageName,
                DataDirectory          = DataDir,
                RunInMemory            = false,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
                Settings =
                {
                    { "Raven/Esent/CircularLog",             "false" },
                    { "Raven/Voron/AllowIncrementalBackups", "true"  }
                }
            }, new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir,
                Defrag           = true
            }, s => { });

            db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            });

            var fetchedData = db.Documents.Get("ayende", null);

            Assert.NotNull(fetchedData);

            var jObject = fetchedData.ToJson();

            Assert.NotNull(jObject);
            Assert.Equal("*****@*****.**", jObject.Value <string>("email"));

            fetchedData = db.Documents.Get("itamar", null);
            Assert.NotNull(fetchedData);

            jObject = fetchedData.ToJson();
            Assert.NotNull(jObject);
            Assert.Equal("*****@*****.**", jObject.Value <string>("email"));
        }
コード例 #6
0
        public void NonIncrementalBackup_Restore_CanReadDocumentWithCorruptedIndex(string storageName)
        {
            InitializeDocumentDatabase(storageName);
            IOExtensions.DeleteDirectory(BackupDir);

            db.Documents.Put("Foo", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);

            db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument(), new ResourceBackupState());
            WaitForBackup(db, true);

            db.Dispose();
            IOExtensions.DeleteDirectory(DataDir);

            var    indexFile = Path.Combine(BackupDir, "IndexDefinitions", "1.index");
            string text      = File.ReadAllText(indexFile);

            text = text.Replace("from", "corrupt");
            File.WriteAllText(indexFile, text); // deliberately corrupt index

            //index is corrupted --> should NOT fail to restore backup
            Assert.DoesNotThrow(() =>
                                MaintenanceActions.Restore(new RavenConfiguration
            {
                DefaultStorageTypeName = storageName,
                DataDirectory          = DataDir,
                RunInMemory            = false,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
                Settings =
                {
                    { "Raven/Esent/CircularLog", "false" }
                }
            }, new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir,
                Defrag           = true
            }, s => { }));

            db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            }, null);

            var fetchedData = db.Documents.Get("Foo", null);

            Assert.NotNull(fetchedData);

            var jObject = fetchedData.ToJson();

            Assert.NotNull(jObject);
            Assert.Equal("*****@*****.**", jObject.Value <string>("email"));

            db.Dispose();
        }
コード例 #7
0
        public void CannotRestoreFailedBackup(string storageName)
        {
            var config = new RavenConfiguration
            {
                DataDirectory = DataDir,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
                DefaultStorageTypeName = storageName,
                Settings =
                {
                    { Constants.Esent.CircularLog,             "false" },
                    { Constants.Voron.AllowIncrementalBackups, "true"  }
                }
            };

            config.Storage.Voron.AllowIncrementalBackups = true;

            using (db = new DocumentDatabase(config, null))
            {
                db.Indexes.PutIndex(new RavenDocumentsByEntityName().IndexName, new RavenDocumentsByEntityName().CreateIndexDefinition());

                db.Documents.Put("ayende", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);

                // purpose of doing first backup is to have Database.Document in target directory
                // we cancel second backup, when file is already in place
                db.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument(), new ResourceBackupState(), CancellationToken.None);
                WaitForBackup(db, true);

                db.Documents.Put("marcin", null, RavenJObject.Parse("{'email':'*****@*****.**'}"), new RavenJObject(), null);

                using (var cts = new CancellationTokenSource())
                {
                    cts.Cancel();
                    db.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument(), new ResourceBackupState(), cts.Token);
                    var ex = Assert.Throws <Exception>(() => WaitForBackup(db, true));
                    Assert.Contains("Backup was canceled", ex.Message);
                }

                db.Dispose();
                IOExtensions.DeleteDirectory(DataDir);

                var restoreEx = Assert.Throws <InvalidOperationException>(() =>
                {
                    MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
                    {
                        BackupLocation   = BackupDir,
                        DatabaseLocation = DataDir,
                        Defrag           = true
                    }, s => { });
                });

                Assert.Equal("Backup failure marker was detected. Unable to restore from given directory.", restoreEx.Message);
            }
        }
コード例 #8
0
        public void CanRestoreFullToMultipleLocationsEmbeddedWithIndexing()
        {
            string storage;

            using (var store = NewDocumentStore(runInMemory: false))
            {
                storage = store.Configuration.DefaultStorageTypeName;

                new User_ByName().Execute(store);

                using (var sesion = store.OpenSession())
                {
                    sesion.Store(new User {
                        Name = "Regina"
                    });
                    sesion.SaveChanges();
                }

                WaitForIndexing(store);

                store.SystemDatabase.Maintenance.StartBackup(backupDir, false, new DatabaseDocument());
                WaitForBackup(store.SystemDatabase, true);
            }

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = backupDir,
                DatabaseLocation = dataDir,
                DatabaseName     = "foo",
                IndexesLocation  = indexesDir,
                JournalsLocation = jouranlDir
            }, Console.WriteLine);

            var ravenConfiguration = new RavenConfiguration
            {
                DefaultStorageTypeName = storage,
                DataDirectory          = dataDir,
                IndexStoragePath       = indexesDir
            };

            ravenConfiguration.Storage.Esent.JournalsStoragePath = jouranlDir;
            ravenConfiguration.Storage.Voron.JournalsStoragePath = jouranlDir;

            using (var db = new DocumentDatabase(ravenConfiguration))
            {
                //db.SpinBackgroundWorkers(); -- indexing disabled here

                var q = db.Queries.Query("User/ByName", new IndexQuery(), CancellationToken.None);
                Assert.Equal(1, q.TotalResults); // we read the indexed results from the restored data
            }
        }
コード例 #9
0
        public void CanRestoreFullToMultipleLocationsEmbedded()
        {
            using (var store = NewDocumentStore(runInMemory: false))
            {
                using (var sesion = store.OpenSession())
                {
                    sesion.Store(new User {
                        Name = "Regina"
                    });
                    sesion.SaveChanges();
                }

                store.SystemDatabase.Maintenance.StartBackup(backupDir, false, new DatabaseDocument());
                WaitForBackup(store.SystemDatabase, true);
            }

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = backupDir,
                DatabaseLocation = dataDir,
                DatabaseName     = "foo",
                IndexesLocation  = indexesDir,
                JournalsLocation = jouranlDir
            }, Console.WriteLine);

            using (var store = NewDocumentStore(runInMemory: false, configureStore: documentStore =>
            {
                documentStore.Configuration.DataDirectory = dataDir;
                documentStore.Configuration.IndexStoragePath = indexesDir;
                documentStore.Configuration.Storage.Esent.JournalsStoragePath = jouranlDir;
                documentStore.Configuration.Storage.Voron.JournalsStoragePath = jouranlDir;
            }))
            {
                using (var sesion = store.OpenSession())
                {
                    Assert.Equal("Regina", sesion.Load <User>(1).Name);
                }
            }
        }
コード例 #10
0
ファイル: RavenDB_1520.cs プロジェクト: stvoidmain/ravendb
        public void Backup_and_restore_of_system_database_should_work()
        {
            using (var ravenServer = GetNewServer(runInMemory: false, requestedStorage: "esent"))
                using (var _ = NewRemoteDocumentStore(ravenDbServer: ravenServer, databaseName: "fooDB", runInMemory: false))
                {
                    using (var systemDatabaseBackupOperation = new BackupOperation
                    {
                        BackupPath = BackupDir,
                        Database = Constants.SystemDatabase,
                        ServerUrl = ravenServer.SystemDatabase.Configuration.ServerUrl
                    })
                    {
                        Assert.True(systemDatabaseBackupOperation.InitBackup());
                        WaitForBackup(ravenServer.SystemDatabase, true);
                    }
                }

            Assert.DoesNotThrow(() => MaintenanceActions.Restore(new RavenConfiguration(), new RestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir
            }, s => { }));
        }
コード例 #11
0
        public void AfterRestoreOfIncrementalBackupAllIndexesShouldWork()
        {
            using (var store = NewDocumentStore(requestedStorage: "esent"))
            {
                new Users_ByName().Execute(store);

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "Arek", Country = "Poland"
                    });
                    session.SaveChanges();
                }

                WaitForIndexing(store);

                store.SystemDatabase.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument());
                WaitForBackup(store.SystemDatabase, true);

                Thread.Sleep(1000);                 // incremental tag has seconds precision

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "Ramon", Country = "Spain"
                    });
                    session.SaveChanges();
                }

                WaitForIndexing(store);

                store.SystemDatabase.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument());
                WaitForBackup(store.SystemDatabase, true);

                Thread.Sleep(1000);                 // incremental tag has seconds precision

                new Users_ByNameAndCountry().Execute(store);

                WaitForIndexing(store);

                store.SystemDatabase.Maintenance.StartBackup(BackupDir, true, new DatabaseDocument());
                WaitForBackup(store.SystemDatabase, true);

                var output = new StringBuilder();

                MaintenanceActions.Restore(new RavenConfiguration
                {
                    Settings =
                    {
                        { Constants.Esent.CircularLog,             "false" },
                        { Constants.Voron.AllowIncrementalBackups, "true"  }
                    }
                }, new DatabaseRestoreRequest
                {
                    BackupLocation   = BackupDir,
                    Defrag           = true,
                    DatabaseLocation = DataDir
                }, s => output.Append(s));

                Assert.DoesNotContain("error", output.ToString().ToLower());

                using (var db = new DocumentDatabase(new RavenConfiguration
                {
                    DataDirectory = DataDir,
                    Settings =
                    {
                        { Constants.Esent.CircularLog, "false" }
                    }
                }))
                {
                    var indexStats = db.Statistics.Indexes;

                    Assert.Equal(3, indexStats.Length);                     // Users/* and Raven/DocumentsByEntityName

                    QueryResult docs = db.Queries.Query("Users/ByName", new IndexQuery
                    {
                        Query    = "Name:*",
                        Start    = 0,
                        PageSize = 10
                    }, CancellationToken.None);

                    Assert.Equal(2, docs.Results.Count);

                    docs = db.Queries.Query("Users/ByNameAndCountry", new IndexQuery
                    {
                        Query    = "Name:*",
                        Start    = 0,
                        PageSize = 10
                    }, CancellationToken.None);

                    Assert.Equal(2, docs.Results.Count);
                }
            }
        }
コード例 #12
0
        public void ShouldNotSetAutoIndexesToAbandonedPriorityAfterDatabaseRecovery()
        {
            using (var db = new DocumentDatabase(new RavenConfiguration
            {
                DataDirectory = DataDir,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false
            }))
            {
                db.SpinBackgroundWorkers();
                db.Indexes.PutIndex(new RavenDocumentsByEntityName().IndexName, new RavenDocumentsByEntityName().CreateIndexDefinition());

                db.Documents.Put("users/1", null, RavenJObject.Parse("{'Name':'Arek'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
                db.Documents.Put("users/2", null, RavenJObject.Parse("{'Name':'David'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);

                var results = db.ExecuteDynamicQuery("Users", new IndexQuery()
                {
                    PageSize = 128,
                    Start    = 0,
                    Cutoff   = SystemTime.UtcNow,
                    Query    = "Name:Arek"
                }, CancellationToken.None);

                WaitForIndexing(db);

                var autoIdexes = db.Statistics.Indexes.Where(x => x.Name.StartsWith("Auto")).ToList();

                Assert.True(autoIdexes.Count > 0);

                autoIdexes.ForEach(x => db.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexPriority(x.Id, IndexingPriority.Idle)));

                db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
                WaitForBackup(db, true);
            }
            IOExtensions.DeleteDirectory(DataDir);

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir,
                Defrag           = true
            }, s => { });

            using (var db = new DocumentDatabase(new RavenConfiguration
            {
                DataDirectory = DataDir,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
            }))
            {
                db.SpinBackgroundWorkers();
                db.RunIdleOperations();

                var autoIndexes = db.Statistics.Indexes.Where(x => x.Name.StartsWith("Auto")).ToList();

                Assert.True(autoIndexes.Count > 0);

                foreach (var indexStats in autoIndexes)
                {
                    Assert.NotEqual(indexStats.Priority, IndexingPriority.Abandoned);
                }
            }
        }
コード例 #13
0
        public DocumentDatabase(InMemoryRavenConfiguration configuration, TransportState transportState = null)
        {
            DocumentLock        = new PutSerialLock();
            Name                = configuration.DatabaseName;
            Configuration       = configuration;
            this.transportState = transportState ?? new TransportState();
            ExtensionsState     = new AtomicDictionary <object>();

            using (LogManager.OpenMappedContext("database", Name ?? Constants.SystemDatabase))
            {
                Log.Debug("Start loading the following database: {0}", Name ?? Constants.SystemDatabase);

                initializer = new DocumentDatabaseInitializer(this, configuration);

                initializer.InitializeEncryption();
                initializer.ValidateLicense();

                initializer.SubscribeToDomainUnloadOrProcessExit();
                initializer.ExecuteAlterConfiguration();
                initializer.SatisfyImportsOnce();

                backgroundTaskScheduler = configuration.CustomTaskScheduler ?? TaskScheduler.Default;


                recentTouches = new SizeLimitedConcurrentDictionary <string, TouchedDocumentInfo>(configuration.MaxRecentTouchesToRemember, StringComparer.OrdinalIgnoreCase);

                configuration.Container.SatisfyImportsOnce(this);

                workContext = new WorkContext
                {
                    Database            = this,
                    DatabaseName        = Name,
                    IndexUpdateTriggers = IndexUpdateTriggers,
                    ReadTriggers        = ReadTriggers,
                    TaskScheduler       = backgroundTaskScheduler,
                    Configuration       = configuration,
                    IndexReaderWarmers  = IndexReaderWarmers
                };

                try
                {
                    uuidGenerator = new SequentialUuidGenerator();
                    initializer.InitializeTransactionalStorage(uuidGenerator);
                    lastCollectionEtags = new LastCollectionEtags(TransactionalStorage, WorkContext);
                }
                catch (Exception)
                {
                    if (TransactionalStorage != null)
                    {
                        TransactionalStorage.Dispose();
                    }
                    throw;
                }

                try
                {
                    TransactionalStorage.Batch(actions => uuidGenerator.EtagBase = actions.General.GetNextIdentityValue("Raven/Etag"));

                    // Index codecs must be initialized before we try to read an index
                    InitializeIndexCodecTriggers();
                    initializer.InitializeIndexStorage();

                    Attachments   = new AttachmentActions(this, recentTouches, uuidGenerator, Log);
                    Documents     = new DocumentActions(this, recentTouches, uuidGenerator, Log);
                    Indexes       = new IndexActions(this, recentTouches, uuidGenerator, Log);
                    Maintenance   = new MaintenanceActions(this, recentTouches, uuidGenerator, Log);
                    Notifications = new NotificationActions(this, recentTouches, uuidGenerator, Log);
                    Patches       = new PatchActions(this, recentTouches, uuidGenerator, Log);
                    Queries       = new QueryActions(this, recentTouches, uuidGenerator, Log);
                    Tasks         = new TaskActions(this, recentTouches, uuidGenerator, Log);
                    Transformers  = new TransformerActions(this, recentTouches, uuidGenerator, Log);

                    inFlightTransactionalState = TransactionalStorage.GetInFlightTransactionalState(Documents.Put, Documents.Delete);

                    CompleteWorkContextSetup();

                    prefetcher       = new Prefetcher(workContext);
                    indexingExecuter = new IndexingExecuter(workContext, prefetcher);

                    RaiseIndexingWiringComplete();

                    InitializeTriggersExceptIndexCodecs();
                    SecondStageInitialization();
                    ExecuteStartupTasks();
                    lastCollectionEtags.Initialize();

                    Log.Debug("Finish loading the following database: {0}", configuration.DatabaseName ?? Constants.SystemDatabase);
                }
                catch (Exception)
                {
                    Dispose();
                    throw;
                }
            }
        }
コード例 #14
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <RestoreRequest>();

            DatabaseDocument databaseDocument = null;

            var databaseDocumentPath = Path.Combine(restoreRequest.BackupLocation, "Database.Document");

            if (File.Exists(databaseDocumentPath))
            {
                var databaseDocumentText = File.ReadAllText(databaseDocumentPath);
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                                                ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                                                : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            if (databaseName == Constants.SystemDatabase)
            {
                return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);
            restoreRequest.DatabaseLocation  = ravenConfiguration.DataDirectory;
            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            await Task.Factory.StartNew(() =>
            {
                MaintenanceActions.Restore(ravenConfiguration, restoreRequest,
                                           msg =>
                {
                    restoreStatus.Messages.Add(msg);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                });

                if (databaseDocument == null)
                {
                    return;
                }

                databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                if (restoreRequest.IndexesLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                }
                if (restoreRequest.JournalsLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                }
                databaseDocument.Id = databaseName;
                DatabasesLandlord.Protect(databaseDocument);
                DatabasesLandlord.SystemDatabase.Documents.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument),
                                                               new RavenJObject(), null);

                restoreStatus.Messages.Add("The new database was created");
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                               RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
            }, TaskCreationOptions.LongRunning);

            return(GetEmptyMessage());
        }
コード例 #15
0
        public void AfterFailedRestoreOfIndex_ShouldGenerateWarningAndResetIt(string storageName)
        {
            using (var db = new DocumentDatabase(new RavenConfiguration
            {
                DataDirectory = DataDir,
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = false,
                DefaultStorageTypeName = storageName,
                Settings =
                {
                    { "Raven/Esent/CircularLog",             "false" },
                    { "Raven/Voron/AllowIncrementalBackups", "true"  }
                }
            }))
            {
                db.SpinBackgroundWorkers();
                db.Indexes.PutIndex(new RavenDocumentsByEntityName().IndexName, new RavenDocumentsByEntityName().CreateIndexDefinition());

                db.Documents.Put("users/1", null, RavenJObject.Parse("{'Name':'Arek'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
                db.Documents.Put("users/2", null, RavenJObject.Parse("{'Name':'David'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);

                WaitForIndexing(db);

                var databaseDocument = new DatabaseDocument();
                db.Maintenance.StartBackup(BackupDir, false, databaseDocument);
                WaitForBackup(db, true);

                db.Documents.Put("users/3", null, RavenJObject.Parse("{'Name':'Daniel'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);

                WaitForIndexing(db);

                db.Maintenance.StartBackup(BackupDir, true, databaseDocument);
                WaitForBackup(db, true);
            }
            IOExtensions.DeleteDirectory(DataDir);

            var incrementalDirectories = Directory.GetDirectories(BackupDir, "Inc*");

            // delete 'index-files.required-for-index-restore' to make backup corrupted according to the reported error
            var combine = Directory.GetFiles(incrementalDirectories.First(), "index-files.required-for-index-restore", SearchOption.AllDirectories).First();

            File.Delete(combine);

            var sb = new StringBuilder();

            MaintenanceActions.Restore(new RavenConfiguration(), new RestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir
            }, s => sb.Append(s));

            Assert.Contains(
                "could not be restored. All already copied index files was deleted." +
                " Index will be recreated after launching Raven instance",
                sb.ToString());

            using (var db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            }))
            {
                db.SpinBackgroundWorkers();
                QueryResult queryResult;
                do
                {
                    queryResult = db.Queries.Query("Raven/DocumentsByEntityName", new IndexQuery
                    {
                        Query    = "Tag:[[Users]]",
                        PageSize = 10
                    }, CancellationToken.None);
                } while (queryResult.IsStale);
                Assert.Equal(3, queryResult.Results.Count);
            }
        }
コード例 #16
0
        public void AfterBackupRestore_IndexConsistentWithWritesDuringBackup()
        {
            var count = 1;
            var docId = string.Format("ayende{0}", count++.ToString("D4"));

            db.Documents.Put(docId, null, RavenJObject.Parse("{'email':'*****@*****.**'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
            db.SpinBackgroundWorkers();

            QueryResult queryResult;

            do
            {
                queryResult = db.Queries.Query("Raven/DocumentsByEntityName", new IndexQuery
                {
                    Query    = "Tag:[[Users]]",
                    PageSize = 10
                }, CancellationToken.None);
            } while (queryResult.IsStale);
            Assert.Equal(1, queryResult.Results.Count);

            var runInserts = true;

            Task.Run(() =>
            {
                while (runInserts)
                {
                    docId = string.Format("ayende{0}", count++.ToString("D4"));
                    db.Documents.Put(docId, null, RavenJObject.Parse("{'email':'*****@*****.**'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
                    db.IndexStorage.FlushMapIndexes();
                }
            });

            db.Maintenance.StartBackup(BackupDir, false, new DatabaseDocument());
            WaitForBackup(db, true);
            runInserts = false;

            db.Dispose();
            IOExtensions.DeleteDirectory(DataDir);

            MaintenanceActions.Restore(new RavenConfiguration(), new DatabaseRestoreRequest
            {
                BackupLocation   = BackupDir,
                DatabaseLocation = DataDir,
                Defrag           = true
            }, s => { });

            db = new DocumentDatabase(new RavenConfiguration {
                DataDirectory = DataDir
            });
            docId = string.Format("ayende{0}", count++.ToString("D4"));
            db.Documents.Put(docId, null, RavenJObject.Parse("{'email':'*****@*****.**'}"), RavenJObject.Parse("{'Raven-Entity-Name':'Users'}"), null);
            db.SpinBackgroundWorkers();

            int next       = 0;
            var storedDocs = new List <string>();

            while (true)
            {
                var batch = db.Documents.GetDocumentsWithIdStartingWith("ayende", null, null, next, 1024, CancellationToken.None, ref next);
                storedDocs.AddRange(batch.Select(doc => doc.Value <RavenJObject>("@metadata").Value <string>("@id")));
                if (batch.Length < 1024)
                {
                    break;
                }
            }

            List <string> indexedDocs;
            bool          stale;

            do
            {
                indexedDocs = db.Queries.QueryDocumentIds("Raven/DocumentsByEntityName", new IndexQuery
                {
                    Query    = "Tag:[[Users]]",
                    PageSize = int.MaxValue,
                    WaitForNonStaleResultsAsOfNow = true
                }, new CancellationTokenSource(), out stale).ToList();
            } while (stale);

            if (storedDocs.Count != indexedDocs.Count)
            {
                var storedHash  = new HashSet <string>(storedDocs);
                var indexedHash = new HashSet <string>(indexedDocs);
                foreach (var id in storedDocs.Union(indexedDocs).OrderBy(x => x))
                {
                    Debug.WriteLine("{0} Database:{1} Indexed:{2}", id, storedHash.Contains(id), indexedHash.Contains(id));
                }
            }

            Assert.Equal(storedDocs.Count, indexedDocs.Count());
            db.Dispose();
        }