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

问题描述 投票:0回答:4

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

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 并复制文件,然后再次启动服务器?

sql vb.net file-io
4个回答
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 服务以复制某些文件,您永远不会发生什么。可能会非常昂贵,所以最好是安全的。


1
投票

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

完成此操作后,您应该能够根据需要简单地复制文件。

对于 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
投票

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

这正是“正常”备份的目的。
正如您自己注意到的那样,您可以通过简单地复制

.mdf
.ldf
文件来备份SQL Server数据库,但缺点是您只能在SQL Server服务未运行时执行此操作。

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

可以在数据库运行时进行“正常”备份(通常是

.bak
文件),因此无需在每次要进行备份时停止 SQL Server。

备份有几种方法:

a) 在 SQL Server Management Studio 中手动操作:
请参阅Jason Evans 的回答中的第一个链接

b)如果你想定期备份(比如,每天一次)你需要使用

sqlcmd
.
Jason Evans 在他的回答中也描述了这一点,但 IMO 有一种更简单的方法 - 你只需要两个文件,每个文件一行。请参阅如何在 SQL Server Express 版中创建作业

(如果您使用的是完整的 SQL Server 版本而不仅仅是 Express,您可以 在 Management Studio 中设置维护任务,但这在 SQL Server Express 中是不可能的,因此您必须像上面描述的那样手动执行) .


0
投票

如果你的数据库可能有一些停机时间,你可以使用:

ALTER DATABASE foo SET OFFLINE WITH ROLLBACK IMMEDIATE;

复制 mdf 和 ldf 文件并将数据库上线。

ALTER DATABASE foo SET ONLINE;
© www.soinside.com 2019 - 2024. All rights reserved.