在服务器正在使用时复制SQL Server MDF和LDF文件

时间:2011-12-30 15:26:53

标签: sql vb.net file-io

我使用以下代码将文件从一个文件夹复制到另一个文件夹......

Public Shared Sub CopyFlashScriptFile(ByVal SourceDirectory As String, ByVal DestinationDirectory As String)
   Try
      Dim f() As String = Directory.GetFiles(SourceDirectory)
      For i As Integer = 0 To UBound(f)
         File.Copy(f(i), DestinationDirectory & "\" & System.IO.Path.GetFileName(f(i)),True)
         Next
   Catch ex As Exception
      MsgBox(ex.Message)
   End Try
End Sub

我要复制的文件是数据库文件,.mdf.ldf。应用程序正在使用哪些。现在的问题是,当我尝试复制文件时,它会抛出错误

  另一个进程正在使用

文件

任何人都可以帮我吗?

无论如何,我可以通过编程方式停止SQL Server并复制文件,然后再次启动服务器吗?

3 个答案:

答案 0 :(得分:1)

根据您使用的SQL版本,您可以使用Microsoft.SqlServer.Management.Smo.Wmi.Service对象来启动和停止运行SQL实例的服务。

执行此操作后,您应该可以根据需要简单地复制文件。

For SQL Server 2008

{ 
   //Declare and create an instance of the ManagedComputer 
   //object that represents the WMI Provider services. 
   ManagedComputer mc; 
   mc = new ManagedComputer(); 
   //Iterate through each service registered with the WMI Provider. 

   foreach (Service svc in mc.Services)
   { 
      Console.WriteLine(svc.Name); 
   } 
//Reference the Microsoft SQL Server service. 
  Service Mysvc = mc.Services["MSSQLSERVER"]; 
//Stop the service if it is running and report on the status
// continuously until it has stopped. 
   if (Mysvc.ServiceState == ServiceState.Running) { 
      Mysvc.Stop(); 
      Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState)); 
      while (!(string.Format("{0}", Mysvc.ServiceState) == "Stopped")) { 
         Console.WriteLine(string.Format("{0}", Mysvc.ServiceState)); 
          Mysvc.Refresh(); 
      } 
      Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState)); 
//Start the service and report on the status continuously 
//until it has started. 
      Mysvc.Start(); 
      while (!(string.Format("{0}", Mysvc.ServiceState) == "Running")) { 
         Console.WriteLine(string.Format("{0}", Mysvc.ServiceState)); 
         Mysvc.Refresh(); 
      } 
      Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState));
      Console.ReadLine();
   } 
   else { 
      Console.WriteLine("SQL Server service is not running.");
      Console.ReadLine();
   } 
}

来自msdn

答案 1 :(得分:1)

要扩展我的注释 - 我将使用T-SQL命令构建一个.sql文件以将数据库备份到另一个位置,然后我可以从命令行使用sqlcmd来运行备份.sql文件。

因此,要构建.sql文件,我将通过SQL Server Management Studio完成备份数据库的过程。这是一个如何执行此操作的教程:

http://www.serverintellect.com/support/sqlserver/database-backup-ssmse.aspx

然后,在单击“确定”执行备份之前,单击备份窗口上的“脚本”按钮,然后选择“脚本操作到新查询窗口”。这将从备份数据库窗口生成您的设置的SQL。将该SQL保存到文件中即可完成。

接下来是使用sqlcmd.exe执行.sql文件来随时备份数据库。这里有一个使用C#代码sqlcmd.exe的非常好的例子:

http://geekswithblogs.net/thomasweller/archive/2009/09/08/automating-database-script-execution.aspx

我总是喜欢做这样的事情,而不影响正在运行的SQL Server(除非它是在我的开发机器上运行的,我很乐意停止/启动服务)。如果停止生产SQL Server服务来复制某些文件,您将永远不会发生什么。可能是非常昂贵的,所以更安全。

答案 2 :(得分:1)

  

我在我的应用程序中使用.mdf文件...如果系统崩溃或格式化,用户将丢失数据..如果用户将数据(.mdf)复制到其他驱动器。 。她/她可以将旧的.mdf文件替换为包含所有数据的旧文件...如果我错了,请纠正我...谢谢。

这正是“正常”备份的用途 正如您自己注意到的那样,可以通过简单地复制.mdf.ldf文件来备份SQL Server数据库,但缺点是您只能在SQL Server上执行此操作服务没有运行。

停止SQL Server服务只是为了备份数据库不是一个好主意,因为您的用户在服务停止时无法访问数据库。

在数据库运行时可以进行“正常”备份(通常是.bak文件),因此每次要进行备份时都不需要停止SQL Server。

有多种方法可以进行备份:

a)在SQL Server Management Studio中手动:
请参阅Jason Evans' answer

中的第一个链接

b)如果您想定期备份(比方说,每天一次),您需要使用sqlcmd
Jason Evans也在他的回答中描述了这一点,但IMO有一种更简单的方法 - 你只需要两个文件,每个文件一行。请参阅How to create jobs in SQL Server Express edition

(如果您使用的是完整的SQL Server版本而不仅仅是Express,则可以使用set up a Maintenance Task in Management Studio,但这在SQL Server Express中是不可能的,因此您必须像上面所述手动执行此操作。