public static void Restore(ConfigPair storageConfig, List <ConfigPair> pipelineConfig, ConfigPair databaseConfig, IUpdateNotification updateNotifier) { BackupOrRestore(false, storageConfig, databaseConfig, pipelineConfig, updateNotifier); }
private static void BackupOrRestore(bool isBackup, ConfigPair storageConfig, ConfigPair databaseConfig, List <ConfigPair> pipelineConfig, IUpdateNotification updateNotifier) { string deviceSetName = Guid.NewGuid().ToString(); IBackupStorage storage = storageConfig.TransformationType.GetConstructor(new Type[0]).Invoke(new object[0]) as IBackupStorage; IBackupDatabase databaseComp = databaseConfig.TransformationType.GetConstructor(new Type[0]).Invoke(new object[0]) as IBackupDatabase; try { int numDevices = storage.GetNumberOfDevices(storageConfig.Parameters); string instanceName = databaseComp.GetInstanceName(databaseConfig.Parameters); string clusterNetworkName = databaseComp.GetClusterNetworkName(databaseConfig.Parameters); SqlPlatform sqlPlatform = VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName); //NotifyWhenReady notifyWhenReady = new NotifyWhenReady(deviceName, isBackup);)) using (IVirtualDeviceSet deviceSet = VirtualBackupDeviceFactory.NewVirtualDeviceSet(sqlPlatform)) { using (SqlThread sql = new SqlThread()) { bool sqlStarted = false; bool sqlFinished = false; ParallelExecutionException exceptions = new ParallelExecutionException(); try { IStreamNotification streamNotification = new InternalStreamNotification(updateNotifier); long estimatedTotalBytes; List <string> deviceNames = sql.PreConnect(clusterNetworkName, instanceName, deviceSetName, numDevices, databaseComp, databaseConfig.Parameters, isBackup, updateNotifier, out estimatedTotalBytes); using (DisposableList <Stream> fileStreams = new DisposableList <Stream>(isBackup ? storage.GetBackupWriter(storageConfig.Parameters) : storage.GetRestoreReader(storageConfig.Parameters, out estimatedTotalBytes))) using (DisposableList <Stream> topOfPilelines = new DisposableList <Stream>(CreatePipeline(pipelineConfig, fileStreams, isBackup, streamNotification, estimatedTotalBytes))) { VirtualDeviceSetConfig config = new VirtualDeviceSetConfig(); config.Features = FeatureSet.PipeLike; config.DeviceCount = (uint)topOfPilelines.Count; deviceSet.CreateEx(instanceName, deviceSetName, config); sql.BeginExecute(); sqlStarted = true; deviceSet.GetConfiguration(TimeSpan.FromMinutes(1)); List <IVirtualDevice> devices = new List <IVirtualDevice>(); foreach (string devName in deviceNames) { devices.Add(deviceSet.OpenDevice(devName)); } using (DisposableList <DeviceThread> threads = new DisposableList <DeviceThread>(devices.Count)) { for (int i = 0; i < devices.Count; i++) { DeviceThread dThread = new DeviceThread(); threads.Add(dThread); dThread.Initialize(isBackup, topOfPilelines[i], devices[i], deviceSet); } foreach (DeviceThread dThread in threads) { dThread.BeginCopy(); } updateNotifier.OnStart(); //Console.WriteLine(string.Format("{0} started", isBackup ? "Backup" : "Restore")); Exception sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } foreach (DeviceThread dThread in threads) { Exception devE = dThread.EndCopy(); if (devE != null) { exceptions.Exceptions.Add(devE); } } } } } catch (Exception e) { exceptions.Exceptions.Add(e); } finally { if (sqlStarted && !sqlFinished) { Exception sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } } } if (exceptions.HasExceptions) { throw exceptions; } } } } catch { storage.CleanupOnAbort(); throw; } }
/// <summary> /// Returns the auto-generated device names /// </summary> public List <string> PreConnect(string clusterNetworkName, string instanceName, string deviceSetName, int numDevices, IBackupDatabase dbComponent, Dictionary <string, List <string> > dbConfig, bool isBackup, IUpdateNotification notifier, out long estimatedTotalBytes) { string serverConnectionName = clusterNetworkName == null ? "." : clusterNetworkName; string dataSource = string.IsNullOrEmpty(instanceName) ? serverConnectionName : string.Format(@"{0}\{1}", serverConnectionName, instanceName); string connectionString = string.Format("Data Source={0};Initial Catalog=master;Integrated Security=SSPI;Asynchronous Processing=true;", dataSource); notifier.OnConnecting(string.Format("Connecting: {0}", connectionString)); mCnn = new SqlConnection(connectionString); mCnn.Open(); List <string> deviceNames = new List <string>(numDevices); deviceNames.Add(deviceSetName); for (int i = 1; i < numDevices; i++) { deviceNames.Add(string.Format("dev{0}", i)); } mCmd = new SqlCommand(); mCmd.Connection = mCnn; mCmd.CommandTimeout = 0; if (isBackup) { dbComponent.ConfigureBackupCommand(dbConfig, deviceNames, mCmd); estimatedTotalBytes = CalculateEstimatedDatabaseSize(mCnn, dbConfig); } else { dbComponent.ConfigureRestoreCommand(dbConfig, deviceNames, mCmd); estimatedTotalBytes = 0; } return(deviceNames); }
public InternalStreamNotification(IUpdateNotification notification) { _mExternalNotification = notification; }
private static void BackupOrRestore(int commandType, ConfigPair storageConfig, ConfigPair databaseConfig, List <ConfigPair> pipelineConfig, IUpdateNotification updateNotifier, out List <string> returndevices) { var isBackup = commandType == 1; var deviceSetName = Guid.NewGuid().ToString(); var constructorInfo = storageConfig.TransformationType.GetConstructor(new Type[0]); if (constructorInfo == null) { throw new ArgumentException("Unable to transformation type"); } var storage = constructorInfo.Invoke(new object[0]) as IBackupStorage; var constructor = databaseConfig.TransformationType.GetConstructor(new Type[0]); if (constructor == null) { throw new ArgumentException("Unable to transformation type"); } var databaseComp = constructor.Invoke(new object[0]) as IBackupDatabase; try { if (storage == null) { returndevices = null; return; } var numDevices = storage.GetNumberOfDevices(storageConfig.Parameters); //get instance name e.g. myserver\myinstance if (databaseComp == null) { returndevices = null; return; } var instanceName = databaseComp.GetInstanceName(databaseConfig.Parameters); //get the cluster networking name usually diffrent than the currently running node name var clusterNetworkName = databaseComp.GetClusterNetworkName(databaseConfig.Parameters); //get bit version of our platform x86,x64 or IA64 var sqlPlatform = databaseConfig.Parameters.ContainsKey("user") ? VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName, databaseConfig.Parameters["user"][0], databaseConfig.Parameters.ContainsKey("password") ? databaseConfig.Parameters["password"][0] : null) : VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName, null, null); //NotifyWhenReady notifyWhenReady = new NotifyWhenReady(deviceName, isBackup);)) using (var deviceSet = VirtualBackupDeviceFactory.NewVirtualDeviceSet(sqlPlatform)) { //Since it is possible to have multiple backup/restore targets we encapsulate each call to a device in its own thread using (var sql = new SqlThread()) { var sqlStarted = false; var sqlFinished = false; returndevices = new List <string>(); var exceptions = new ParallelExecutionException(); try { IStreamNotification streamNotification = new InternalStreamNotification(updateNotifier); long estimatedTotalBytes; var deviceNames = sql.PreConnect(clusterNetworkName, instanceName, deviceSetName, numDevices, databaseComp, databaseConfig.Parameters, commandType, updateNotifier, out estimatedTotalBytes); using ( var fileStreams = new DisposableList <Stream>(isBackup ? storage.GetBackupWriter(storageConfig.Parameters, estimatedTotalBytes) : storage.GetRestoreReader(storageConfig.Parameters, out estimatedTotalBytes))) using ( var topOfPilelines = new DisposableList <Stream>(CreatePipeline(pipelineConfig, fileStreams, isBackup, streamNotification, estimatedTotalBytes))) { ReturnByteScale(estimatedTotalBytes, isBackup); var config = new VirtualDeviceSetConfig { Features = FeatureSet.PipeLike, DeviceCount = (uint)topOfPilelines.Count }; deviceSet.CreateEx(instanceName, deviceSetName, config); sql.BeginExecute(); sqlStarted = true; deviceSet.GetConfiguration(TimeSpan.FromMinutes(360)); var devices = deviceNames.Select(deviceSet.OpenDevice).ToList(); returndevices = deviceNames; using (var threads = new DisposableList <DeviceThread>(devices.Count)) { for (var i = 0; i < devices.Count; i++) { var dThread = new DeviceThread(); threads.Add(dThread); dThread.Initialize(isBackup, topOfPilelines[i], devices[i], deviceSet); } foreach (var dThread in threads) { dThread.BeginCopy(); } updateNotifier.OnStart(); var sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } foreach (var devE in threads.Select(dThread => dThread.EndCopy()).Where(devE => devE != null)) { exceptions.Exceptions.Add(devE); } } } } catch (Exception e) { exceptions.Exceptions.Add(e); } finally { if (exceptions.HasExceptions) { throw exceptions; } if (sqlStarted && !sqlFinished) { var sqlE = sql.EndExecute(); if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } } } } } } catch { if (storage != null) { storage.CleanupOnAbort(); } throw; } }
public static void FileList(ConfigPair storageConfig, List <ConfigPair> pipelineConfig, ConfigPair databaseConfig, IUpdateNotification updateNotifier) { List <string> returndevices; BackupOrRestore(5, storageConfig, databaseConfig, pipelineConfig, updateNotifier, out returndevices); }
/// <summary> /// Returns the auto-generated device names /// </summary> public List <string> PreConnect(string clusterNetworkName, string instanceName, string deviceSetName, int numDevices, IBackupDatabase dbComponent, Dictionary <string, List <string> > dbConfig, int isBackup, IUpdateNotification notifier, out long estimatedTotalBytes) { var serverConnectionName = clusterNetworkName ?? "."; var dataSource = string.IsNullOrEmpty(instanceName) ? serverConnectionName : string.Format(@"{0}\{1}", serverConnectionName, instanceName); var connectionString = dbConfig.ContainsKey("user") ? string.Format("Data Source={0};Initial Catalog=master;Integrated Security=False;User ID={1};Password={2};Asynchronous Processing=true;;Connect Timeout=2147483647", dataSource, dbConfig["user"][0], dbConfig.ContainsKey("password") ? dbConfig["password"][0] : null) : string.Format("Data Source={0};Initial Catalog=master;Integrated Security=True;Asynchronous Processing=true;Connect Timeout=2147483647", dataSource); notifier.OnConnecting(string.Format("Connecting: {0}", connectionString)); _mCnn = new SqlConnection(connectionString); _mCnn.Open(); var deviceNames = new List <string>(numDevices) { deviceSetName }; for (var i = 1; i < numDevices; i++) { deviceNames.Add(Guid.NewGuid().ToString()); } _mCmd = new SqlCommand { Connection = _mCnn, CommandTimeout = 0 }; estimatedTotalBytes = 0; //Console.WriteLine(mCmd); switch (isBackup) { case 1: dbComponent.ConfigureBackupCommand(dbConfig, deviceNames, _mCmd); estimatedTotalBytes = CalculateEstimatedDatabaseSize(_mCnn, dbConfig); break; case 2: dbComponent.ConfigureRestoreCommand(dbConfig, deviceNames, _mCmd); estimatedTotalBytes = 0; break; case 3: dbComponent.ConfigureVerifyCommand(dbConfig, deviceNames, _mCmd); estimatedTotalBytes = 0; break; default: Console.WriteLine("Default case"); break; } return(deviceNames); }