public void restore_azure_cloud_settings_tests() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var databaseName = $"restored_database-{Guid.NewGuid()}"; var restoreConfiguration = new RestoreFromAzureConfiguration { DatabaseName = databaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Account Key cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.AccountKey = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Account Name cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.AccountName = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Storage Container cannot be null or empty", e.InnerException.Message); } }
public void restore_google_cloud_settings_tests() { using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var databaseName = $"restored_database-{Guid.NewGuid()}"; var restoreConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Google Cloud Bucket name cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.BucketName = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Google Credentials JSON cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.GoogleCredentialsJson = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Wrong format for Google Credentials.", e.InnerException.Message); } }
public IDisposable RestoreDatabase(IDocumentStore store, RestoreBackupConfiguration config, TimeSpan?timeout = null) { var restoreOperation = new RestoreBackupOperation(config); var operation = store.Maintenance.Server.Send(restoreOperation); operation.WaitForCompletion(timeout ?? TimeSpan.FromMilliseconds(_reasonableTimeout * 2)); return(_parent.Databases.EnsureDatabaseDeletion(config.DatabaseName, store)); }
public IDisposable RestoreDatabaseFromCloud(IDocumentStore store, RestoreBackupConfigurationBase config, TimeSpan?timeout = null) { var restoreOperation = new RestoreBackupOperation(config); var operation = store.Maintenance.Server.Send(restoreOperation); operation.WaitForCompletion(timeout ?? TimeSpan.FromSeconds(30)); return(EnsureDatabaseDeletion(config.DatabaseName, store)); }
private async Task RestoreBackup(MyBackup backup) { var rnd = new Random(); var restoreDbName = $"Restored_{new string(Enumerable.Repeat(_chars, rnd.Next(5, 10)).Select(x => x[rnd.Next(x.Length)]).ToArray())}"; var restoreConfig = new RestoreBackupConfiguration { DatabaseName = restoreDbName, BackupLocation = backup.BackupPath }; var restoreBackupTask = new RestoreBackupOperation(restoreConfig); using (var session = DocumentStore.OpenAsyncSession()) { var succeeded = true; try { ReportInfo($"Starting to restore DB: {restoreDbName}"); var re = DocumentStore.GetRequestExecutor(DocumentStore.Database); var restoreBackupTaskCommand = restoreBackupTask.GetCommand(DocumentStore.Conventions, session.Advanced.Context); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag == backup.BackupStatus.NodeTag), null, session.Advanced.Context, restoreBackupTaskCommand, shouldRetry : false); var getOperationStateTask = new GetOperationStateOperation(restoreBackupTaskCommand.Result.OperationId); var getOperationStateTaskCommand = getOperationStateTask.GetCommand(DocumentStore.Conventions, session.Advanced.Context); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag == backup.BackupStatus.NodeTag), null, session.Advanced.Context, getOperationStateTaskCommand, shouldRetry : false); while (getOperationStateTaskCommand.Result.Status == OperationStatus.InProgress) { await Task.Delay(2000); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag == backup.BackupStatus.NodeTag), null, session.Advanced.Context, getOperationStateTaskCommand, shouldRetry : false); } } catch (Exception e) { ReportFailure($"Restoring DB: {restoreDbName} Failed", e); succeeded = false; } for (var i = 0; i < MyBackupsList.Count; i++) { if (MyBackupsList[i].BackupTaskId == backup.BackupTaskId) { MyBackupsList[i].RestoreResult = succeeded ? RestoreResult.Succeeded : RestoreResult.Failed; break; } } } }
private static async Task Restore(string backupPath, DocumentStore restoreStore) { var restore = new RestoreBackupOperation(new RestoreBackupConfiguration { BackupLocation = Directory.GetDirectories(backupPath).First(), DatabaseName = restoreStore.Database, }); var result = await restoreStore.Maintenance.Server.SendAsync(restore); result.WaitForCompletion(); }
/// <summary> /// Restores a RavenDB 4 Backup /// </summary> protected override void RestoreDb() { var restoreCfg = new RestoreBackupConfiguration { DatabaseName = o.Db, BackupLocation = o.Backup }; var restoreTask = new RestoreBackupOperation(restoreCfg); store.Maintenance.Server.Send(restoreTask).WaitForCompletion(); o.DbSize = GetDbSize(); }
public Restore() { using (var store = new DocumentStore()) { #region restore_3 RestoreBackupConfiguration config = new RestoreBackupConfiguration() { BackupLocation = @"C:\backups\Northwind", DatabaseName = "Northwind" }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(); #endregion } }
public void restore_azure_cloud_settings_tests() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var databaseName = $"restored_database-{Guid.NewGuid()}"; var restoreConfiguration = new RestoreFromAzureConfiguration { DatabaseName = databaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains($"{nameof(AzureSettings.AccountKey)} and {nameof(AzureSettings.SasToken)} cannot be both null or empty", e.InnerException.Message); restoreConfiguration.Settings.AccountKey = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains($"{nameof(AzureSettings.AccountName)} cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.AccountName = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains($"{nameof(AzureSettings.StorageContainer)} cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.StorageContainer = "test"; restoreConfiguration.Settings.AccountKey = null; restoreConfiguration.Settings.SasToken = "testSasToken"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains($"{nameof(AzureSettings.SasToken)} isn't in the correct format", e.InnerException.Message); restoreConfiguration.Settings.AccountKey = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains($"{nameof(AzureSettings.AccountKey)} and {nameof(AzureSettings.SasToken)} cannot be used simultaneously", e.InnerException.Message); } }
public async Task CreateFullAndIncrementalBackupWithCompareExchangeInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Name = "Toli" }, "users/1"); session.SaveChanges(); } var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "* */6 * * *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = (await GetDocumentDatabaseInstanceFor(store)); RunBackup(result.TaskId, documentDatabase, true, store); CompareExchangeResult <string> compareExchangeResult = store.Operations.Send( new PutCompareExchangeValueOperation <string>("users/1", "Mitzi", 0)); config.IncrementalBackupFrequency = "* */2 * * *"; config.TaskId = result.TaskId; result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); RunBackup(result.TaskId, documentDatabase, false, store); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = Directory.GetFiles(backupDirectory).Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { using (var session = store2.OpenSession()) { var doc = session.Load <User>("users/1"); Assert.NotNull(doc); }; CompareExchangeValue <string> readResult = store2.Operations.Send(new GetCompareExchangeValueOperation <string>("users/1")); Assert.Equal("Mitzi", readResult.Value); }; } }
static async Task MainInternal() { using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { #region logical_full_backup_every_3_hours var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { //Backup files local path FolderPath = @"E:\RavenBackups" }, //Full Backup period (Cron expression for a 3-hours period) FullBackupFrequency = "0 */3 * * *", //Type can be Backup or Snapshot BackupType = BackupType.Backup, //Task Name Name = "fullBackupTask", }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { #region encrypted_logical_full_backup var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { //Backup files local path FolderPath = @"E:\RavenBackups" }, //Full Backup period (Cron expression for a 3-hours period) FullBackupFrequency = "0 */3 * * *", //Type can be Backup or Snapshot BackupType = BackupType.Backup, //Task Name Name = "fullBackupTask" }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = @"E:\RavenBackups" }, #region backup_type_snapshot //Type can be Backup or Snapshot BackupType = BackupType.Snapshot, #endregion #region backup_full_backup //Full Backup period (Cron expression for a 6-hours period) FullBackupFrequency = "0 */6 * * *", #endregion #region backup_incremental_backup //Cron expression: set incremental backup period ("*/20 * * * *" is a 20-minutes period) IncrementalBackupFrequency = "*/20 * * * *", #endregion }; } using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { #region backup_remote_destinations var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = @"E:\RavenBackups" }, //FTP Backup settings FtpSettings = new FtpSettings { Url = "192.168.10.4", Port = 8080, UserName = "******", Password = "******" }, //Azure Backup settings AzureSettings = new AzureSettings { StorageContainer = "storageContainer", RemoteFolderName = "remoteFolder", AccountName = "JohnAccount", AccountKey = "key" }, //Amazon S3 bucket settings. S3Settings = new S3Settings { AwsAccessKey = "your access key here", AwsSecretKey = "your secret key here", AwsRegionName = "OPTIONAL", BucketName = "john-bucket", }, //Amazon Glacier settings. GlacierSettings = new GlacierSettings { AwsAccessKey = "your access key here", AwsSecretKey = "your secret key here", AwsRegionName = "OPTIONAL", VaultName = "john-glacier", } }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = @"E:\RavenBackups" }, //FTP Backup settings FtpSettings = new FtpSettings { Url = "192.168.10.4", Port = 8080, UserName = "******", Password = "******" }, //Azure Backup settings AzureSettings = new AzureSettings { StorageContainer = "storageContainer", RemoteFolderName = "remoteFolder", AccountName = "JohnAccount", AccountKey = "key" } }; #region initiate_immediate_backup_execution var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); //run a backup task immediately await docStore.Maintenance.SendAsync(new StartBackupOperation(true, result.TaskId)); #endregion #region get_backup_execution_results //Provide GetPeriodicBackupStatusOperation with the task ID returned by RavenDB var backupStatus = new GetPeriodicBackupStatusOperation(result.TaskId); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "http://127.0.0.1:8080" }, Database = "Products" }.Initialize()) { #region restore_to_single_node var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newProductsDatabase"; //Local path with a backup file var backupPath = @"C:\Users\RavenDB\backups\2018-12-26-16-17.ravendb-Products-A-backup"; restoreConfiguration.BackupLocation = backupPath; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); #endregion #region restore_disable_ongoing_tasks_false //Disable or Enable ongoing tasks after restoration. //Default setting is FALSE, so tasks DO run when backup is restored. restoreConfiguration.DisableOngoingTasks = false; #endregion #region restore_last_file_name_to_restore //Last incremental backup file to restore from restoreConfiguration.LastFileNameToRestore = @"2018-12-26-12-00.ravendb-incremental-backup"; #endregion #region restore_to_specific__data_directory //Restore to a pre-chosen folder var dataPath = @"C:\Users\RavenDB\backups\2018-12-26-16-17.ravendb-Products-A-backup\restoredDatabaseLocation"; restoreConfiguration.DataDirectory = dataPath; #endregion #region restore_disable_ongoing_tasks_true //Do or do not run ongoing tasks after restoration. //Default setting is FALSE, to allow tasks' execution when the backup is restored. restoreConfiguration.DisableOngoingTasks = true; #endregion } #region encrypted_database // path to the certificate you received during the server setup var cert = new X509Certificate2(@"C:\Users\RavenDB\authentication_key\admin.client.certificate.RavenDBdom.pfx"); using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { // Backup & Restore here } #endregion // path to the authentication key you received during the server setup cert = new X509Certificate2(@"C:\Users\RavenDB\authentication_key\admin.client.certificate.RavenDBdom.pfx"); using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { #region restore_encrypted_database // restore encrypted database // restore configuration var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newEncryptedDatabase"; //Backup-file location var backupPath = @"C:\Users\RavenDB\2019-01-06-11-11.ravendb-encryptedDatabase-A-snapshot"; restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.EncryptionKey = "1F0K2R/KkcwbkK7n4kYlv5eqisy/pMnSuJvZ2sJ/EKo="; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); #endregion } }
private async Task RestoreBackup(MyBackup backup) { var rnd = new Random(); var restoreDbName = $"Restored_{new string(Enumerable.Repeat(_chars, rnd.Next(5, 10)).Select(x => x[rnd.Next(x.Length)]).ToArray())}"; var restoreConfig = new RestoreBackupConfiguration { DatabaseName = restoreDbName, BackupLocation = backup.BackupPath }; var restoreBackupTask = new RestoreBackupOperation(restoreConfig); using (var session = DocumentStore.OpenAsyncSession()) { var reasonableTimeForBackup = Stopwatch.StartNew(); var succeeded = true; try { ReportInfo($"Starting to restore DB: {restoreDbName}"); var re = DocumentStore.GetRequestExecutor(DocumentStore.Database); var restoreBackupTaskCommand = restoreBackupTask.GetCommand(DocumentStore.Conventions, session.Advanced.Context); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag.Equals(backup.BackupStatus.NodeTag)), null, session.Advanced.Context, restoreBackupTaskCommand, shouldRetry : false) .ConfigureAwait(false); var getOperationStateTask = new GetOperationStateOperation(restoreBackupTaskCommand.Result.OperationId); var getOperationStateTaskCommand = getOperationStateTask.GetCommand(DocumentStore.Conventions, session.Advanced.Context); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag.Equals(backup.BackupStatus.NodeTag)), null, session.Advanced.Context, getOperationStateTaskCommand, shouldRetry : false) .ConfigureAwait(false); while (getOperationStateTaskCommand.Result == null || getOperationStateTaskCommand.Result.Status == OperationStatus.InProgress) { await Task.Delay(2000).ConfigureAwait(false); await re.ExecuteAsync(re.TopologyNodes.First(q => q.ClusterTag.Equals(backup.BackupStatus.NodeTag)), null, session.Advanced.Context, getOperationStateTaskCommand, shouldRetry : false) .ConfigureAwait(false); if (reasonableTimeForBackup.Elapsed > TimeSpan.FromMinutes(5)) { ReportFailure($"Restoring DB: {restoreDbName} Failed, taskID {backup.BackupTaskId} - Waited {reasonableTimeForBackup.Elapsed} and task didn't finished", null); succeeded = true; // marking as success in order to delete // TODO : RavenDB-13684 break; } } } catch (RavenException re) { if (re.InnerException is ArgumentException ae) { ReportInfo($"Probably somebody deleted the backup files, taskID {backup.BackupTaskId}, exception: {ae}"); } else { ReportFailure($"Restoring DB: {restoreDbName} Failed, taskID {backup.BackupTaskId}", re); } } catch (Exception e) { ReportFailure($"Restoring DB: {restoreDbName} Failed, taskID {backup.BackupTaskId}", e); succeeded = false; } if (succeeded) { MyRestoreDbsList.Add(restoreDbName); } for (var i = 0; i < MyBackupsList.Count; i++) { if (MyBackupsList[i].BackupTaskId == backup.BackupTaskId) { MyBackupsList[i].RestoreResult = succeeded ? RestoreResult.Succeeded : RestoreResult.Failed; break; } } } }
public async Task restore_settings_tests() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var restoreConfiguration = new RestoreBackupConfiguration(); var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Database name can't be null or empty", e.InnerException.Message); restoreConfiguration.DatabaseName = store.Database; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Cannot restore data to an existing database", e.InnerException.Message); restoreConfiguration.DatabaseName = "test-" + Guid.NewGuid(); restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Backup location can't be null or empty", e.InnerException.Message); restoreConfiguration.BackupLocation = "this-path-doesn't-exist\\"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Backup location doesn't exist", e.InnerException.Message); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, LocalSettings = new LocalSettings { FolderPath = backupPath }, IncrementalBackupFrequency = "* * * * *" //every minute }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); var value = WaitForValue(() => { var status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 1); Assert.Equal(1, value); restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.DataDirectory = backupPath; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("New data directory must be empty of any files or folders", e.InnerException.Message); var emptyFolder = NewDataPath(suffix: "BackupFolderRestore"); restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.DataDirectory = emptyFolder; } }
public async Task CreateFullAndIncrementalBackupWithCompareExchangeInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Name = "Toli" }, "users/1"); session.SaveChanges(); } var config = Backup.CreateBackupConfiguration(backupPath); var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store); CompareExchangeResult <string> compareExchangeResult = store.Operations.Send( new PutCompareExchangeValueOperation <string>("users/1", "Mitzi", 0)); WaitForValue(() => compareExchangeResult.Successful, true); await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false); compareExchangeResult = store.Operations.Send( new PutCompareExchangeValueOperation <string>("users/1", "Mitzi2", compareExchangeResult.Index)); WaitForValue(() => compareExchangeResult.Successful, true); await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { using (var session = store2.OpenSession()) { var doc = session.Load <User>("users/1"); Assert.NotNull(doc); }; CompareExchangeValue <string> readResult = store2.Operations.Send(new GetCompareExchangeValueOperation <string>("users/1")); Assert.Equal("Mitzi2", readResult.Value); }; } }
public async Task SkipExportingTheServerWideBackup2() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { var serverWideBackupConfiguration = new ServerWideBackupConfiguration { Disabled = false, FullBackupFrequency = "0 2 * * 0", IncrementalBackupFrequency = "0 2 * * 1", LocalSettings = new LocalSettings { FolderPath = backupPath } }; await store.Maintenance.Server.SendAsync(new PutServerWideBackupConfigurationOperation(serverWideBackupConfiguration)); var record = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store.Database)); var backup = record.PeriodicBackups.First(); var backupTaskId = backup.TaskId; // save another backup task in the database record var backupConfiguration = new PeriodicBackupConfiguration { Disabled = true, FullBackupFrequency = "0 2 * * 0", IncrementalBackupFrequency = "0 2 * * 1" }; await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(backupConfiguration)); await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); string backupDirectory = null; var value = WaitForValue(() => { var status = store.Maintenance.Send(new GetPeriodicBackupStatusOperation(backupTaskId)).Status; backupDirectory = status?.LocalBackup.BackupDirectory; return(status?.LastEtag); }, 0); Assert.Equal(0, value); var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); var databaseName = GetDatabaseName() + "restore"; var restoreConfig = new RestoreBackupConfiguration { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.OrderBackups().Last() }; var restoreOperation = new RestoreBackupOperation(restoreConfig); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); // old server should have 2: 1 server-wide and 1 regular backup using (var store2 = GetDocumentStore(new Options { CreateDatabase = false, ModifyDatabaseName = s => databaseName, })) { var record2 = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store2.Database)); Assert.Equal(2, record2.PeriodicBackups.Count); } // new server should have only one backup var server = GetNewServer(); using (var store3 = GetDocumentStore(new Options { CreateDatabase = false, ModifyDatabaseName = s => databaseName, Server = server })) { store3.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); var record3 = await store3.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(databaseName)); Assert.Equal(1, record3.PeriodicBackups.Count); } } }
public async Task TombstonesOfArtificialDocumentsShouldNotBeRestored() { using (var store = GetDocumentStore()) { new Users_ByName_Count().Execute(store); using (var session = store.OpenSession()) { session.Store(new User() { Name = "Arek" }, "users/arek"); session.SaveChanges(); } Indexes.WaitForIndexing(store); using (var session = store.OpenSession()) { session.Delete("users/arek"); // delete source document so we'll have tombstones of artificial documents generated by the index session.SaveChanges(); } Indexes.WaitForIndexing(store); var backupPath = NewDataPath(suffix: "BackupFolder"); var config = Backup.CreateBackupConfiguration(backupPath); var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store); // restore var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); await store.Maintenance.Server.Send(restoreOperation) .WaitForCompletionAsync(TimeSpan.FromSeconds(30)); using (var storeOfRestoredDb = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var db = await GetDatabase(storeOfRestoredDb.Database); using (db.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var tombstones = db.DocumentsStorage.GetTombstonesFrom(ctx, 0, 0, int.MaxValue).ToList(); Assert.Equal(1, tombstones.Count); Assert.Equal("users/arek", tombstones[0].LowerId); } } } }
public async Task CreateFullBackupWithSeveralCompareExchange() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { var user = new User { Name = "💩" }; await store.Operations.SendAsync(new PutCompareExchangeValueOperation <User>("emojis/poo", user, 0)); var user2 = new User { Name = "💩🤡" }; await store.Operations.SendAsync(new PutCompareExchangeValueOperation <User>("emojis/pooclown", user2, 0)); var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "* */6 * * *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = (await GetDocumentDatabaseInstanceFor(store)); RunBackup(result.TaskId, documentDatabase, true, store); // FULL BACKUP var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); var restoreConfig = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; var restoreOperation = new RestoreBackupOperation(restoreConfig); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { using (var session = store2.OpenAsyncSession(new SessionOptions { TransactionMode = TransactionMode.ClusterWide })) { var user1 = (await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <User>("emojis/poo")); var user3 = (await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <User>("emojis/pooclown")); Assert.Equal(user.Name, user1.Value.Name); Assert.Equal(user2.Name, user3.Value.Name); } } } }
public async Task can_backup_and_restore() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); session.CountersFor("users/1").Increment("likes", 100); await session.SaveChangesAsync(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, GoogleCloudSettings = GoogleCloudFact.GoogleCloudSettings, IncrementalBackupFrequency = "* * * * *" //every minute }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); var value = WaitForValue(() => { var status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 4); Assert.Equal(4, value); var backupStatus = store.Maintenance.Send(operation); var backupOperationId = backupStatus.Status.LastOperationId; var backupOperation = store.Maintenance.Send(new GetOperationStateOperation(backupOperationId.Value)); var backupResult = backupOperation.Result as BackupResult; Assert.True(backupResult.Counters.Processed); Assert.Equal(1, backupResult.Counters.ReadCount); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; await store.Maintenance.SendAsync(new StartBackupOperation(false, backupTaskId)); value = WaitForValue(() => store.Maintenance.Send(operation).Status.LastEtag, lastEtag); Assert.Equal(lastEtag, value); // restore the database with a different name var databaseName = $"restored_database-{Guid.NewGuid()}"; GoogleCloudFact.GoogleCloudSettings.RemoteFolderName = $"{backupStatus.Status.FolderName}"; var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration() { DatabaseName = databaseName, Settings = GoogleCloudFact.GoogleCloudSettings }; var googleCloudOperation = new RestoreBackupOperation(restoreFromGoogleCloudConfiguration); var restoreOperation = store.Maintenance.Server.Send(googleCloudOperation); restoreOperation.WaitForCompletion(TimeSpan.FromSeconds(30)); { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Equal($"A:7-{originalDatabase.DbBase64Id}, A:8-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public async Task restore_settings_tests() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var restoreConfiguration = new RestoreBackupConfiguration(); var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Database name can't be null or empty", e.InnerException.Message); restoreConfiguration.DatabaseName = store.Database; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Cannot restore data to an existing database", e.InnerException.Message); restoreConfiguration.DatabaseName = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Backup location can't be null or empty", e.InnerException.Message); restoreConfiguration.BackupLocation = "~\\this-path-doesn't-exist\\"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Backup location doesn't exist", e.InnerException.Message); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, LocalSettings = new LocalSettings { FolderPath = backupPath }, IncrementalBackupFrequency = "* * * * *" //every minute }; var result = await store.Admin.Server.SendAsync(new UpdatePeriodicBackupOperation(config, store.Database)); var periodicBackupTaskId = result.TaskId; var operation = new GetPeriodicBackupStatusOperation(store.Database, periodicBackupTaskId); SpinWait.SpinUntil(() => { var getPeriodicBackupResult = store.Admin.Server.Send(operation); return(getPeriodicBackupResult.Status?.LastEtag > 0); }, TimeSpan.FromMinutes(2)); restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.DataDirectory = backupPath; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("New data directory must be empty of any files or folders", e.InnerException.Message); restoreConfiguration.BackupLocation = backupPath; var emptyFolder = NewDataPath(suffix: "BackupFolderRestore"); restoreConfiguration.DataDirectory = emptyFolder; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Journals directory must be empty of any files or folders", e.InnerException.Message); restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.DataDirectory = emptyFolder;; restoreConfiguration.IndexingStoragePath = backupPath; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Admin.Server.Send(restoreBackupTask)); Assert.Contains("Indexes directory must be empty of any files or folders", e.InnerException.Message); } }
public async Task can_backup_and_restore_snapshot() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Snapshot, LocalSettings = new LocalSettings { FolderPath = backupPath }, IncrementalBackupFrequency = "* * * * *" //every minute }; var result = await store.Admin.Server.SendAsync(new UpdatePeriodicBackupOperation(config, store.Database)); var periodicBackupTaskId = result.TaskId; var operation = new GetPeriodicBackupStatusOperation(store.Database, periodicBackupTaskId); SpinWait.SpinUntil(() => { var getPeriodicBackupResult = store.Admin.Server.Send(operation); return(getPeriodicBackupResult.Status?.LastEtag > 0); }, TimeSpan.FromMinutes(2)); var etagForBackups = store.Admin.Server.Send(operation).Status.LastEtag; using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); await session.StoreAsync(new User { Name = "ayende" }, "users/3"); await session.SaveChangesAsync(); } SpinWait.SpinUntil(() => { var newLastEtag = store.Admin.Server.Send(operation).Status.LastEtag; return(newLastEtag != etagForBackups); }, TimeSpan.FromMinutes(2)); // restore the database with a different name const string restoredDatabaseName = "restored_database_snapshot"; var restoreConfiguration = new RestoreBackupConfiguration { BackupLocation = Directory.GetDirectories(backupPath).First(), DatabaseName = restoredDatabaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var restoreResult = store.Admin.Server.Send(restoreBackupTask); var stateRequest = new GetOperationStateOperation(restoreResult.OperationId, true); store.Admin.Server.Send(stateRequest); SpinWait.SpinUntil(() => { var state = store.Admin.Server.Send(stateRequest); return(state.Status == OperationStatus.Completed); }, TimeSpan.FromMinutes(2)); using (var session = store.OpenAsyncSession(restoredDatabaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); } } }
public async Task CreateFullAndIncrementalBackupWithIdentitiesInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Id = "users|", Name = "Toli" }); session.Store(new User { Id = "users|", Name = "Mitzi" }); session.SaveChanges(); } var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "* */6 * * *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = (await GetDocumentDatabaseInstanceFor(store)); RunBackup(result.TaskId, documentDatabase, true, store); Dictionary <string, long> identities = store.Maintenance.Send(new GetIdentitiesOperation()); config.IncrementalBackupFrequency = "* */2 * * *"; config.TaskId = result.TaskId; result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); RunBackup(result.TaskId, documentDatabase, false, store); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = Directory.GetFiles(backupDirectory).Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { Dictionary <string, long> identities2 = store2.Maintenance.Send(new GetIdentitiesOperation()); Assert.Equal(identities.First().Key, identities2.First().Key); Assert.Equal(identities.First().Value, identities2.First().Value); }; } }
static async Task MainInternal() { #region encrypted_database // path to the certificate you received during the server setup var cert = new X509Certificate2(@"C:\Users\RavenDB\authentication_key\admin.client.certificate.RavenDBdom.pfx"); using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { // Backup & Restore procedures here } #endregion using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { //Backup files local path FolderPath = @"E:\RavenBackups" }, //Full Backup period (Cron expression for a 3-hours period) FullBackupFrequency = "0 */3 * * *", //Type can be Backup or Snapshot BackupType = BackupType.Backup, //Task Name Name = "fullBackupTask", BackupEncryptionSettings = new BackupEncryptionSettings { #region use_database_encryption_key //Use the same encryption key as the database EncryptionMode = EncryptionMode.UseDatabaseKey #endregion } }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { #region use_database_encryption_key_full_sample var config = new PeriodicBackupConfiguration { //additional settings here.. //.. //This is a logical-backup BackupType = BackupType.Backup, BackupEncryptionSettings = new BackupEncryptionSettings { //Use the same encryption key as the database EncryptionMode = EncryptionMode.UseDatabaseKey } }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); #endregion } using (var docStore = new DocumentStore) { var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { //Backup files local path FolderPath = @"E:\RavenBackups" }, //Full Backup period (Cron expression for a 3-hours period) FullBackupFrequency = "0 */3 * * *", //Type can be Backup or Snapshot BackupType = BackupType.Backup, //Task Name Name = "fullBackupTask", BackupEncryptionSettings = new BackupEncryptionSettings { #region use_provided_encryption_key //Use an encryption key of your choice EncryptionMode = EncryptionMode.UseProvidedKey, Key = "OI7Vll7DroXdUORtc6Uo64wdAk1W0Db9ExXXgcg5IUs=" #endregion } }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { var config = new PeriodicBackupConfiguration { // additional settings here.. //.. #region use_provided_encryption_key_full_sample BackupEncryptionSettings = new BackupEncryptionSettings { //Use an encryption key of your choice EncryptionMode = EncryptionMode.UseProvidedKey, Key = "OI7Vll7DroXdUORtc6Uo64wdAk1W0Db9ExXXgcg5IUs=" } #endregion }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { var config = new PeriodicBackupConfiguration { // additional settings here.. //.. #region explicitly_choose_no_encryption BackupEncryptionSettings = new BackupEncryptionSettings { //No encryption EncryptionMode = EncryptionMode.None } #endregion }; var operation = new UpdatePeriodicBackupOperation(config); var result = await docStore.Maintenance.SendAsync(operation); } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { #region restore_encrypted_backup // restore encrypted database var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newEncryptedDatabase"; //Backup-file location var backupPath = @"C:\Users\RavenDB\2019-01-06-11-11.ravendb-encryptedDatabase-A-snapshot"; restoreConfiguration.BackupLocation = backupPath; restoreConfiguration.BackupEncryptionSettings = new BackupEncryptionSettings { Key = "OI7Vll7DroXdUORtc6Uo64wdAk1W0Db9ExXXgcg5IUs=" }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { // restore encrypted database var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newEncryptedDatabase"; //Backup-file location var backupPath = @"C:\Users\RavenDB\2019-01-06-11-11.ravendb-encryptedDatabase-A-snapshot"; restoreConfiguration.BackupLocation = backupPath; #region restore_encrypted_database //Restore the database using the key you encrypted it with restoreConfiguration.BackupEncryptionSettings = new BackupEncryptionSettings { Key = "OI7Vll7DroXdUORtc6Uo64wdAk1W0Db9ExXXgcg5IUs=" }; //Encrypt the restored database using this key restoreConfiguration.EncryptionKey = "1F0K2R/KkcwbkK7n4kYlv5eqisy/pMnSuJvZ2sJ/EKo="; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); #endregion } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newEncryptedDatabase"; //Backup-file location var backupPath = @"C:\Users\RavenDB\2019-01-06-11-11.ravendb-encryptedDatabase-A-snapshot"; restoreConfiguration.BackupLocation = backupPath; #region restore_unencrypted_database restoreConfiguration.BackupEncryptionSettings = new BackupEncryptionSettings { //No encryption EncryptionMode = EncryptionMode.None }; #endregion var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); } using (var docStore = new DocumentStore { Urls = new[] { "https://a.RavenDBdom.development.run" }, Database = "encryptedDatabase", Certificate = cert }.Initialize()) { // restore encrypted database // restore configuration var restoreConfiguration = new RestoreBackupConfiguration(); //New database name restoreConfiguration.DatabaseName = "newEncryptedDatabase"; // restoreConfiguration.EncryptionKey = "1F0K2R/KkcwbkK7n4kYlv5eqisy/pMnSuJvZ2sJ/EKo="; #region encrypting_logical_backup_with_new_key //Restore using your own key restoreConfiguration.BackupEncryptionSettings = new BackupEncryptionSettings { Key = "OI7Vll7DroXdUORtc6Uo64wdAk1W0Db9ExXXgcg5IUs=" }; #endregion #region restore_encrypting_logical_backup_with_database_key //Restore using the DB-encryption key restoreConfiguration.EncryptionKey = "1F0K2R/KkcwbkK7n4kYlv5eqisy/pMnSuJvZ2sJ/EKo="; //Backup-file location var backupPath = @"C:\Users\RavenDB\2019-01-06-11-11.ravendb-encryptedDatabase-A-snapshot"; restoreConfiguration.BackupLocation = backupPath; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); docStore.Maintenance.Server.Send(restoreBackupTask); #endregion }
public async Task CreateFullAndIncrementalBackupWithIndexInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Name = "Toli" }, "users/1"); session.SaveChanges(); } var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "* */6 * * *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = (await GetDocumentDatabaseInstanceFor(store)); RunBackup(result.TaskId, documentDatabase, true, store); var input = new IndexDefinition { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }; await store .Maintenance .SendAsync(new PutIndexesOperation(new[] { input })); config.IncrementalBackupFrequency = "* */300 * * *"; config.TaskId = result.TaskId; result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); RunBackup(result.TaskId, documentDatabase, false, store); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = Directory.GetFiles(backupDirectory).Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var stats = store2.Maintenance.ForDatabase(databaseName).Send(new GetStatisticsOperation()); Assert.Equal(1, stats.CountOfIndexes); Assert.Equal(1, stats.CountOfDocuments); }; } }
public async Task CreateFullAndIncrementalBackupWithIdentitiesInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Id = "users|", Name = "Toli" }); session.Store(new User { Id = "users|", Name = "Mitzi" }); session.SaveChanges(); } var config = Backup.CreateBackupConfiguration(backupPath); var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store); Dictionary <string, long> identities = store.Maintenance.Send(new GetIdentitiesOperation()); await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { Dictionary <string, long> identities2 = store2.Maintenance.Send(new GetIdentitiesOperation()); Assert.Equal(identities.First().Key, identities2.First().Key); Assert.Equal(identities.First().Value, identities2.First().Value); }; } }
public async Task CanExportImportCompareExchangeWithExpiration() { using var server = GetNewServer(); int count = 15; var expiry = DateTime.Now.AddMinutes(2); var longExpiry = DateTime.Now.AddMinutes(4); var compareExchangesWithShortExpiration = new Dictionary <string, User>(); var compareExchangesWithLongExpiration = new Dictionary <string, User>(); var compareExchanges = new Dictionary <string, User>(); var amountToAdd = count / 3; var backupPath = NewDataPath(suffix: "BackupFolder"); var databaseName = GetDatabaseName() + "restore"; using (var store = GetDocumentStore(new Options { Server = server })) { await AddCompareExchangesWithExpire(amountToAdd, compareExchanges, store, expiry : null); await AddCompareExchangesWithExpire(amountToAdd, compareExchangesWithShortExpiration, store, expiry); await AddCompareExchangesWithExpire(amountToAdd, compareExchangesWithLongExpiration, store, longExpiry); await AssertCompareExchanges(compareExchangesWithShortExpiration, store, expiry); await AssertCompareExchanges(compareExchangesWithLongExpiration, store, longExpiry); await AssertCompareExchanges(compareExchanges, store, expiry : null); var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "0 0 1 1 *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = await server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var periodicBackupRunner = documentDatabase.PeriodicBackupRunner; var op = periodicBackupRunner.StartBackupTask(result.TaskId, isFullBackup: true); var value = WaitForValue(() => { var status = store.Maintenance.Send(new GetOperationStateOperation(op)).Status; return(status); }, OperationStatus.Completed); Assert.Equal(OperationStatus.Completed, value); var backupDirectory = Directory.GetDirectories(backupPath).First(); var restoreConfig = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName }; var restoreOperation = new RestoreBackupOperation(restoreConfig); var o = await store.Maintenance.Server.SendAsync(restoreOperation); await o.WaitForCompletionAsync(TimeSpan.FromSeconds(30)); using (var store2 = GetDocumentStore(new Options { Server = server, CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var stats1 = await store.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); Assert.Equal(count, stats1.CountOfCompareExchange); var stats = await store2.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); Assert.Equal(count, stats.CountOfCompareExchange); server.ServerStore.Observer.Time.UtcDateTime = () => DateTime.UtcNow.AddMinutes(3); var val = await WaitForValueAsync(async() => { var stats = await store2.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); return(stats.CountOfCompareExchange); }, count - amountToAdd); Assert.Equal(count - amountToAdd, val); server.ServerStore.Observer.Time.UtcDateTime = () => DateTime.UtcNow.AddMinutes(5); var nextVal = await WaitForValueAsync(async() => { var stats = await store2.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); return(stats.CountOfCompareExchange); }, amountToAdd); Assert.Equal(amountToAdd, nextVal); stats1 = await store.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); Assert.Equal(amountToAdd, stats1.CountOfCompareExchange); stats = await store2.Maintenance.SendAsync(new GetDetailedStatisticsOperation()); Assert.Equal(amountToAdd, stats.CountOfCompareExchange); } } }
public async Task CreateFullAndIncrementalBackupWithIndexInTheMiddle() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Name = "Toli" }, "users/1"); session.SaveChanges(); } var config = Backup.CreateBackupConfiguration(backupPath); var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store); var input = new IndexDefinition { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }; await store .Maintenance .SendAsync(new PutIndexesOperation(new[] { input })); await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false); var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); store.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var stats = store2.Maintenance.ForDatabase(databaseName).Send(new GetStatisticsOperation()); Assert.Equal(1, stats.CountOfIndexes); Assert.Equal(1, stats.CountOfDocuments); }; } }
public async Task BackupWithIdentityAndCompareExchangeShouldHaveOnlyOwnValues() { var backupPath = NewDataPath(suffix: "BackupFolder1"); var cmpXchg1 = new User { Name = "👺" }; using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => "a" })) using (var store2 = GetDocumentStore(new Options { ModifyDatabaseName = s => "aa" })) { using (var session = store.OpenAsyncSession()) { var bestUser = new User { Name = "Egor1" }; await session.StoreAsync(bestUser, "a|"); await session.SaveChangesAsync(); } await store.Operations.SendAsync(new PutCompareExchangeValueOperation <User>("emojis/goblin", cmpXchg1, 0)); using (var session = store2.OpenAsyncSession()) { var bestUser = new User { Name = "Egor2" }; await session.StoreAsync(bestUser, "aa|"); await session.SaveChangesAsync(); } var cmpXchg2 = new User { Name = "🤡" }; await store2.Operations.SendAsync(new PutCompareExchangeValueOperation <User>("emojis/clown", cmpXchg2, 0)); var config = new PeriodicBackupConfiguration { LocalSettings = new LocalSettings { FolderPath = backupPath }, Name = "full", FullBackupFrequency = "* */6 * * *", BackupType = BackupType.Backup }; var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config)); var documentDatabase = (await GetDocumentDatabaseInstanceFor(store)); PeriodicBackupTestsSlow.RunBackup(result.TaskId, documentDatabase, true, store); // FULL BACKUP } var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); var restoreConfig = new RestoreBackupConfiguration { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; using (var store2 = GetDocumentStore(new Options { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var restoreOperation = new RestoreBackupOperation(restoreConfig); store2.Maintenance.Server.Send(restoreOperation) .WaitForCompletion(TimeSpan.FromSeconds(30)); using (var session = store2.OpenAsyncSession(new SessionOptions { TransactionMode = TransactionMode.ClusterWide })) { var stats = store2.Maintenance.ForDatabase(databaseName).Send(new GetDetailedStatisticsOperation()); Assert.Equal(1, stats.CountOfIdentities); Assert.Equal(1, stats.CountOfCompareExchange); Assert.Equal(1, stats.CountOfDocuments); var bestUser = await session.LoadAsync <User>("a/1"); var mediocreUser1 = await session.LoadAsync <User>("aa/1"); Assert.NotNull(bestUser); Assert.Null(mediocreUser1); Assert.Equal("Egor1", bestUser.Name); var cmpXchg = await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <User>("emojis/goblin"); Assert.Equal(cmpXchg1.Name, cmpXchg.Value.Name); var cmpXchg2 = await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <User>("emojis/clown"); Assert.Null(cmpXchg2); } } }
public async Task ShouldPreserveTombstoneFlagsAfterRestore() { using (var store = GetDocumentStore()) { var configuration = new RevisionsConfiguration { Default = new RevisionsCollectionConfiguration { Disabled = false, MinimumRevisionsToKeep = 10 }, Collections = new Dictionary <string, RevisionsCollectionConfiguration> { ["Users"] = new RevisionsCollectionConfiguration { Disabled = false, MinimumRevisionsToKeep = 5 } } }; await RevisionsHelper.SetupRevisions(store, Server.ServerStore, configuration); using (var session = store.OpenSession()) { session.Store(new User() { Name = "Arek" }, "users/arek"); session.SaveChanges(); } using (var session = store.OpenSession()) { session.Delete("users/arek"); // this will create tombstone with HasRevisions flags session.SaveChanges(); } var backupPath = NewDataPath(suffix: "BackupFolder"); var config = Backup.CreateBackupConfiguration(backupPath); var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store); // restore var backupDirectory = Directory.GetDirectories(backupPath).First(); var databaseName = GetDatabaseName() + "restore"; var files = Directory.GetFiles(backupDirectory) .Where(BackupUtils.IsBackupFile) .OrderBackups() .ToArray(); RestoreBackupConfiguration config2 = new RestoreBackupConfiguration() { BackupLocation = backupDirectory, DatabaseName = databaseName, LastFileNameToRestore = files.Last() }; RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2); await store.Maintenance.Server.Send(restoreOperation) .WaitForCompletionAsync(TimeSpan.FromSeconds(30)); using (var storeOfRestoredDb = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { var db = await GetDatabase(storeOfRestoredDb.Database); using (db.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var tombstones = db.DocumentsStorage.GetTombstonesFrom(ctx, 0, 0, int.MaxValue).ToList(); Assert.Equal(1, tombstones.Count); Assert.Equal(DocumentFlags.HasRevisions, tombstones[0].Flags); } } } }
public void can_backup_and_restore() { var azureSettings = GenerateAzureSettings(); InitContainer(azureSettings); using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new User { Name = "oren" }, "users/1"); session.CountersFor("users/1").Increment("likes", 100); session.SaveChanges(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, AzureSettings = azureSettings, IncrementalBackupFrequency = "0 0 1 1 *" }; var backupTaskId = (store.Maintenance.Send(new UpdatePeriodicBackupOperation(config))).TaskId; store.Maintenance.Send(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); PeriodicBackupStatus status = null; var value = WaitForValue(() => { status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 4); Assert.True(4 == value, $"4 == value, Got status: {status != null}, exception: {status?.Error?.Exception}"); Assert.True(status.LastOperationId != null, $"status.LastOperationId != null, Got status: {status != null}, exception: {status?.Error?.Exception}"); var backupOperation = store.Maintenance.Send(new GetOperationStateOperation(status.LastOperationId.Value)); var backupResult = backupOperation.Result as BackupResult; Assert.True(backupResult != null && backupResult.Counters.Processed, "backupResult != null && backupResult.Counters.Processed"); Assert.True(1 == backupResult.Counters.ReadCount, "1 == backupResult.Counters.ReadCount"); using (var session = store.OpenSession()) { session.Store(new User { Name = "ayende" }, "users/2"); session.CountersFor("users/2").Increment("downloads", 200); session.SaveChanges(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; store.Maintenance.Send(new StartBackupOperation(false, backupTaskId)); value = WaitForValue(() => store.Maintenance.Send(operation).Status.LastEtag, lastEtag); Assert.Equal(lastEtag, value); // restore the database with a different name var databaseName = $"restored_database-{Guid.NewGuid()}"; azureSettings.RemoteFolderName = status.FolderName; var restoreFromGoogleCloudConfiguration = new RestoreFromAzureConfiguration() { DatabaseName = databaseName, Settings = azureSettings, DisableOngoingTasks = true }; var googleCloudOperation = new RestoreBackupOperation(restoreFromGoogleCloudConfiguration); var restoreOperation = store.Maintenance.Server.Send(googleCloudOperation); restoreOperation.WaitForCompletion(TimeSpan.FromSeconds(30)); using (var store2 = GetDocumentStore(new Options() { CreateDatabase = false, ModifyDatabaseName = s => databaseName })) { using (var session = store2.OpenSession(databaseName)) { var users = session.Load <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = session.CountersFor("users/1").Get("likes"); Assert.Equal(100, val); val = session.CountersFor("users/2").Get("downloads"); Assert.Equal(200, val); } var originalDatabase = Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database).Result; var restoredDatabase = Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName).Result; using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Equal($"A:7-{originalDatabase.DbBase64Id}, A:8-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public async Task can_backup_and_restore_snapshot() { var backupPath = NewDataPath(suffix: "BackupFolder"); using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } using (var session = store.OpenAsyncSession()) { await session .Query <User>() .Where(x => x.Name == "oren") .ToListAsync(); // create an index to backup await session .Query <User>() .Where(x => x.Age > 20) .ToListAsync(); // create an index to backup } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Snapshot, LocalSettings = new LocalSettings { FolderPath = backupPath }, IncrementalBackupFrequency = "* * * * *" //every minute }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); SpinWait.SpinUntil(() => { var getPeriodicBackupResult = store.Maintenance.Send(operation); return(getPeriodicBackupResult.Status?.LastEtag > 0); }, TimeSpan.FromSeconds(15)); var etagForBackups = store.Maintenance.Send(operation).Status.LastEtag; using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); await session.StoreAsync(new User { Name = "ayende" }, "users/3"); await session.SaveChangesAsync(); } await store.Maintenance.SendAsync(new StartBackupOperation(false, backupTaskId)); SpinWait.SpinUntil(() => { var newLastEtag = store.Maintenance.Send(operation).Status.LastEtag; return(newLastEtag != etagForBackups); }, TimeSpan.FromSeconds(15)); // restore the database with a different name const string restoredDatabaseName = "restored_database_snapshot"; var restoreConfiguration = new RestoreBackupConfiguration { BackupLocation = Directory.GetDirectories(backupPath).First(), DatabaseName = restoredDatabaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var restoreResult = store.Maintenance.Server.Send(restoreBackupTask); restoreResult.WaitForCompletion(TimeSpan.FromSeconds(30)); using (var session = store.OpenAsyncSession(restoredDatabaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); } var stats = await store.Maintenance.SendAsync(new GetStatisticsOperation()); Assert.Equal(2, stats.CountOfIndexes); } }